2010-01-26 11:20:18 +01:00
|
|
|
/*
|
|
|
|
* dec21041.c
|
|
|
|
*
|
|
|
|
* This file contains an ethernet device driver for DEC 21140A
|
|
|
|
* fast ethernet controllers as emulated by VirtualPC 2007. It is not
|
|
|
|
* intended to support the real card, as much more error checking
|
|
|
|
* and testing would be needed. It supports both bridged and NAT mode.
|
|
|
|
*
|
|
|
|
* Created: Mar 2008 by Nicolas Tittley <first.last@ google's mail>
|
|
|
|
*/
|
|
|
|
|
2010-03-22 22:25:22 +01:00
|
|
|
#include <minix/drivers.h>
|
2010-04-08 15:41:35 +02:00
|
|
|
#include <minix/netdriver.h>
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
#include <assert.h>
|
2010-03-08 12:04:59 +01:00
|
|
|
#include <machine/pci.h>
|
2010-01-26 11:20:18 +01:00
|
|
|
#include <minix/syslib.h>
|
|
|
|
#include <minix/endpoint.h>
|
|
|
|
#include <minix/com.h>
|
|
|
|
#include <minix/sef.h>
|
|
|
|
#include <minix/ds.h>
|
|
|
|
#include <net/gen/ether.h>
|
|
|
|
#include <net/gen/eth_io.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "dec21140A.h"
|
|
|
|
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static u32_t io_inl(u16_t);
|
|
|
|
static void io_outl(u16_t, u32_t);
|
|
|
|
static void do_conf(const message *);
|
|
|
|
static void do_get_stat_s(message *);
|
|
|
|
static void do_interrupt(const dpeth_t *);
|
|
|
|
static void do_reply(dpeth_t *);
|
|
|
|
static void do_vread_s(const message *, int);
|
|
|
|
static void do_watchdog(void *);
|
|
|
|
|
|
|
|
static void de_update_conf(dpeth_t *);
|
|
|
|
static int de_probe(dpeth_t *, int skip);
|
|
|
|
static void de_conf_addr(dpeth_t *);
|
|
|
|
static void de_first_init(dpeth_t *);
|
|
|
|
static void de_reset(const dpeth_t *);
|
|
|
|
static void de_hw_conf(const dpeth_t *);
|
|
|
|
static void de_start(const dpeth_t *);
|
|
|
|
static void de_setup_frame(const dpeth_t *);
|
|
|
|
static u16_t de_read_rom(const dpeth_t *, u8_t, u8_t);
|
|
|
|
static int de_calc_iov_size(iovec_dat_s_t *);
|
|
|
|
static void de_next_iov(iovec_dat_s_t *);
|
|
|
|
static void do_vwrite_s(const message *, int);
|
|
|
|
static void de_get_userdata_s(int, cp_grant_id_t, vir_bytes, int, void
|
2012-03-24 16:16:34 +01:00
|
|
|
*);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
/* Error messages */
|
|
|
|
static char str_CopyErrMsg[] = "unable to read/write user data";
|
|
|
|
static char str_SendErrMsg[] = "send failed";
|
|
|
|
static char str_SizeErrMsg[] = "illegal packet size";
|
|
|
|
static char str_UmapErrMsg[] = "Unable to sys_umap";
|
|
|
|
static char str_BusyErrMsg[] = "Send/Recv failed: busy";
|
|
|
|
static char str_StatErrMsg[] = "Unable to send stats";
|
|
|
|
static char str_AlignErrMsg[] = "Bad align of buffer/descriptor";
|
|
|
|
static char str_DevName[] = "dec21140A:eth#?";
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static dpeth_t de_state;
|
|
|
|
static int de_instance;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
/* SEF functions and variables. */
|
2012-03-25 20:25:53 +02:00
|
|
|
static void sef_local_startup(void);
|
|
|
|
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* main *
|
|
|
|
*===========================================================================*/
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
dpeth_t *dep;
|
|
|
|
message m;
|
2010-04-08 15:41:35 +02:00
|
|
|
int ipc_status;
|
2010-01-26 11:20:18 +01:00
|
|
|
int r;
|
|
|
|
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
/* SEF local startup. */
|
2010-01-26 11:20:18 +01:00
|
|
|
env_setargs(argc, argv);
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
sef_local_startup();
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
2010-04-08 15:41:35 +02:00
|
|
|
if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
|
|
|
|
panic("netdriver_receive failed: %d", r);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-04-08 15:41:35 +02:00
|
|
|
if(is_ipc_notify(ipc_status)) {
|
2010-01-26 11:20:18 +01:00
|
|
|
switch(_ENDPOINT_P(m.m_source)) {
|
|
|
|
case CLOCK:
|
|
|
|
do_watchdog(&m);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HARDWARE:
|
2010-05-18 00:22:53 +02:00
|
|
|
dep = &de_state;
|
|
|
|
if (dep->de_mode == DEM_ENABLED) {
|
|
|
|
do_interrupt(dep);
|
|
|
|
if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
|
|
|
|
do_reply(dep);
|
|
|
|
sys_irqenable(&dep->de_hook);
|
2010-01-26 11:20:18 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("ignoring notify from %d\n", m.m_source);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (m.m_type)
|
|
|
|
{
|
|
|
|
case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
|
|
|
|
case DL_READV_S: do_vread_s(&m, FALSE); break;
|
|
|
|
case DL_CONF: do_conf(&m); break;
|
|
|
|
case DL_GETSTAT_S: do_get_stat_s(&m); break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printf("message 0x%lx; %d from %d\n",
|
|
|
|
m.m_type, m.m_type-DL_RQ_BASE, m.m_source);
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("illegal message: %d", m.m_type);
|
2010-01-26 11:20:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* sef_local_startup *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
static void sef_local_startup()
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
{
|
|
|
|
/* Register init callbacks. */
|
|
|
|
sef_setcb_init_fresh(sef_cb_init_fresh);
|
2010-04-08 15:41:35 +02:00
|
|
|
sef_setcb_init_lu(sef_cb_init_fresh);
|
|
|
|
sef_setcb_init_restart(sef_cb_init_fresh);
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
|
2010-04-08 15:41:35 +02:00
|
|
|
/* Register live update callbacks. */
|
|
|
|
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
|
|
|
|
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
|
|
|
|
/* Register signal callbacks. */
|
|
|
|
sef_setcb_signal_handler(sef_cb_signal_handler_term);
|
|
|
|
|
|
|
|
/* Let SEF perform startup. */
|
|
|
|
sef_startup();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* sef_cb_init_fresh *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
{
|
|
|
|
/* Initialize the DEC 21140A driver. */
|
|
|
|
int fkeys, sfkeys;
|
2010-05-18 00:22:53 +02:00
|
|
|
long v;
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
v = 0;
|
|
|
|
(void) env_parse("instance", "d", 0, &v, 0, 255);
|
|
|
|
de_instance = (int) v;
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
|
|
|
|
/* Request function key for debug dumps */
|
2010-04-01 14:51:31 +02:00
|
|
|
fkeys = sfkeys = 0;
|
|
|
|
bit_set(sfkeys, DE_FKEY);
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
if ((fkey_map(&fkeys, &sfkeys)) != OK)
|
|
|
|
printf("%s: error using Shift+F%d key(%d)\n", str_DevName, DE_FKEY, errno);
|
|
|
|
|
2010-04-08 15:41:35 +02:00
|
|
|
/* Announce we are up! */
|
|
|
|
netdriver_announce();
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_get_stat_s(message * mp)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
2010-05-18 00:22:53 +02:00
|
|
|
int rc;
|
2010-01-26 11:20:18 +01:00
|
|
|
dpeth_t *dep;
|
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
dep = &de_state;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
if ((rc = sys_safecopyto(mp->m_source, mp->DL_GRANT, 0UL,
|
2010-01-26 11:20:18 +01:00
|
|
|
(vir_bytes)&dep->de_stat,
|
2012-06-16 03:46:15 +02:00
|
|
|
sizeof(dep->de_stat))) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_CopyErrMsg, rc);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
mp->m_type = DL_STAT_REPLY;
|
|
|
|
rc = send(mp->m_source, mp);
|
|
|
|
if( rc != OK )
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_StatErrMsg, rc);
|
2010-01-26 11:20:18 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_conf(const message * mp)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
2010-05-18 00:22:53 +02:00
|
|
|
int r;
|
2010-01-26 11:20:18 +01:00
|
|
|
dpeth_t *dep;
|
|
|
|
message reply_mess;
|
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
dep = &de_state;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
strncpy(dep->de_name, str_DevName, strlen(str_DevName));
|
|
|
|
dep->de_name[strlen(dep->de_name)-1] = '0' + de_instance;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
if (dep->de_mode == DEM_DISABLED) {
|
|
|
|
de_update_conf(dep);
|
|
|
|
pci_init();
|
|
|
|
if (dep->de_mode == DEM_ENABLED && !de_probe(dep, de_instance)) {
|
2010-01-26 11:20:18 +01:00
|
|
|
printf("%s: warning no ethernet card found at 0x%04X\n",
|
|
|
|
dep->de_name, dep->de_base_port);
|
|
|
|
dep->de_mode = DEM_DISABLED;
|
|
|
|
}
|
2010-05-18 00:22:53 +02:00
|
|
|
}
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
r = OK;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
/* 'de_mode' may change if probe routines fail, test again */
|
|
|
|
switch (dep->de_mode) {
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
case DEM_DISABLED:
|
|
|
|
r = ENXIO; /* Device is OFF or hardware probe failed */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DEM_ENABLED:
|
|
|
|
if (dep->de_flags == DEF_EMPTY) {
|
2010-01-26 11:20:18 +01:00
|
|
|
de_first_init(dep);
|
|
|
|
dep->de_flags |= DEF_ENABLED;
|
|
|
|
de_reset(dep);
|
|
|
|
de_hw_conf(dep);
|
|
|
|
de_setup_frame(dep);
|
|
|
|
de_start(dep);
|
2010-05-18 00:22:53 +02:00
|
|
|
}
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
/* TODO CHECK PROMISC AND MULTI */
|
|
|
|
dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
|
|
|
|
if (mp->DL_MODE & DL_PROMISC_REQ)
|
2010-01-26 11:20:18 +01:00
|
|
|
dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
|
2010-05-18 00:22:53 +02:00
|
|
|
if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;
|
|
|
|
if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DEM_SINK:
|
|
|
|
DEBUG(printf("%s running in sink mode\n", str_DevName));
|
|
|
|
memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
|
|
|
|
de_conf_addr(dep);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: break;
|
2010-04-01 14:51:31 +02:00
|
|
|
}
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
reply_mess.m_type = DL_CONF_REPLY;
|
2010-05-18 00:22:53 +02:00
|
|
|
reply_mess.DL_STAT = r;
|
|
|
|
if(r == OK){
|
|
|
|
*(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
|
2010-04-01 15:25:05 +02:00
|
|
|
}
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
if (send(mp->m_source, &reply_mess) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_SendErrMsg, mp->m_source);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_reply(dpeth_t * dep)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
|
|
|
message reply;
|
2010-05-18 00:22:53 +02:00
|
|
|
int r, flags = DL_NOFLAGS;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND;
|
|
|
|
if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
reply.m_type = DL_TASK_REPLY;
|
2010-06-29 13:45:32 +02:00
|
|
|
reply.DL_FLAGS = flags;
|
2010-01-26 11:20:18 +01:00
|
|
|
reply.DL_COUNT = dep->de_read_s;
|
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
r = send(dep->de_client, &reply);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
if(r < 0)
|
|
|
|
panic(str_SendErrMsg, r);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
dep->de_read_s = 0;
|
|
|
|
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_watchdog(void *UNUSED(message))
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
|
|
|
/* nothing here yet */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static int de_probe(dpeth_t *dep, int skip)
|
2012-03-07 00:49:16 +01:00
|
|
|
{
|
2010-01-26 11:20:18 +01:00
|
|
|
int i, r, devind;
|
|
|
|
u16_t vid, did, temp16;
|
|
|
|
|
|
|
|
DEBUG(printf("PROBING..."));
|
|
|
|
|
|
|
|
r= pci_first_dev(&devind, &vid, &did);
|
|
|
|
if (r == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
2012-03-07 00:49:16 +01:00
|
|
|
while (skip--)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
|
|
|
r= pci_next_dev(&devind, &vid, &did);
|
|
|
|
if (!r)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pci_reserve(devind);
|
|
|
|
|
|
|
|
dep->de_base_port = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
|
|
|
|
dep->de_irq = pci_attr_r8(devind, PCI_ILR);
|
|
|
|
|
|
|
|
if (dep->de_base_port < DE_MIN_BASE_ADDR)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("de_probe: base address invalid: %d", dep->de_base_port);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
DEBUG(printf("%s: using I/O address 0x%lx, IRQ %d\n",
|
|
|
|
dep->de_name, (unsigned long)dep->de_base_port,
|
|
|
|
dep->de_irq));
|
|
|
|
|
|
|
|
dep->de_type = pci_attr_r8(devind, PCI_REV);
|
|
|
|
|
|
|
|
/* device validation. We support only the DEC21140A */
|
|
|
|
if(dep->de_type != DEC_21140A){
|
|
|
|
dep->de_type = DE_TYPE_UNKNOWN;
|
|
|
|
printf("%s: unsupported device\n", str_DevName);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
de_reset(dep);
|
|
|
|
|
|
|
|
DEBUG(printf("Reading SROM...\n"));
|
|
|
|
|
|
|
|
for(i=0;i<(1<<SROM_BITWIDTH)-1;i++){
|
|
|
|
temp16 = de_read_rom(dep, i, SROM_BITWIDTH);
|
|
|
|
dep->srom[i*2] = temp16 & 0xFF;
|
|
|
|
dep->srom[i*2+1] = temp16 >> 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: validate SROM content */
|
|
|
|
/* acquire MAC addr */
|
|
|
|
DEBUG(printf("Using MAC addr= "));
|
|
|
|
for(i=0;i<6;i++){
|
|
|
|
dep->de_address.ea_addr[i] = dep->srom[i+DE_SROM_EA_OFFSET];
|
|
|
|
DEBUG(printf("%02X%c",dep->de_address.ea_addr[i],i!=5?'-':'\n'));
|
|
|
|
}
|
|
|
|
DEBUG(printf("probe success\n"));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static u16_t de_read_rom(const dpeth_t *dep, u8_t addr, u8_t nbAddrBits){
|
2010-01-26 11:20:18 +01:00
|
|
|
u16_t retVal = 0;
|
|
|
|
int i;
|
|
|
|
u32_t csr = 0;
|
|
|
|
u32_t csr2 = 0; /* csr2 is used to hold constant values that are
|
|
|
|
setup in the init phase, it makes this a little
|
|
|
|
more readable, the following macro is also just
|
|
|
|
to clear up the code a little.*/
|
|
|
|
|
|
|
|
#define EMIT do { io_outl(CSR_ADDR(dep, CSR9), csr | csr2); io_outl(CSR_ADDR(dep, CSR1), 0);} while(0)
|
|
|
|
|
|
|
|
/* init */
|
|
|
|
csr = 0; EMIT;
|
|
|
|
csr = CSR9_SR; EMIT;
|
|
|
|
csr = CSR9_SR | CSR9_RD; EMIT;
|
|
|
|
|
|
|
|
csr2 = CSR9_SR | CSR9_RD;
|
|
|
|
csr = 0; EMIT;
|
|
|
|
csr2 |= CSR9_CS;
|
|
|
|
|
|
|
|
csr = 0; EMIT;
|
|
|
|
csr = CSR9_SRC; EMIT;
|
|
|
|
csr = 0; EMIT;
|
|
|
|
|
|
|
|
/* cmd 110 - Read */
|
|
|
|
csr = CSR9_DI; EMIT;
|
|
|
|
csr = CSR9_DI | CSR9_SRC; EMIT;
|
|
|
|
csr = CSR9_DI; EMIT;
|
|
|
|
csr = CSR9_DI | CSR9_SRC; EMIT;
|
|
|
|
csr = CSR9_DI; EMIT;
|
|
|
|
csr = 0; EMIT;
|
|
|
|
csr = CSR9_SRC; EMIT;
|
|
|
|
csr = 0; EMIT;
|
|
|
|
|
|
|
|
/* addr to read */
|
|
|
|
for(i=nbAddrBits;i!=0;i--){
|
|
|
|
csr = (addr&(1<<(i-1))) != 0 ? CSR9_DI : 0; EMIT;
|
|
|
|
csr ^= CSR9_SRC; EMIT;
|
|
|
|
csr ^= CSR9_SRC; EMIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* actual read */
|
|
|
|
retVal=0;
|
|
|
|
for(i=0;i<16;i++){
|
|
|
|
retVal <<= 1;
|
|
|
|
csr = CSR9_SRC; EMIT;
|
|
|
|
retVal |= (io_inl(CSR_ADDR(dep, CSR9)) & CSR9_DO) == 0 ? 0 : 1;
|
|
|
|
csr = 0; EMIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clean up */
|
|
|
|
csr = 0; EMIT;
|
|
|
|
|
|
|
|
#undef EMIT
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void de_update_conf(dpeth_t * dep)
|
|
|
|
{
|
|
|
|
static char dpc_fmt[] = "x:d:x";
|
2010-05-18 00:22:53 +02:00
|
|
|
char ec_key[16];
|
2010-01-26 11:20:18 +01:00
|
|
|
long val;
|
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
strcpy(ec_key, "DEETH0");
|
|
|
|
ec_key[5] += de_instance;
|
|
|
|
|
2010-01-26 11:20:18 +01:00
|
|
|
dep->de_mode = DEM_ENABLED;
|
2010-05-18 00:22:53 +02:00
|
|
|
switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
|
2010-01-26 11:20:18 +01:00
|
|
|
case EP_OFF: dep->de_mode = DEM_DISABLED; break;
|
|
|
|
case EP_ON: dep->de_mode = DEM_SINK; break;
|
|
|
|
}
|
|
|
|
dep->de_base_port = 0;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_vread_s(const message * mp, int from_int)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
2011-09-29 19:37:05 +02:00
|
|
|
u8_t *buffer;
|
2010-01-26 11:20:18 +01:00
|
|
|
u32_t size;
|
2010-03-30 16:07:15 +02:00
|
|
|
int r, ix = 0;
|
|
|
|
vir_bytes bytes;
|
2010-01-26 11:20:18 +01:00
|
|
|
dpeth_t *dep = NULL;
|
|
|
|
de_loc_descr_t *descr = NULL;
|
|
|
|
iovec_dat_s_t *iovp = NULL;
|
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
dep = &de_state;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
dep->de_client = mp->m_source;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
if (dep->de_mode == DEM_ENABLED) {
|
|
|
|
|
|
|
|
descr = &dep->descr[DESCR_RECV][dep->cur_descr[DESCR_RECV]];
|
|
|
|
|
|
|
|
/* check if packet is in the current descr and only there */
|
|
|
|
if( !( !(descr->descr->des[DES0] & DES0_OWN) &&
|
|
|
|
(descr->descr->des[DES0] & DES0_FS) &&
|
|
|
|
(descr->descr->des[DES0] & DES0_LS) ))
|
|
|
|
goto suspend;
|
|
|
|
|
|
|
|
|
|
|
|
/*TODO: multi-descr msgs...*/
|
|
|
|
/* We only support packets contained in a single descriptor.
|
|
|
|
Setting the descriptor buffer size to less then
|
|
|
|
ETH_MAX_PACK_SIZE will result in multi-descriptor
|
|
|
|
packets that we won't be able to handle
|
|
|
|
*/
|
|
|
|
assert(!(descr->descr->des[DES0]&DES0_OWN));
|
|
|
|
assert(descr->descr->des[DES0]&DES0_FS);
|
|
|
|
assert(descr->descr->des[DES0]&DES0_LS);
|
|
|
|
|
|
|
|
/* Check for abnormal messages. We assert here
|
|
|
|
because this driver is for a virtualized
|
|
|
|
envrionment where we will not get bad packets
|
|
|
|
*/
|
|
|
|
assert(!(descr->descr->des[DES0]&DES0_ES));
|
|
|
|
assert(!(descr->descr->des[DES0]&DES0_RE));
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup the iovec entry to allow copying into
|
|
|
|
client layer
|
|
|
|
*/
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
dep->de_read_iovec.iod_proc_nr = mp->m_source;
|
|
|
|
de_get_userdata_s(mp->m_source, (cp_grant_id_t) mp->DL_GRANT, 0,
|
2010-01-26 11:20:18 +01:00
|
|
|
mp->DL_COUNT, dep->de_read_iovec.iod_iovec);
|
|
|
|
dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT;
|
2010-03-04 17:15:26 +01:00
|
|
|
dep->de_read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT;
|
2010-01-26 11:20:18 +01:00
|
|
|
dep->de_read_iovec.iod_iovec_offset = 0;
|
|
|
|
size = de_calc_iov_size(&dep->de_read_iovec);
|
|
|
|
if (size < ETH_MAX_PACK_SIZE)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_SizeErrMsg, size);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
/* Copy buffer to user area and clear ownage */
|
|
|
|
size = (descr->descr->des[DES0]&DES0_FL)>>DES0_FL_SHIFT;
|
|
|
|
|
|
|
|
/*TODO: Complain to MS */
|
|
|
|
/*HACK: VPC2007 returns packet of invalid size. Ethernet standard
|
|
|
|
specify 46 bytes as the minimum for valid payload. However, this is
|
|
|
|
artificial in so far as for certain packet types, notably ARP, less
|
|
|
|
then 46 bytes are needed to contain the full information. In a non
|
|
|
|
virtualized environment the 46 bytes rule is enforced in order to give
|
|
|
|
guarantee in the collison detection scheme. Of course, this being a
|
|
|
|
driver for a VPC2007, we won't have collisions and I can only suppose
|
|
|
|
MS decided to cut packet size to true minimum, regardless of the
|
|
|
|
46 bytes payload standard. Note that this seems to not happen in
|
|
|
|
bridged mode. Note also, that the card does not return runt or
|
|
|
|
incomplete frames to us, so this hack is safe
|
|
|
|
*/
|
|
|
|
if(size<60){
|
|
|
|
bzero(&descr->buf1[size], 60-size);
|
|
|
|
size=60;
|
|
|
|
}
|
|
|
|
/* End ugly hack */
|
|
|
|
|
|
|
|
iovp = &dep->de_read_iovec;
|
|
|
|
buffer = descr->buf1;
|
|
|
|
dep->bytes_rx += size;
|
|
|
|
dep->de_stat.ets_packetR++;
|
|
|
|
dep->de_read_s = size;
|
|
|
|
|
|
|
|
do {
|
|
|
|
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
|
|
|
|
if (bytes >= size)
|
|
|
|
bytes = size;
|
|
|
|
|
|
|
|
r= sys_safecopyto(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 0,
|
2012-06-16 03:46:15 +02:00
|
|
|
(vir_bytes)buffer, bytes);
|
2010-01-26 11:20:18 +01:00
|
|
|
if (r != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_CopyErrMsg, r);
|
2010-01-26 11:20:18 +01:00
|
|
|
buffer += bytes;
|
|
|
|
|
|
|
|
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
|
|
|
|
de_next_iov(iovp);
|
|
|
|
ix = 0;
|
|
|
|
}
|
|
|
|
} while ((size -= bytes) > 0);
|
|
|
|
|
|
|
|
descr->descr->des[DES0]=DES0_OWN;
|
|
|
|
dep->cur_descr[DESCR_RECV]++;
|
|
|
|
if(dep->cur_descr[DESCR_RECV] >= DE_NB_RECV_DESCR)
|
|
|
|
dep->cur_descr[DESCR_RECV] = 0;
|
|
|
|
|
|
|
|
DEBUG(printf("Read returned size = %d\n", size));
|
|
|
|
|
|
|
|
/* Reply information */
|
|
|
|
dep->de_flags |= DEF_ACK_RECV;
|
|
|
|
dep->de_flags &= NOT(DEF_READING);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!from_int){
|
2010-05-18 00:22:53 +02:00
|
|
|
do_reply(dep);
|
2010-01-26 11:20:18 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
suspend:
|
|
|
|
if(from_int){
|
|
|
|
assert(dep->de_flags & DEF_READING);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!(dep->de_flags & DEF_READING));
|
|
|
|
dep->rx_return_msg = *mp;
|
|
|
|
dep->de_flags |= DEF_READING;
|
2010-05-18 00:22:53 +02:00
|
|
|
do_reply(dep);
|
2010-01-26 11:20:18 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_conf_addr(dpeth_t * dep)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
|
|
|
static char ea_fmt[] = "x:x:x:x:x:x";
|
|
|
|
char ea_key[16];
|
|
|
|
int ix;
|
|
|
|
long val;
|
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
strcpy(ea_key, "DEETH0_EA");
|
|
|
|
ea_key[5] += de_instance;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
for (ix = 0; ix < SA_ADDR_LEN; ix++) {
|
|
|
|
val = dep->de_address.ea_addr[ix];
|
|
|
|
if (env_parse(ea_key, ea_fmt, ix, &val, 0x00L, 0xFFL) != EP_SET)
|
|
|
|
break;
|
|
|
|
dep->de_address.ea_addr[ix] = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ix != 0 && ix != SA_ADDR_LEN)
|
|
|
|
env_parse(ea_key, "?", 0, &val, 0L, 0L);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_first_init(dpeth_t *dep)
|
2010-01-26 11:20:18 +01:00
|
|
|
{
|
|
|
|
int i,j,r;
|
2011-09-29 19:37:05 +02:00
|
|
|
vir_bytes descr_vir = (vir_bytes)dep->sendrecv_descr_buf;
|
|
|
|
vir_bytes buffer_vir = (vir_bytes)dep->sendrecv_buf;
|
2010-01-26 11:20:18 +01:00
|
|
|
de_loc_descr_t *loc_descr;
|
|
|
|
u32_t temp;
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0;i<2;i++){
|
|
|
|
loc_descr = &dep->descr[i][0];
|
|
|
|
for(j=0; j < (i==DESCR_RECV ? DE_NB_RECV_DESCR : DE_NB_SEND_DESCR); j++){
|
|
|
|
|
|
|
|
/* assign buffer space for descriptor */
|
2011-09-29 19:37:05 +02:00
|
|
|
loc_descr->descr = (void*)descr_vir;
|
2010-01-26 11:20:18 +01:00
|
|
|
descr_vir += sizeof(de_descr_t);
|
|
|
|
|
|
|
|
/* assign space for buffer */
|
2011-09-29 19:37:05 +02:00
|
|
|
loc_descr->buf1 = (u8_t*)buffer_vir;
|
2010-01-26 11:20:18 +01:00
|
|
|
buffer_vir += (i==DESCR_RECV ? DE_RECV_BUF_SIZE : DE_SEND_BUF_SIZE);
|
|
|
|
loc_descr->buf2 = 0;
|
|
|
|
loc_descr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now that we have buffer space and descriptors, we need to
|
|
|
|
obtain their physical address to pass to the hardware
|
|
|
|
*/
|
|
|
|
for(i=0;i<2;i++){
|
|
|
|
loc_descr = &dep->descr[i][0];
|
|
|
|
temp = (i==DESCR_RECV ? DE_RECV_BUF_SIZE : DE_SEND_BUF_SIZE);
|
|
|
|
for(j=0; j < (i==DESCR_RECV ? DE_NB_RECV_DESCR : DE_NB_SEND_DESCR); j++){
|
|
|
|
/* translate buffers physical address */
|
2011-09-29 19:37:05 +02:00
|
|
|
r = sys_umap(SELF, VM_D, (vir_bytes)loc_descr->buf1, temp,
|
2010-01-26 11:20:18 +01:00
|
|
|
&(loc_descr->descr->des[DES_BUF1]));
|
2010-03-05 16:05:11 +01:00
|
|
|
if(r != OK) panic("umap failed: %d", r);
|
2010-01-26 11:20:18 +01:00
|
|
|
loc_descr->descr->des[DES_BUF2] = 0;
|
|
|
|
memset(&loc_descr->descr->des[DES0],0,sizeof(u32_t));
|
|
|
|
loc_descr->descr->des[DES1] = temp;
|
|
|
|
if(j==( (i==DESCR_RECV?DE_NB_RECV_DESCR:DE_NB_SEND_DESCR)-1))
|
|
|
|
loc_descr->descr->des[DES1] |= DES1_ER;
|
|
|
|
if(i==DESCR_RECV)
|
|
|
|
loc_descr->descr->des[DES0] |= DES0_OWN;
|
|
|
|
loc_descr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* record physical location of two first descriptor */
|
2011-09-29 19:37:05 +02:00
|
|
|
r = sys_umap(SELF, VM_D, (vir_bytes)dep->descr[DESCR_RECV][0].descr,
|
2010-01-26 11:20:18 +01:00
|
|
|
sizeof(de_descr_t), &dep->sendrecv_descr_phys_addr[DESCR_RECV]);
|
2010-03-05 16:05:11 +01:00
|
|
|
if(r != OK) panic(str_UmapErrMsg, r);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2011-09-29 19:37:05 +02:00
|
|
|
r = sys_umap(SELF, VM_D, (vir_bytes)dep->descr[DESCR_TRAN][0].descr,
|
2010-01-26 11:20:18 +01:00
|
|
|
sizeof(de_descr_t), &dep->sendrecv_descr_phys_addr[DESCR_TRAN]);
|
2010-03-05 16:05:11 +01:00
|
|
|
if(r != OK) panic(str_UmapErrMsg, r);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
DEBUG(printf("Descr: head tran=[%08X] head recv=[%08X]\n",
|
|
|
|
dep->sendrecv_descr_phys_addr[DESCR_TRAN],
|
|
|
|
dep->sendrecv_descr_phys_addr[DESCR_RECV]));
|
|
|
|
|
|
|
|
/* check alignment just to be extra safe */
|
|
|
|
for(i=0;i<2;i++){
|
|
|
|
loc_descr = &dep->descr[i][0];
|
|
|
|
for(j=0;j< (i==DESCR_RECV?DE_NB_RECV_DESCR:DE_NB_SEND_DESCR);j++){
|
2011-09-29 19:37:05 +02:00
|
|
|
r = sys_umap(SELF, VM_D, (vir_bytes)&(loc_descr->descr),
|
|
|
|
sizeof(de_descr_t), &temp);
|
2010-01-26 11:20:18 +01:00
|
|
|
if(r != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_UmapErrMsg, r);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
if( ((loc_descr->descr->des[DES_BUF1] & 0x3) != 0) ||
|
|
|
|
((loc_descr->descr->des[DES_BUF2] & 0x3) != 0) ||
|
|
|
|
((temp&0x3)!=0) )
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_AlignErrMsg, temp);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
loc_descr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Init default values */
|
|
|
|
dep->cur_descr[DESCR_TRAN]=1;
|
|
|
|
dep->cur_descr[DESCR_RECV]=0;
|
|
|
|
dep->bytes_rx = 0;
|
|
|
|
dep->bytes_tx = 0;
|
|
|
|
|
|
|
|
/* Set the interrupt handler policy. Request interrupts not to be reenabled
|
|
|
|
* automatically. Return the IRQ line number when an interrupt occurs.
|
|
|
|
*/
|
|
|
|
dep->de_hook = dep->de_irq;
|
|
|
|
sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
|
|
|
|
sys_irqenable(&dep->de_hook);
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_interrupt(const dpeth_t *dep){
|
2010-01-26 11:20:18 +01:00
|
|
|
u32_t val;
|
|
|
|
val = io_inl(CSR_ADDR(dep, CSR5));
|
|
|
|
|
|
|
|
if(val & CSR5_AIS){
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Abnormal Int CSR5=: %d", val);
|
2010-01-26 11:20:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if( (dep->de_flags & DEF_READING) && (val & CSR5_RI) ){
|
|
|
|
do_vread_s(&dep->rx_return_msg, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( (dep->de_flags & DEF_SENDING) && (val & CSR5_TI) ){
|
|
|
|
do_vwrite_s(&dep->tx_return_msg, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ack and reset interrupts */
|
|
|
|
io_outl(CSR_ADDR(dep, CSR5), 0xFFFFFFFF);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_reset(const dpeth_t *dep){
|
2010-01-26 11:20:18 +01:00
|
|
|
io_outl(CSR_ADDR(dep, CSR0), CSR0_SWR);
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_hw_conf(const dpeth_t *dep){
|
2010-01-26 11:20:18 +01:00
|
|
|
u32_t val;
|
|
|
|
|
|
|
|
/* CSR0 - global host bus prop */
|
|
|
|
val = CSR0_BAR | CSR0_CAL_8;
|
|
|
|
io_outl(CSR_ADDR(dep, CSR0), val);
|
|
|
|
|
|
|
|
/* CSR3 - Receive list BAR */
|
|
|
|
val = dep->sendrecv_descr_phys_addr[DESCR_RECV];
|
|
|
|
io_outl(CSR_ADDR(dep, CSR3), val);
|
|
|
|
|
|
|
|
/* CSR4 - Transmit list BAR */
|
|
|
|
val = dep->sendrecv_descr_phys_addr[DESCR_TRAN];
|
|
|
|
io_outl(CSR_ADDR(dep, CSR4), val);
|
|
|
|
|
|
|
|
/* CSR7 - interrupt mask */
|
|
|
|
val = CSR7_TI | CSR7_RI | CSR7_AI;
|
|
|
|
io_outl(CSR_ADDR(dep, CSR7), val);
|
|
|
|
|
|
|
|
/* CSR6 - operating mode register */
|
|
|
|
val = CSR6_MBO | CSR6_PS | CSR6_FD | CSR6_HBD |
|
|
|
|
CSR6_PCS | CSR6_SCR | CSR6_TR_00;
|
|
|
|
io_outl(CSR_ADDR(dep, CSR6), val);
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_start(const dpeth_t *dep){
|
2010-01-26 11:20:18 +01:00
|
|
|
u32_t val;
|
|
|
|
val = io_inl(CSR_ADDR(dep, CSR6)) | CSR6_ST | CSR6_SR;
|
|
|
|
io_outl(CSR_ADDR(dep, CSR6), val);
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_setup_frame(const dpeth_t *dep){
|
2010-01-26 11:20:18 +01:00
|
|
|
int i;
|
|
|
|
u32_t val;
|
|
|
|
|
|
|
|
/* this is not perfect... we assume pass all multicast and only
|
|
|
|
filter non-multicast frames */
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[0] = 0xFF;
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[1] = 0xFF;
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[4] = 0xFF;
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[5] = 0xFF;
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[8] = 0xFF;
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[9] = 0xFF;
|
|
|
|
for(i=1;i<16;i++){
|
|
|
|
memset(&(dep->descr[DESCR_TRAN][0].buf1[12*i]), 0, 12);
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[12*i+0] = dep->de_address.ea_addr[0];
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[12*i+1] = dep->de_address.ea_addr[1];
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[12*i+4] = dep->de_address.ea_addr[2];
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[12*i+5] = dep->de_address.ea_addr[3];
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[12*i+8] = dep->de_address.ea_addr[4];
|
|
|
|
dep->descr[DESCR_TRAN][0].buf1[12*i+9] = dep->de_address.ea_addr[5];
|
|
|
|
}
|
|
|
|
|
|
|
|
dep->descr[DESCR_TRAN][0].descr->des[DES0] = DES0_OWN;
|
|
|
|
dep->descr[DESCR_TRAN][0].descr->des[DES1] = DES1_SET |
|
|
|
|
DE_SETUP_FRAME_SIZE | DES1_IC;
|
|
|
|
|
|
|
|
/* start transmit process to process setup frame */
|
|
|
|
val = io_inl(CSR_ADDR(dep, CSR6)) | CSR6_ST;
|
|
|
|
io_outl(CSR_ADDR(dep, CSR6), val);
|
|
|
|
io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static int de_calc_iov_size(iovec_dat_s_t * iovp){
|
2010-01-26 11:20:18 +01:00
|
|
|
int size, ix;
|
|
|
|
size = ix = 0;
|
|
|
|
|
|
|
|
do{
|
|
|
|
size += iovp->iod_iovec[ix].iov_size;
|
|
|
|
if (++ix >= IOVEC_NR) {
|
|
|
|
de_next_iov(iovp);
|
|
|
|
ix = 0;
|
|
|
|
}
|
|
|
|
} while (ix < iovp->iod_iovec_s);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_get_userdata_s(int user_proc, cp_grant_id_t grant,
|
2010-01-26 11:20:18 +01:00
|
|
|
vir_bytes offset, int count, void *loc_addr){
|
|
|
|
int rc;
|
|
|
|
vir_bytes len;
|
|
|
|
|
|
|
|
len = (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_t);
|
2012-06-16 03:46:15 +02:00
|
|
|
rc = sys_safecopyfrom(user_proc, grant, 0, (vir_bytes)loc_addr, len);
|
2010-01-26 11:20:18 +01:00
|
|
|
if (rc != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_CopyErrMsg, rc);
|
2010-01-26 11:20:18 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void de_next_iov(iovec_dat_s_t * iovp){
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
iovp->iod_iovec_s -= IOVEC_NR;
|
|
|
|
iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
|
|
|
|
de_get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant, iovp->iod_iovec_offset,
|
|
|
|
iovp->iod_iovec_s, iovp->iod_iovec);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void do_vwrite_s(const message * mp, int from_int){
|
2010-01-26 11:20:18 +01:00
|
|
|
static u8_t setupDone = 0;
|
|
|
|
int size, r, bytes, ix, totalsize;
|
2010-04-01 14:51:31 +02:00
|
|
|
dpeth_t *dep;
|
2010-01-26 11:20:18 +01:00
|
|
|
iovec_dat_s_t *iovp = NULL;
|
|
|
|
de_loc_descr_t *descr = NULL;
|
2011-09-29 19:37:05 +02:00
|
|
|
u8_t *buffer = NULL;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
dep = &de_state;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
2010-05-18 00:22:53 +02:00
|
|
|
dep->de_client = mp->m_source;
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
if (dep->de_mode == DEM_ENABLED) {
|
|
|
|
|
|
|
|
if (!from_int && (dep->de_flags & DEF_SENDING))
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_BusyErrMsg);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
descr = &dep->descr[DESCR_TRAN][dep->cur_descr[DESCR_TRAN]];
|
|
|
|
|
|
|
|
if(( descr->descr->des[DES0] & DES0_OWN)!=0)
|
|
|
|
goto suspend;
|
|
|
|
|
|
|
|
if(!setupDone && (dep->cur_descr[DESCR_TRAN] == 0) ){
|
|
|
|
dep->descr[DESCR_TRAN][0].descr->des[DES0] = 0;
|
|
|
|
setupDone=1;
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer = descr->buf1;
|
|
|
|
iovp = &dep->de_write_iovec;
|
Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.
From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:
- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
when setting REP_ENDPT, matching requests in CANCEL calls, getting
DEV_SELECT flags, and retrieving of the real user process's endpoint
in DEV_OPEN.
The changes in this patch are binary backward compatible.
2011-04-11 19:35:05 +02:00
|
|
|
iovp->iod_proc_nr = mp->m_source;
|
|
|
|
de_get_userdata_s(mp->m_source, mp->DL_GRANT, 0,
|
2010-01-26 11:20:18 +01:00
|
|
|
mp->DL_COUNT, iovp->iod_iovec);
|
|
|
|
iovp->iod_iovec_s = mp->DL_COUNT;
|
2010-03-04 17:15:26 +01:00
|
|
|
iovp->iod_grant = (cp_grant_id_t) mp->DL_GRANT;
|
2010-01-26 11:20:18 +01:00
|
|
|
iovp->iod_iovec_offset = 0;
|
|
|
|
totalsize = size = de_calc_iov_size(iovp);
|
|
|
|
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_SizeErrMsg, size);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
dep->bytes_tx += size;
|
|
|
|
dep->de_stat.ets_packetT++;
|
|
|
|
|
|
|
|
ix=0;
|
|
|
|
do {
|
|
|
|
bytes = iovp->iod_iovec[ix].iov_size;
|
|
|
|
if (bytes >= size)
|
|
|
|
bytes = size;
|
|
|
|
|
|
|
|
r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
|
2012-06-16 03:46:15 +02:00
|
|
|
0, (vir_bytes)buffer, bytes);
|
2010-01-26 11:20:18 +01:00
|
|
|
if (r != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic(str_CopyErrMsg, r);
|
2010-01-26 11:20:18 +01:00
|
|
|
buffer += bytes;
|
|
|
|
|
|
|
|
if (++ix >= IOVEC_NR) {
|
|
|
|
de_next_iov(iovp);
|
|
|
|
ix = 0;
|
|
|
|
}
|
|
|
|
} while ((size -= bytes) > 0);
|
|
|
|
|
|
|
|
descr->descr->des[DES1] = (descr->descr->des[DES1]&DES1_ER) |
|
|
|
|
DES1_FS | DES1_LS | DES1_IC | totalsize;
|
|
|
|
descr->descr->des[DES0] = DES0_OWN;
|
|
|
|
|
|
|
|
dep->cur_descr[DESCR_TRAN]++;
|
|
|
|
if(dep->cur_descr[DESCR_TRAN] >= DE_NB_SEND_DESCR)
|
|
|
|
dep->cur_descr[DESCR_TRAN] = 0;
|
|
|
|
|
|
|
|
io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
dep->de_flags |= DEF_ACK_SEND;
|
|
|
|
if(from_int){
|
|
|
|
dep->de_flags &= NOT(DEF_SENDING);
|
|
|
|
return;
|
|
|
|
}
|
2010-05-18 00:22:53 +02:00
|
|
|
do_reply(dep);
|
2010-01-26 11:20:18 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
suspend:
|
|
|
|
if(from_int)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("should not happen: %d", 0);
|
2010-01-26 11:20:18 +01:00
|
|
|
|
|
|
|
dep->de_stat.ets_transDef++;
|
|
|
|
dep->de_flags |= DEF_SENDING;
|
|
|
|
dep->de_stat.ets_transDef++;
|
|
|
|
dep->tx_return_msg = *mp;
|
2010-05-18 00:22:53 +02:00
|
|
|
do_reply(dep);
|
2010-01-26 11:20:18 +01:00
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void warning(const char *type, int err){
|
2010-01-26 11:20:18 +01:00
|
|
|
printf("Warning: %s sys_%s failed (%d)\n", str_DevName, type, err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static u32_t io_inl(u16_t port){
|
2010-01-26 11:20:18 +01:00
|
|
|
u32_t value;
|
|
|
|
int rc;
|
|
|
|
if ((rc = sys_inl(port, &value)) != OK) warning("inl", rc);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2012-03-25 20:25:53 +02:00
|
|
|
static void io_outl(u16_t port, u32_t value){
|
2010-01-26 11:20:18 +01:00
|
|
|
int rc;
|
|
|
|
if ((rc = sys_outl(port, value)) != OK) warning("outl", rc);
|
|
|
|
return;
|
|
|
|
}
|