Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
86
Issues
86
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Software
Commits
68aaa1be
Commit
68aaa1be
authored
Jul 10, 2015
by
Adam Wujek
💬
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'wrs_watchdog'
Add wrs_watchdog.
parents
f43421ef
f1e9c39e
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
855 additions
and
3 deletions
+855
-3
Kconfig
Kconfig
+9
-0
wrs-user-manual.in
doc/wrs-user-manual.in
+2
-1
Makefile
kernel/wbgen-regs/Makefile
+1
-1
wdog-regs.h
kernel/wbgen-regs/wdog-regs.h
+108
-0
wdog-regs.wb
kernel/wbgen-regs/wdog-regs.wb
+131
-0
Makefile
userspace/Makefile
+2
-1
fpga_io.h
userspace/include/fpga_io.h
+3
-0
wrs_watchdog.sh
userspace/rootfs_override/etc/init.d/wrs_watchdog.sh
+81
-0
wrs_watchdog.conf
userspace/rootfs_override/etc/monit.d/wrs_watchdog.conf
+4
-0
S70wrs_watchdog.sh
userspace/rootfs_override/etc/rcS/S70wrs_watchdog.sh
+1
-0
WR-SWITCH-MIB.txt
userspace/snmpd/WR-SWITCH-MIB.txt
+17
-0
wrsBootStatusGroup.c
userspace/snmpd/wrsBootStatusGroup.c
+27
-0
wrsBootStatusGroup.h
userspace/snmpd/wrsBootStatusGroup.h
+1
-0
wrsStartCntGroup.c
userspace/snmpd/wrsStartCntGroup.c
+3
-0
wrsStartCntGroup.h
userspace/snmpd/wrsStartCntGroup.h
+1
-0
Makefile
userspace/wrs_watchdog/Makefile
+41
-0
wrs_watchdog.c
userspace/wrs_watchdog/wrs_watchdog.c
+328
-0
wrs_watchdog.h
userspace/wrs_watchdog/wrs_watchdog.h
+95
-0
No files found.
Kconfig
View file @
68aaa1be
...
...
@@ -183,6 +183,15 @@ config WRS_LOG_MONIT
Please note that unknown facility names will generate a runtime error
on the switch.
config WRS_LOG_WRSWATCHDOG
string "Logging directions for the wrs_watchdog"
default "daemon.info"
help
The string can be a pathname (e.g. /dev/kmsg) or a <facility>.<level>
spefification like "daemon.debug". An empty strings is used
to represent no logging (like /dev/null). Please note that
unknown facility names will generate a runtime error on the switch.
config KEEP_ROOTFS
bool "Keep generated filesystem and related script"
help
...
...
doc/wrs-user-manual.in
View file @
68aaa1be
...
...
@@ -495,6 +495,7 @@ value is changed by the web interface, proper action is taken.
@item CONFIG
_
WRS
_
LOG
_
HAL
@itemx CONFIG
_
WRS
_
LOG
_
RTU
@itemx CONFIG
_
WRS
_
LOG
_
PTP
@itemx CONFIG
_
WRS
_
LOG
_
WRSWATCHDOG
Logging options for the three main WRS processes. Each value
can be a pathname, to select logging to file (and @t
{
/dev/kmsg
}
...
...
@@ -502,7 +503,7 @@ value is changed by the web interface, proper action is taken.
like @t
{
daemon.debug
}
, for syslog-based logging.
An empty strings selects no logging at all. Please note that
unknown facility names will generate a runtime error on the switch.
All
three
strings default to ``@t
{
daemon.info
}
''.
All
four
strings default to ``@t
{
daemon.info
}
''.
@item CONFIG
_
WRS
_
LOG
_
SNMPD
...
...
kernel/wbgen-regs/Makefile
View file @
68aaa1be
...
...
@@ -20,7 +20,7 @@ WB_GEN10 = $(MODULES_WRS)/wrsw_rt_subsystem/wrsw_gen_10mhz.wb
WB_SOFTPLL
=
$(MODULES_WRC)
/wr_softpll_ng/spll_wb_slave.wb
HEADERS
=
endpoint-regs.h endpoint-mdio.h ppsg-regs.h tstamp-regs.h rtu-regs.h
\
nic-regs.h softpll-regs.h pstats-regs.h gen10mhz-regs.h
nic-regs.h softpll-regs.h pstats-regs.h gen10mhz-regs.h
wdog-regs.h
WBINPUT
=
$
(
HEADERS:.h
=
wb
)
# No default, for people who types "make" everywhere (like me)
...
...
kernel/wbgen-regs/wdog-regs.h
0 → 100644
View file @
68aaa1be
/*
Register definitions for slave core: WR Watchdog module
* File : wdog-regs.h
* Author : auto-generated by wbgen2 from wdog-regs.wb
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wdog-regs.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WDOG
#define __WBGEN2_REGDEFS_WDOG
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <stdint.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Restart counter */
/* definitions for register: Control Register */
/* definitions for field: Port select in reg: Control Register */
#define WDOG_CR_PORT_MASK WBGEN2_GEN_MASK(0, 8)
#define WDOG_CR_PORT_SHIFT 0
#define WDOG_CR_PORT_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WDOG_CR_PORT_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: Force reset in reg: Control Register */
#define WDOG_CR_RST WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Port FSM activity register */
/* definitions for register: Port FSM register */
/* definitions for field: IB alloc FSM state in reg: Port FSM register */
#define WDOG_FSM_IB_ALLOC_MASK WBGEN2_GEN_MASK(0, 4)
#define WDOG_FSM_IB_ALLOC_SHIFT 0
#define WDOG_FSM_IB_ALLOC_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define WDOG_FSM_IB_ALLOC_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
/* definitions for field: IB transfer FSM state in reg: Port FSM register */
#define WDOG_FSM_IB_TRANS_MASK WBGEN2_GEN_MASK(4, 4)
#define WDOG_FSM_IB_TRANS_SHIFT 4
#define WDOG_FSM_IB_TRANS_W(value) WBGEN2_GEN_WRITE(value, 4, 4)
#define WDOG_FSM_IB_TRANS_R(reg) WBGEN2_GEN_READ(reg, 4, 4)
/* definitions for field: IB receive FSM state in reg: Port FSM register */
#define WDOG_FSM_IB_RCV_MASK WBGEN2_GEN_MASK(8, 4)
#define WDOG_FSM_IB_RCV_SHIFT 8
#define WDOG_FSM_IB_RCV_W(value) WBGEN2_GEN_WRITE(value, 8, 4)
#define WDOG_FSM_IB_RCV_R(reg) WBGEN2_GEN_READ(reg, 8, 4)
/* definitions for field: IB LL FSM state in reg: Port FSM register */
#define WDOG_FSM_IB_LL_MASK WBGEN2_GEN_MASK(12, 4)
#define WDOG_FSM_IB_LL_SHIFT 12
#define WDOG_FSM_IB_LL_W(value) WBGEN2_GEN_WRITE(value, 12, 4)
#define WDOG_FSM_IB_LL_R(reg) WBGEN2_GEN_READ(reg, 12, 4)
/* definitions for field: OB prepare FSM state in reg: Port FSM register */
#define WDOG_FSM_OB_PREP_MASK WBGEN2_GEN_MASK(16, 4)
#define WDOG_FSM_OB_PREP_SHIFT 16
#define WDOG_FSM_OB_PREP_W(value) WBGEN2_GEN_WRITE(value, 16, 4)
#define WDOG_FSM_OB_PREP_R(reg) WBGEN2_GEN_READ(reg, 16, 4)
/* definitions for field: OB send FSM state in reg: Port FSM register */
#define WDOG_FSM_OB_SEND_MASK WBGEN2_GEN_MASK(20, 4)
#define WDOG_FSM_OB_SEND_SHIFT 20
#define WDOG_FSM_OB_SEND_W(value) WBGEN2_GEN_WRITE(value, 20, 4)
#define WDOG_FSM_OB_SEND_R(reg) WBGEN2_GEN_READ(reg, 20, 4)
/* definitions for field: FREE FSM state in reg: Port FSM register */
#define WDOG_FSM_FREE_MASK WBGEN2_GEN_MASK(24, 4)
#define WDOG_FSM_FREE_SHIFT 24
#define WDOG_FSM_FREE_W(value) WBGEN2_GEN_WRITE(value, 24, 4)
#define WDOG_FSM_FREE_R(reg) WBGEN2_GEN_READ(reg, 24, 4)
PACKED
struct
WDOG_WB
{
/* [0x0]: REG Restart counter */
uint32_t
RST_CNT
;
/* [0x4]: REG Control Register */
uint32_t
CR
;
/* [0x8]: REG Port FSM activity register */
uint32_t
ACT
;
/* [0xc]: REG Port FSM register */
uint32_t
FSM
;
};
#endif
kernel/wbgen-regs/wdog-regs.wb
0 → 100644
View file @
68aaa1be
-- -*- Mode: LUA; tab-width: 2 -*-
-- White-Rabbit Watchdog Module
-- author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
--
-- Use wbgen2 to generate code, documentation and more.
-- wbgen2 is available at:
-- http://www.ohwr.org/projects/wishbone-gen
--
peripheral {
name = "WR Watchdog module";
description = "The module monitors the Switching Core and performs a reset when swcore is stuck";
hdl_entity = "wdog_wishbone_slave";
prefix = "wdog";
reg {
name = "Restart counter";
description = "Counts how many times watchdog had to restart the swcore";
prefix = "RST_CNT";
field {
name = "counter value";
size = 32;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Control Register";
prefix = "CR";
field {
name = "Port select";
prefix = "PORT";
size = 8;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Force reset";
prefix = "RST";
size = 1;
align = 31;
type = MONOSTABLE;
access_dev = READ_ONLY;
access_bus = WRITE_ONLY;
};
};
reg {
name = "Port FSM activity register";
prefix = "ACT";
field {
name = "bit-per-fsm activity since the last readout";
size = 7;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Port FSM register";
prefix = "FSM";
field {
name = "IB alloc FSM state";
prefix = "IB_ALLOC";
size = 4;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "IB transfer FSM state";
prefix = "IB_TRANS";
size = 4;
align = 4;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "IB receive FSM state";
prefix = "IB_RCV";
size = 4;
align = 8;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "IB LL FSM state";
prefix = "IB_LL";
size = 4;
align = 12;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "OB prepare FSM state";
prefix = "OB_PREP";
size = 4;
align = 16;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "OB send FSM state";
prefix = "OB_SEND";
size = 4;
align = 20;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "FREE FSM state";
prefix = "FREE";
size = 4;
align = 24;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
};
userspace/Makefile
View file @
68aaa1be
...
...
@@ -5,7 +5,8 @@ WRDEV_DIR ?= $(WRS_BASE_DIR)/..
# subdirectories we want to compile
SUBDIRS
=
libwr mini-rpc libsdb
\
wrsw_hal wrsw_rtud tools snmpd
wrsw_hal wrsw_rtud tools snmpd
\
wrs_watchdog
# all variables are exported
export
...
...
userspace/include/fpga_io.h
View file @
68aaa1be
...
...
@@ -32,6 +32,9 @@
/* HardWare Debugging Unit */
#define FPGA_BASE_HWDU 0x59000
/* Watchdog Module */
#define FPGA_BASE_WDOG 0x5A000
/* Endpoint */
#define FPGA_BASE_EP0 0x30000
...
...
userspace/rootfs_override/etc/init.d/wrs_watchdog.sh
0 → 100755
View file @
68aaa1be
#!/bin/sh
WDG_PID
=
/var/run/wrs_watchdog.pid
dotconfig
=
/wr/etc/dot-config
start_counter
()
{
# increase boot counter
COUNTER_FILE
=
"/tmp/start_cnt_wrs_watchdog"
START_COUNTER
=
1
if
[
-f
"
$COUNTER_FILE
"
]
;
then
read
-r
START_COUNTER <
$COUNTER_FILE
START_COUNTER
=
$((
START_COUNTER+1
))
fi
echo
"
$START_COUNTER
"
>
$COUNTER_FILE
}
start
()
{
echo
-n
"Starting wrs_watchdog daemon: "
if
[
-f
$WDG_PID
]
&&
kill
-0
`
cat
$WDG_PID
`
&> /dev/null
;
then
# wrs_watchdog already running
echo
"Failed (already running?)"
else
if
[
-f
$dotconfig
]
;
then
.
$dotconfig
else
echo
"
$0
unable to source dot-config (
$dotconfig
)!"
fi
WRS_LOG
=
$CONFIG_WRS_LOG_WRSWATCHDOG
# if empty turn it to /dev/null
if
[
-z
$WRS_LOG
]
;
then
WRS_LOG
=
"/dev/null"
;
fi
# if a pathname, use it
if
echo
"
$WRS_LOG
"
|
grep
/
>
/dev/null
;
then
eval
LOGPIPE
=
\"
\>
$WRS_LOG
2
\>\&
1
\"
;
else
# not a pathname: use verbatim
eval
LOGPIPE
=
\"
2
\>\&
1
\|
logger
-t
wr-switch
-p
$WRS_LOG
\"
fi
eval
/wr/bin/wrs_watchdog
-d
-p
$WDG_PID
$LOGPIPE
\&
start_counter
echo
"OK"
fi
}
stop
()
{
echo
-n
"Stopping wrs_watchdog "
start-stop-daemon
-K
-q
-p
$WDG_PID
if
[
$?
-eq
0
]
;
then
echo
"OK"
else
echo
"Failed"
fi
}
restart
()
{
stop
start
}
case
"
$1
"
in
start
)
start
;;
stop
)
stop
;;
restart|reload
)
restart
;;
*
)
echo
$"Usage:
$0
{start|stop|restart}"
exit
1
;;
esac
userspace/rootfs_override/etc/monit.d/wrs_watchdog.conf
0 → 100644
View file @
68aaa1be
check
process
wrs_watchdog
with
pidfile
/
var
/
run
/
wrs_watchdog
.
pid
start
program
=
"/etc/init.d/wrs_watchdog.sh start"
stop
program
=
"/etc/init.d/wrs_watchdog.sh stop"
if
5
restarts
within
10
cycles
then
exec
"/etc/init.d/reboot.sh wrs_watchdog"
userspace/rootfs_override/etc/rcS/S70wrs_watchdog.sh
0 → 120000
View file @
68aaa1be
../init.d/wrs_watchdog.sh
\ No newline at end of file
userspace/snmpd/WR-SWITCH-MIB.txt
View file @
68aaa1be
...
...
@@ -703,6 +703,15 @@ wrsBootUserspaceDaemonsMissing OBJECT-TYPE
are reported as maximum number of missing modules"
::= { wrsBootStatusGroup 14 }
wrsGwWatchdogTimeouts OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of times the watchdog has restarted the HDL module responsible
for the Ethernet switching process."
::= { wrsBootStatusGroup 15 }
-- wrsTemperatureGroup (.7.1.3)
wrsTemperatureGroup OBJECT IDENTIFIER ::= { wrsOperationStatus 3 }
...
...
@@ -976,6 +985,14 @@ wrsStartCntSyslogd OBJECT-TYPE
"Nmber of SYSLOG daemon starts"
::= { wrsStartCntGroup 7 }
wrsStartCntWrsWatchdog OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Nmber of wrs_watchdog daemon starts"
::= { wrsStartCntGroup 8 }
-- wrsSpllState (.7.3)
wrsSpllState OBJECT IDENTIFIER ::= { wrsExpertStatus 3 }
...
...
userspace/snmpd/wrsBootStatusGroup.c
View file @
68aaa1be
...
...
@@ -18,6 +18,9 @@
/* get process list, output only process' command */
#define PROCESS_COMMAND "/bin/ps axo command"
/* get number of GW watchdog timeouts */
#define WDOG_COMMAND "/wr/bin/wrs_watchdog -g"
/* Macros for fscanf function to read line with maximum of "x" characters
* without new line. Macro expands to something like: "%10[^\n]" */
#define LINE_READ_LEN_HELPER(x) "%"#x"[^\n]"
...
...
@@ -42,6 +45,7 @@ static struct pickinfo wrsBootStatus_pickinfo[] = {
FIELD
(
wrsBootStatus_s
,
ASN_INTEGER
,
wrsBootLoadLM32
),
FIELD
(
wrsBootStatus_s
,
ASN_INTEGER
,
wrsBootKernelModulesMissing
),
FIELD
(
wrsBootStatus_s
,
ASN_INTEGER
,
wrsBootUserspaceDaemonsMissing
),
FIELD
(
wrsBootStatus_s
,
ASN_COUNTER
,
wrsGwWatchdogTimeouts
),
};
struct
wrsBootStatus_s
wrsBootStatus_s
;
...
...
@@ -456,6 +460,26 @@ static void get_daemons_status(void)
pclose
(
f
);
}
static
void
get_n_watchdog_timouts
(
void
)
{
FILE
*
f
;
wrsBootStatus_s
.
wrsGwWatchdogTimeouts
=
0
;
f
=
popen
(
WDOG_COMMAND
,
"r"
);
if
(
!
f
)
{
snmp_log
(
LOG_ERR
,
"SNMP: wrsBootStatusGroup failed to execute "
WDOG_COMMAND
"
\n
"
);
return
;
}
/* Number of watchdog restarts is returned as a int value,
* if error there nothing we can do */
fscanf
(
f
,
"%d"
,
&
wrsBootStatus_s
.
wrsGwWatchdogTimeouts
);
pclose
(
f
);
}
time_t
wrsBootStatus_data_fill
(
void
)
{
static
time_t
time_update
;
...
...
@@ -483,6 +507,9 @@ time_t wrsBootStatus_data_fill(void)
/* get info about running daemons */
get_daemons_status
();
/* get info about number of gateware watchdog timeouts */
get_n_watchdog_timouts
();
/* there was an update, return current time */
return
time_update
;
}
...
...
userspace/snmpd/wrsBootStatusGroup.h
View file @
68aaa1be
...
...
@@ -53,6 +53,7 @@ struct wrsBootStatus_s {
int32_t
wrsBootLoadLM32
;
int32_t
wrsBootKernelModulesMissing
;
int32_t
wrsBootUserspaceDaemonsMissing
;
int32_t
wrsGwWatchdogTimeouts
;
};
extern
struct
wrsBootStatus_s
wrsBootStatus_s
;
...
...
userspace/snmpd/wrsStartCntGroup.c
View file @
68aaa1be
...
...
@@ -6,6 +6,7 @@
#define START_CNT_HTTPD "/tmp/start_cnt_httpd"
#define START_CNT_SNMPD "/tmp/start_cnt_snmpd"
#define START_CNT_SYSLOGD "/tmp/start_cnt_syslogd"
#define START_CNT_WRSWATCHDOG "/tmp/start_cnt_wrs_watchdog"
static
struct
pickinfo
wrsStartCnt_pickinfo
[]
=
{
FIELD
(
wrsStartCnt_s
,
ASN_COUNTER
,
wrsStartCntHAL
),
...
...
@@ -15,6 +16,7 @@ static struct pickinfo wrsStartCnt_pickinfo[] = {
FIELD
(
wrsStartCnt_s
,
ASN_COUNTER
,
wrsStartCntHttpd
),
FIELD
(
wrsStartCnt_s
,
ASN_COUNTER
,
wrsStartCntSnmpd
),
FIELD
(
wrsStartCnt_s
,
ASN_COUNTER
,
wrsStartCntSyslogd
),
FIELD
(
wrsStartCnt_s
,
ASN_COUNTER
,
wrsStartCntWrsWatchdog
),
};
struct
wrsStartCnt_s
wrsStartCnt_s
;
...
...
@@ -59,6 +61,7 @@ time_t wrsStartCnt_data_fill(void){
read_start_count
(
START_CNT_HTTPD
,
&
wrsStartCnt_s
.
wrsStartCntHttpd
);
read_start_count
(
START_CNT_SNMPD
,
&
wrsStartCnt_s
.
wrsStartCntSnmpd
);
read_start_count
(
START_CNT_SYSLOGD
,
&
wrsStartCnt_s
.
wrsStartCntSyslogd
);
read_start_count
(
START_CNT_WRSWATCHDOG
,
&
wrsStartCnt_s
.
wrsStartCntWrsWatchdog
);
/* there was an update, return current time */
return
time_update
;
...
...
userspace/snmpd/wrsStartCntGroup.h
View file @
68aaa1be
...
...
@@ -12,6 +12,7 @@ struct wrsStartCnt_s {
uint32_t
wrsStartCntHttpd
;
uint32_t
wrsStartCntSnmpd
;
uint32_t
wrsStartCntSyslogd
;
uint32_t
wrsStartCntWrsWatchdog
;
};
extern
struct
wrsStartCnt_s
wrsStartCnt_s
;
...
...
userspace/wrs_watchdog/Makefile
0 → 100644
View file @
68aaa1be
OBJS
=
wrs_watchdog.o
BINARY
=
wrs_watchdog
WR_INSTALL_ROOT
?=
/usr/lib/white-rabbit
# # Standard stanza for cross-compilation (courtesy of the linux makefile)
AS
=
$(CROSS_COMPILE)
as
LD
=
$(CROSS_COMPILE)
ld
CC
=
$(CROSS_COMPILE)
gcc
CPP
=
$(CC)
-E
AR
=
$(CROSS_COMPILE)
ar
NM
=
$(CROSS_COMPILE)
nm
STRIP
=
$(CROSS_COMPILE)
strip
OBJCOPY
=
$(CROSS_COMPILE)
objcopy
OBJDUMP
=
$(CROSS_COMPILE)
objdump
CFLAGS
=
-O
-g
-Wall
\
-I
../include
\
-I
../libwr/include
\
-I
../mini-rpc
\
-I
$(LINUX)
/arch/arm/mach-at91/include
GIT_VER
=
$(
shell
git describe
--always
--dirty
|
sed
's;^wr-switch-sw-;;'
)
CFLAGS
+=
-D__GIT_VER__
=
"
\"
${
GIT_VER
}
\"
"
LDFLAGS
=
-L
../libwr
-L
../mini-rpc
\
-lm
-ldl
-lwr
-lminipc
all
:
$(BINARY)
$(BINARY)
:
$(OBJS)
$(CC)
-o
$@
$^
$(LDFLAGS)
install
:
all
install
-d
$(WR_INSTALL_ROOT)
/bin
install
$(BINARY)
$(WR_INSTALL_ROOT)
/bin
clean
:
rm
-f
$(BINARY)
*
.o
*
~
userspace/wrs_watchdog/wrs_watchdog.c
0 → 100644
View file @
68aaa1be
/*
* Copyright (c) 2015, CERN
*
* Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <getopt.h>
#include <inttypes.h>
#include <stddef.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <libwr/switch_hw.h>
#include <libwr/wrs-msg.h>
#include <fpga_io.h>
#include <regs/wdog-regs.h>
#include "wrs_watchdog.h"
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
#define RST_THR 2
#define wdog_write(reg, val) \
_fpga_writel(FPGA_BASE_WDOG + offsetof(struct WDOG_WB, reg), val)
#define wdog_read(reg) \
_fpga_readl(FPGA_BASE_WDOG + offsetof(struct WDOG_WB, reg))
static
char
*
prgname
;
int
daemon_mode
;
int
list_mode
;
int
port_num
=
0
;
int
get_nports_from_hal
(
void
)
{
struct
hal_shmem_header
*
h
;
struct
wrs_shm_head
*
hal_head
;
int
hal_nports_local
;
/* local copy of number of ports */
int
ii
;
int
n_wait
=
0
;
/* wait forever for HAL */
while
(
!
(
hal_head
=
wrs_shm_get
(
wrs_shm_hal
,
""
,
WRS_SHM_READ
|
WRS_SHM_LOCKED
)))
{
if
(
n_wait
>
5
)
{
/* print if waiting more than 5 seconds, some waiting
* is expected since hal requires few seconds to start
*/
pr_error
(
"unable to open shm for HAL!
\n
"
);
}
n_wait
++
;
sleep
(
1
);
}
h
=
(
void
*
)
hal_head
+
hal_head
->
data_off
;
n_wait
=
0
;
while
(
1
)
{
/* wait forever for HAL to produce consistent nports */
ii
=
wrs_shm_seqbegin
(
hal_head
);
/* Assume number of ports does not change in runtime */
hal_nports_local
=
h
->
nports
;
if
(
!
wrs_shm_seqretry
(
hal_head
,
ii
))
break
;
if
(
n_wait
>
5
)
{
/* print if waiting more than 5 seconds, some waiting
* is expected since hal requires few seconds to start
*/
pr_error
(
"Wait for HAL.
\n
"
);
}
n_wait
++
;
sleep
(
1
);
}
/* check hal's shm version */
if
(
hal_head
->
version
!=
HAL_SHMEM_VERSION
)
{
pr_error
(
"unknown hal's shm version %i (known is %i)
\n
"
,
hal_head
->
version
,
HAL_SHMEM_VERSION
);
exit
(
-
1
);
}
if
(
hal_nports_local
>
HAL_MAX_PORTS
)
{
pr_error
(
"Too many ports reported by HAL. %d vs %d "
"supported
\n
"
,
hal_nports_local
,
HAL_MAX_PORTS
);
exit
(
-
1
);
}
return
hal_nports_local
;
}
uint32_t
show_counter
(
void
)
{
uint32_t
val
;
val
=
wdog_read
(
RST_CNT
);
printf
(
"%u
\n
"
,
val
);
return
val
;
}
void
force_rst
(
void
)
{
wdog_write
(
CR
,
WDOG_CR_RST
);
}
struct
swc_fsms
read_port
(
int
port
)
{
int
i
;
struct
swc_fsms
fsms
;
uint32_t
val_fsm
,
val_act
;
wdog_write
(
CR
,
WDOG_CR_PORT_W
(
port
));
val_fsm
=
wdog_read
(
FSM
);
val_act
=
wdog_read
(
ACT
);
/* parsing results */
fsms
.
state
[
0
]
=
WDOG_FSM_IB_ALLOC_R
(
val_fsm
);
fsms
.
state
[
1
]
=
WDOG_FSM_IB_TRANS_R
(
val_fsm
);
fsms
.
state
[
2
]
=
WDOG_FSM_IB_RCV_R
(
val_fsm
);
fsms
.
state
[
3
]
=
WDOG_FSM_IB_LL_R
(
val_fsm
);
fsms
.
state
[
4
]
=
WDOG_FSM_OB_PREP_R
(
val_fsm
);
fsms
.
state
[
5
]
=
WDOG_FSM_OB_SEND_R
(
val_fsm
);
fsms
.
state
[
6
]
=
WDOG_FSM_FREE_R
(
val_fsm
);
for
(
i
=
0
;
i
<
FSMS_NO
;
++
i
)
{
fsms
.
act
[
i
]
=
(
val_act
&
(
1
<<
i
))
>>
i
;
}
return
fsms
;
}
void
list_fsms
(
void
)
{
int
i
;
struct
swc_fsms
fsms
;
for
(
i
=
0
;
i
<=
port_num
;
++
i
)
{
/* yes, it is i<=port_num because we're reading FSMs for all WR
* ports + NIC */
fsms
=
read_port
(
i
);
printf
(
"PORT %2d: "
,
i
);
printf
(
"ib_alloc(%d): %-14s"
,
fsms
.
act
[
ALLOC_IDX
],
alloc_states
[
fsms
.
state
[
ALLOC_IDX
]]);
printf
(
"ib_trans(%d): %-15s"
,
fsms
.
act
[
TRANS_IDX
],
trans_states
[
fsms
.
state
[
TRANS_IDX
]]);
printf
(
"ib_rcv(%d): %-12s"
,
fsms
.
act
[
RCV_IDX
],
rcv_states
[
fsms
.
state
[
RCV_IDX
]]);
printf
(
"ib_ll(%d): %-17s"
,
fsms
.
act
[
LL_IDX
],
ll_states
[
fsms
.
state
[
LL_IDX
]]);
printf
(
"ob_prep(%d): %-18s"
,
fsms
.
act
[
PREP_IDX
],
prep_states
[
fsms
.
state
[
PREP_IDX
]]);
printf
(
"ob_send(%d): %-14s"
,
fsms
.
act
[
SEND_IDX
],
send_states
[
fsms
.
state
[
SEND_IDX
]]);
printf
(
"free(%d): %s
\n
"
,
fsms
.
act
[
FREE_IDX
],
free_states
[
fsms
.
state
[
FREE_IDX
]]);
}
}
int
update_stuck
(
struct
swc_fsms
*
fsms
,
int
*
stuck_cnt
)
{
int
fsm_it
;
for
(
fsm_it
=
0
;
fsm_it
<
FSMS_NO
;
++
fsm_it
)
{
if
(
fsms
->
state
[
fsm_it
]
!=
idles
[
fsm_it
]
&&
fsms
->
act
[
fsm_it
]
==
0
)
{
stuck_cnt
[
fsm_it
]
++
;
}
else
{
stuck_cnt
[
fsm_it
]
=
0
;
}
/* and we also check if reset is needed */
if
(
stuck_cnt
[
fsm_it
]
>=
RST_THR
)
{
return
1
;
}
}
return
0
;
}
void
clear_stuck
(
int
cnt
[][
FSMS_NO
])
{
int
port_it
,
fsm_it
;
for
(
port_it
=
0
;
port_it
<=
port_num
;
++
port_it
)
{
for
(
fsm_it
=
0
;
fsm_it
<
FSMS_NO
;
++
fsm_it
)
{
cnt
[
port_it
][
fsm_it
]
=
0
;
}
}
}
void
write_pidfile
(
char
*
file
,
pid_t
pid
)
{
FILE
*
f
;
if
(
file
==
NULL
)
return
;
f
=
fopen
(
file
,
"w"
);
if
(
f
==
NULL
)
{
pr_error
(
"Could not create PID file
\n
"
);
return
;
}
fprintf
(
f
,
"%d
\n
"
,
(
int
)
pid
);
fclose
(
f
);
}
void
endless_watchdog
(
void
)
{
struct
swc_fsms
fsms
[
19
];
int
stuck_cnt
[
19
][
FSMS_NO
]
=
{
{
0
}
};
int
port_it
;
int
rst
=
0
;
while
(
1
)
{
/* first we read all the ports */
for
(
port_it
=
0
;
port_it
<=
port_num
;
++
port_it
)
{
fsms
[
port_it
]
=
read_port
(
port_it
);
rst
=
update_stuck
(
&
(
fsms
[
port_it
]),
stuck_cnt
[
port_it
]);
if
(
rst
)
break
;
}
/* handle reset if needed */
if
(
rst
)
{
pr_warning
(
"SWCore stuck... resetting
\n
"
);
force_rst
();
clear_stuck
(
stuck_cnt
);
}
sleep
(
1
);
}
}
void
print_help
(
char
*
prgname
)
{
printf
(
"wrs_watchdog. Commit %s, built on "
__DATE__
"
\n
"
,
__GIT_VER__
);
printf
(
"usage: %s <options>
\n
"
,
prgname
);
printf
(
" -d Run as daemon
\n
"
" -l List FSMs state for all ports
\n
"
" -n <8/18> Set the number of ports
\n
"
" -g Show current value of the restart counter
\n
"
" -r Force restart of the Swcore
\n
"
" -h Show this help message
\n
"
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
c
=
0
;
char
*
pidfile
=
NULL
;
prgname
=
argv
[
0
];
if
(
argc
==
1
)
{
print_help
(
prgname
);
return
0
;
}
wrs_msg_init
(
argc
,
argv
);
if
(
shw_fpga_mmap_init
()
<
0
)
{
pr_error
(
"%s: Can't access device memory
\n
"
,
prgname
);
exit
(
1
);
}
while
((
c
=
getopt
(
argc
,
argv
,
"dhrgqvn:lp:"
))
!=
-
1
)
{
switch
(
c
)
{
case
'd'
:
daemon_mode
=
1
;
break
;
case
'l'
:
list_mode
=
1
;
break
;
case
'r'
:
force_rst
();
break
;
case
'g'
:
show_counter
();
break
;
case
'n'
:
port_num
=
atoi
(
optarg
);
pr_info
(
"Read %d ports from cmdline
\n
"
,
port_num
);
break
;
case
'p'
:
pidfile
=
optarg
;
break
;
case
'q'
:
break
;
/* done in wrs_msg_init() */
case
'v'
:
break
;
/* done in wrs_msg_init() */
case
'h'
:
default:
print_help
(
prgname
);
exit
(
1
);
}
}
if
(
!
port_num
)
{
/* if port_num not read from parameter read it from HAL */
port_num
=
get_nports_from_hal
();
pr_info
(
"Read %d ports from HAL
\n
"
,
port_num
);
}
if
(
!
daemon_mode
&&
list_mode
)
{
list_fsms
();
}
if
(
daemon_mode
)
{
wrs_msg
(
LOG_ALERT
,
"wrs_watchdog. Commit %s, built on "
__DATE__
"
\n
"
,
__GIT_VER__
);
write_pidfile
(
pidfile
,
getpid
());
pr_info
(
"Demonize
\n
"
);
endless_watchdog
();
}
return
0
;
}
userspace/wrs_watchdog/wrs_watchdog.h
0 → 100644
View file @
68aaa1be
#ifndef __WRS_WATCHDOG__
#define __WRS_WATCHDOG__
static
const
char
*
const
alloc_states
[]
=
{
"IDLE"
,
"START_SETUCNT"
,
"START_PGE_REQ"
,
"INTER_PGE_REQ"
,
"START_SET&REQ"
,
"Unknown"
};
static
const
char
*
const
trans_states
[]
=
{
"IDLE"
,
"READY"
,
"WAIT_RTU_V"
,
"WAIT_SOF"
,
"SET_USECNT"
,
"WAIT_W_TRANSFER"
,
"TOO_LONG_TR"
,
"TRANSFER"
,
"TRANSFERRED"
,
"DROP"
,
"Unknown"
};
static
const
char
*
const
rcv_states
[]
=
{
"IDLE"
,
"READY"
,
"PAUSE"
,
"RCV_DATA"
,
"DROP"
,
"WAIT_F_FREE"
,
"INPUT_STUCK"
,
"Unknown"
};
static
const
char
*
const
ll_states
[]
=
{
"IDLE"
,
"RDY_PGR_&_DLAST"
,
"RDY_DLAST_ONLY"
,
"WRITE"
,
"EOF_ON_WR"
,
"SOF_ON_WR"
,
"Unknown"
};
static
const
char
*
const
prep_states
[]
=
{
"RETRY_RDY"
,
"NEWPCK_PG_RDY"
,
"NEWPCK_PG_SET_ADV"
,
"NEWPCK_PG_USED"
,
"RETRY_PREPARE"
,
"IDLE"
,
"Unknown"
,
"cycle frozen"
};
static
const
char
*
const
send_states
[]
=
{
"IDLE"
,
"DATA"
,
"FLUSH_STALL"
,
"FINISH_CYCLE"
,
"EOF"
,
"RETRY"
,
"WAIT_FREE_PCK"
,
"Unknown"
};
static
const
char
*
const
free_states
[]
=
{
"IDLE"
,
"REQ_RD_FIFO"
,
"RD_FIFO"
,
"RD_NEXT_PG_ADR"
,
"FREE_CUR_PG_ADR"
,
"F_FREE_CUR_PG_ADR"
,
"Unknown"
};
static
const
char
idles
[]
=
{
0
,
/*alloc: s_idle */
1
,
/* trans: s_ready */
1
,
/* rcv: s_ready */
1
,
/* ll: s_ready_for_pgr_and_dlast */
5
,
/* prep: s_idle */
0
,
/* send: s_idle */
0
/* free: s_idle */
};
#define FSMS_NO 7
#define ALLOC_IDX 0
#define TRANS_IDX 1
#define RCV_IDX 2
#define LL_IDX 3
#define PREP_IDX 4
#define SEND_IDX 5
#define FREE_IDX 6
struct
swc_fsms
{
int
state
[
FSMS_NO
];
char
act
[
FSMS_NO
];
};
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment