ESB Watchdog Timer 
Linux Driver Release Notes

Overview:
=========
This document describes Linux software support for the Watchdog Timer
device integrated into the Intel Enterprise Southbridge (ESB).

Bill of Materials
=================
/esbwdt
   esbwdt-doc.txt	this file
	/driver			
	 esbwdt.c	/dev/watchdog driver source
	 esbwdt.h	header file
	 Makefile	make file
	/demoapp
	 esbwdt-demo.c  demo application

Scope:
=====
This documentation and associated software is designed for use on 
the Intel ESB 'Petoski' Customer Reference Board with a WDT-enabled 
system bios.

It has been validated using following Linux Distribution/Kernel Versions:

Distribution		Kernel
============		=============================
Redhat 8.0		2.4.20-r8bld from the 
			esb-rh8-beta_1_xx.tgz driver pkg

Redhat Advanced Server	2.4.9-e.24esb from the
v2.1 			esb-rhas-beta_1_xx.tgz driver pkg


Redhat Advanced Server	2.4.21-20.ELesb from the
v3.3* 			esb-rhas30-gold_1_xx.tgz driver pkg


** using following iso's from RedHat:
rhel-3-U3-i386-as-disc1.iso
rhel-3-U3-i386-as-disc2.iso
rhel-3-U3-i386-as-disc3.iso
rhel-3-U3-i386-as-disc4.iso

ESB WDT Operating Modes:
========================

The ESB WDT supports 2 operating modes:

1) Watchdog Timer Mode (Mode = WDT)
In this mode, the ESB WDT behaves like a 2 Stage Watchdog timer.
PRELOAD1 sets timeout of the 1st stage. PRELOAD2 sets timeout of
the 2nd stage. When started in the WDT MODE, the 35bit downcounter
starts counting down from the PRELOAD1 value.

Issuing a periodic 'RELOAD' sequence to the WDT while it's counting down
during stage 1 causes the hardware to reloads it's 35bit downcounter and 
prevents it from reaching zero. In the absence of these periodic 'RELOAD' 
sequences,the WDT will eventually count down to zero, in which case, the
1st stage timeout will cause the WDT to generate an interrupt, reload the
35bit downcounter with PRELOAD2 value and start the stage2 countdown.

Issuing a 'RELOAD' sequence to the WDT while it's in a stage2 countdown,
resets it back to a stage1 (ie, it reloads the PRELOAD1 value and restarts 
the stage1 countdown). If the stage2 countdown is allowed to timeout, the 
WDT will set the WDT_TIMEOUT status bit (which is maintained in the RTC CMOS
power well so it's state is not lost thru a system power cycle) and assert 
its output pin, which if the board is jumpered/wired to do so, will cause a
system reset. 

2) FREE running mode (Mode = FREE)
In this mode, the PRELOAD1 value is meaningless, the ESB WDT starts counting
down using the PRELAOD2 value. 'RELOAD' sequences are also meaningless in this 
mode (ie a 'RELOAD' seq will NOT reload the 35bit downcounter in this mode). 
Upon reaching zero in this mode, the ESB WDT toggles it's output pin, reloads 
the 35bit downcounter with the PRELOAD2 value and repeats the countdown. Each 
time it hit's zero, the output pin toggles. Note, that, unlike the 'WDT' mode, 
in the 'FREE' mode, the ESB WDT does NOT generate any interrupts when the 
35bit downcounter hit's zero.

See ESB datasheet for more details.

Linux Watchdog Device Overview and APIs:
=========================================
See following kernel documentation files supplied with stock 2.4.21 kernels
from www.kernel.org:

    Documentation/watchdog.txt
    Documentation/watchdog-api.txt

The /dev/watchdog device implemented by the esbwdt driver supports the defacto 
behavior described in these documents:

- opening /dev/watchdog device starts the hardware in wdt mode using
  default timeouts of 60seconds for PRELOAD1 and PRELOAD2

- writing any char to the /dev/watchdog device will issue reload to hw

- closing /dev/watchdog device without writing the magic 'V' will 
  leave it running, if 'nowayout' module parameter is set = 0 (default)

- if the driver is loaded with 'nowayout' = 1, it is not possible to
  stop the /dev/watchdog device once it is opened.
  >> not tested yet <<<

ESBWDT Driver IOCTL List:
==========================

The esbwdt does not implement all the defacto api's described in the
Linux watchdog-api.txt document, only the ones needed to adhere to the
behavior's described above. This allows the driver to be used with any
existing WDT Dameon applications.

Defacto API's for /dev/watchdog device from <linux/watchdog.h>:

WDIOC_GETSTATUS		reads WDT_TIMEOUT bit
WDIOC_KEEPALIVE		issues 'RELOAD' seq
WDIOC_SETTIMEOUT	writes PRELOAD1
WDIOC_GETTIMEOUT	reads  PRELOAD2


The esbwdt driver also implements a number of ioctls that allow user 
applications to control & configure the ESB WDT hardware. See the source 
code for the driver and the demo application for more details. The demo 
applicaiton provides details of which ioctl api's are being used to 
perform various control/config functions.

Custome API's for ESB WDT based /dev/watchdog device from <esbwdt.h>:

WDIOC_CLRSTATUS	        clears WDT_TIMEOUT status bit

WDIOC_DISABLE		issues 'RELOAD' seq and Stops WDT (WDT_ENABLE=0)

WDIOC_ENABLE		Starts WDT (WDT_ENABLE bit = 1)

WDIOC_GETWDTENABLE	reads state of WDT_ENABLE bit
			0= Stopped 1= Running

WDIOC_SETMODE		sets state of WDT_MODE bit based based on input arg
			0 = 'WDT MODE' 1= 'FREE MODE'
WDIOC_GETMODE		reads state of WDT_MODE bit into output arg

WDIOC_SETOPIN		sets WDT_OUTPUT bit based on input arg
			(1 gates wdt output pin from being driven)
			(0 enables wdt output pin to be driven)
WDIOC_GETOPIN		reads state of WDT_OUTPUT bit into output arg

WDIOC_GETIRQSTAT	reads state of WDT_IRQSTAT bit into output arg
WDIOC_CLRIRQSTAT	clears WDT_IRQSTAT bit

WDIOC_SETSCALE		sets WDT_PRE_SEL bit based on input arg
			0 = 1Khz   1 = 1Mhz
WDIOC_GETSCALE		reads WDT_PRE_SEL bit into output arg

WDIOC_SETTIMEOUT	sets PRELOAD1 value based on input arg
WDIOC_GETTIMEOUT	reads PRELOAD1 value into output arg
WDIOC_SETTIMEOUT2	sets PRELOAD2 value based on input arg
WDIOC_GETTIMEOUT2	reads PRELOAD2 value into output arg

			35bit downcounter clocks at fixed 33Mhz
			SCALE = 0 (1khz)
			> 20bit preload values endup in bits 34:15 of the
			  35bit downcounter. All non-specd bits are set=0

			  PreloadX value     Resulting Timeout 
			  Max: 0xFFFFF	     ~17 minutes
			  Min: 0x00001       ~1 milliSecond (.983 ms)

			SCALE = 1 (1Mhz)
			> 20bit preload values endup in bits 24:5 of the
			  35bit downcounter. All non-specd bits are set=0

			  PreloadX value     Resulting Timeout
			  Max: 0xFFFFF	     ~16 seconds
			  Min: 0x00001	     ~1 uSec (.960 uSec)
			
WDIOC_NOTIFY		Driver blocks calling process on kernel waitqueue
			The calling process remains blocked until driver's
			isr gets an IRQ, at which point, the isr unblocks
			the calling process. For use by user apps that 
			want to monitor/detect 1st stage wdt timeouts when
			running in '2 stage wdt mode'.

WDIOC_CLRNOTIFY		Forces drivers isr to unblock a process waiting
			for 1st stage timeout irq from the wdt device.

WDIOC_GETDC		reads current status of upper 20bits of 35bit
			downcounter into output arg

WDIOC_GETIRQVEC		returns what IRQ vector the driver is using
			(as specd by 'wdt-irq=9 or 34' module parameter
			 at insmod time)

See esbwdt-demo.c for examples of how to write user space apps that can
interface to the ESB WDT using these ioctls.
	

ESB 'Petoski' CRB WDT Jumpers:
==============================

     J6  J25  J24

WDT   o   o   o
SET   o   o   o


J6  open          
J25 closed - WDT_TOUT pin drives LED only
J24 open

J6  open
J25 open
J24 closed - WDT_TOUT pin drives LED and System RESET

It is highly recommended that you use the J25 jumper setting until you 
have fully validated your WDT Dameon/USER application. WDT initiated system
resets are not 'clean shutdowns' and as such they will eventually 
corrupt most operating systems (including Linux) because OS filesystem/kernel 
caches do not not get properly flushed on hard resets of this type. 

This is a classic example of where a 2 Stage WDT can provide value. With the
ESB WDT running in 2 Stage 'WDT' mode, given the PRELOAD2 timeout is programmed
to be long enough, upon detecting a 1st Stage timeout, the WDT Dameon should 
try to restart the critical application(s) that stopped pinging. If the apps
are successfully restarted, it can issue a reload to the WDT to prevent a
stage2 timeout and the subsequent system reset. If not successful, it should 
try and perform a clean restart of the system ('shutdown -r now' or 'reboot').
If that isn't successful either, the last resort should be the system reset 
via 2nd stage WDT tiemout.

ESB Petoski CRB BIOS Config:
============================
If kernel is configured to use IOAPICs (which is the default setting for
the 2.4.21-20.ELesb kernel supplied by this driver package), you must be 
using a system bios that supplies a Interrupt Assignment entry for the
ESB WDT device in the MPS v1.4 Tables.

Note to BIOS Writers:
=====================
The ESB WDT is missing PCI INTR/INTL registers, you have to provide a
bogus entry for this device in the MPS v1.4 tables. See ESB BIOS 
Specification for more details.

Note to Driver Writers:
=======================
Due the missing PCI INTR/INTL registers in the ESB WDT pci configuration
headers, you have to hardcode IRQ vector if you are implementing ISR in 
your driver code. The standard pci device object created by kernel pci 
configuration api's will report the ESB WDT PCI Device 29:Function 4 as
not being interrupt capable. 

In the 8259 mode, the ESB WDT signals on IRQ9. In IOAPIC mode, the ESB WDT 
signals on IRQ34. 

As previously state, ESB WDT only generates interrupts when running in the 
'WDT' mode ...actually it only generates A SINGLE interrupt when the stage1 
times out...no interrupts are generated on the 2nd stage2 timeout (Under the 
assumption the system will reset if stage2 ever times out)


Loading/Removing esbwdt driver:
==============================

Load with default module parameter settings:

	insmod esbwdt

Load with optional module parameters:

	insmod esbwdt modparm1=xxxx modparam2=yyyyy modparm3=yyyyy

parameters	range/setting		default	comments
==========	======================	======  ============================
wdt_margin1	1 to 1048575		60000	dflt preload1 is ~60sec
wdt_margin2	1 to 1048575		60000	dflt preload2 is ~60sec
wdt_mode	0 (WDT) or 1 (FREE)	0	dflt mode is WDT
wdt_scale	0 (1Khz)or 1 (1Mhz)	0	dflt scale is 1Khz
wdt_irq		9 (8259)or 34 (IOAPIC)  34	dflt irq is 34
nowayout	0 or 1			0	write 'V' + close, stops wdt

To Remove esbwdt driver:

	rmmod esbwdt


Loading the esbwdt driver with insmod configures the ESB WDT hardware 
with either default configs or module parameter supplied configs but does 
not start the wdt down counter

WDT Dameon/User App opening /dev/watchdog device starts the wdt downcounter
using hardware configs setup by insmod

Writing any char to the /dev/watchdog device will reload the wdt if running
in mode=WDT. 

If 'nowayout=0', user apps must write a 'V' to the /dev/watchdog device
prior to closing it if they want to stop the wdt downcounter, otherwise,
the wdt downcounter remains running even after it's been closed.

Removing the esbwdt driver with rmmod will stop the wdt timer.


Running the esbdemo app:
========================

Note: 
Make sure the esbwdt driver BEFORE attempting to use the demo app.

Starting esbdemo app:		./esbdemo

Exiting esbdemo app:		press x or ESC key


EXAMPLE SESSION:
================

insmod esbwdt

./esbdemo

ESB Watchdog Timer Demo App
F1 MODE:        0       0=WDT 1=FREE
F2 PRESCALER:   0       0=1Khz 1=1Mhz
F3 PRELOAD1:    60000   Valid range= 1 to 1048575
F4 PRELOAD2:    60000   Valid range= 1 to 1048575
F5 OUTPIN:      0       0=En 1=Dis
F6 WDT_ENABLE:  1       0=STOP 1=RUN
F7 RELOAD               Ping WDT
F8 WDT_TIMEOUT: 0       0=no_TO 1=TO (F8 clrs)
F9 CloseState:  0       0=STOP 1=RUN
Connected to running hw in wdt mode... stage unknown: XXXXXX

Per defacto linux standards, opening /dev/watchdog device
starts the watchdog timer with default countdown values of 1min


When RUNNING, only following commands are available:
============

F6 WDT_ENABLE		< press F6 to STOP
F7 RELOAD		< press F7 to issue RELOAD

Note: Issuing RELOAD by pressing F7 will sync the demo app
      to the hardware because in the 'WDT Mode' a reload 
      restarts the 2 stage WDT timer from Stage1.

When STOPPED, following commands are available: ----------+
===============================================           |
                                                          |
ESB Watchdog Timer Demo App
F1 MODE:        0       0=WDT 1=FREE			< F1 toggles MODE
F2 PRESCALER:   0       0=1Khz 1=1Mhz			< F2 toggles PRESCALER
F3 PRELOAD1:    60000   Valid range= 1 to 1048575	< F3 inputs PRELOAD1
F4 PRELOAD2:    60000   Valid range= 1 to 1048575	< F4 inputs PRELOAD2
F5 OUTPIN:      0       0=En 1=Dis			< F5 toggles OPIN gate
F6 WDT_ENABLE:  0       0=STOP 1=RUN			< F6 STARTS
F7 RELOAD               Ping WDT
F8 WDT_TIMEOUT: 0       0=no_TO 1=TO (F8 clrs)		< F8 Clr WDT_TIMEOUT
F9 CloseState:  0       0=STOP 1=RUN			< F8 set close state
WDT is STOPPED



WDIOC_DISABLE ioctl OK					< Status line shows
							  IOCTL info


Press F3, set PRELOAD1 = 5000   (~ 5 Sec)
Press F4, set PRELOAD2 = 5000 


ESB Watchdog Timer Demo App
F1 MODE:        0       0=WDT 1=FREE
F2 PRESCALER:   0       0=1Khz 1=1Mhz
F3 PRELOAD1:    5000    Valid range= 1 to 1048575
F4 PRELOAD2:    5000    Valid range= 1 to 1048575
F5 OUTPIN:      0       0=En 1=Dis
F6 WDT_ENABLE:  0       0=STOP 1=RUN
F7 RELOAD               Ping WDT
F8 WDT_TIMEOUT: 0       0=no_TO 1=TO (F8 clrs)
F9 CloseState:  0       0=STOP 1=RUN
WDT is STOPPED


WDIOC_SETTIMEOUT2 ioctl OK


Press F6 to start the wdt
	a> 1st Stage Countdown starts
	b> Callback thread gets installed to monitor IRQ
	c> 1st Stage Timeout IRQ happens

	Pressing F7 during <a>, restarts it from PRELOAD1


ESB Watchdog Timer Demo App
F1 MODE:        0       0=WDT 1=FREE
F2 PRESCALER:   0       0=1Khz 1=1Mhz
F3 PRELOAD1:    5000    Valid range= 1 to 1048575
F4 PRELOAD2:    5000    Valid range= 1 to 1048575
F5 OUTPIN:      0       0=En 1=Dis
F6 WDT_ENABLE:  1       0=STOP 1=RUN
F7 RELOAD               Ping WDT
F8 WDT_TIMEOUT: 0       0=no_TO 1=TO (F8 clrs)
F9 CloseState:  0       0=STOP 1=RUN
WDT MODE Stage 1 countdown progress: XXXXX


Thread Started to Monitor 1st Stage Timeout
WDIOC_NOTIFY ioctl blocks till ISR unblocks it

1st Stage Timeout IRQ Detected

	d> Second Stage countdown starts 
	
	Pressing F7 during stage 2 countdown restarts
	the process from stage 1


	e> Letting Stage 2 countdown occur
	   results in WDT_TIMEOUT bit getting set
	   & WDT_TOUT pin getting asserted

	   > if your board is jumpered to have wdt_tout pin
	   drive system reset, this will result in a system
	   reset.
	   > if your board is jumpered to just drive the 
	   wdt-tout led, than only the led will come on.


ESB Watchdog Timer Demo App
F1 MODE:        0       0=WDT 1=FREE
F2 PRESCALER:   0       0=1Khz 1=1Mhz
F3 PRELOAD1:    5000   Valid range= 1 to 1048575
F4 PRELOAD2:    5000   Valid range= 1 to 1048575
F5 OUTPIN:      0       0=En 1=Dis
F6 WDT_ENABLE:  1       0=STOP 1=RUN
F7 RELOAD               Ping WDT
F8 WDT_TIMEOUT: 1       0=no_TO 1=TO (F8 clrs)
F9 CloseState:  0       0=STOP 1=RUN
WDT MODE Stage 2 countdown progress:  0

Thread Started to Monitor 1st Stage Timeout
WDIOC_NOTIFY ioctl blocks till ISR unblocks it

1st Stage Timeout IRQ Detected

	f> Press F6 to STOP
	g> Press F8 to clear WDT_TIMEOUT status bit

	  depending on your jumper settings, if you unmask
	  the wdt outpin pin (F5) in this state, your system
	  will reset. 

	NOTE: EVEN THOUGH F8 CLEARS THE WDT_TIMEOUT bit,
	the WDT_TOUT pin register will remain asserted
	until the system is reset or you do the following
	software procedure:

FREE MODE DEMO
==============

	> set Mode = FREE
	> start the WDT
	> in FREE mode,each PRELOAD2 timeouts toggles the output pin
	  
	    > to get back to initial conditions for WDT Mode, 
	    wait for the output pin to toggle off (LED off) and then
	    press F6 to stop the WDT.


ESB Watchdog Timer Demo App
F1 MODE:        1       0=WDT 1=FREE
F2 PRESCALER:   0       0=1Khz 1=1Mhz
F3 PRELOAD1:    10000   Valid range= 1 to 1048575
F4 PRELOAD2:    2000    Valid range= 1 to 1048575
F5 OUTPIN:      0       0=En 1=Dis
F6 WDT_ENABLE:  1       0=STOP 1=RUN
F7 RELOAD               Ping WDT
F8 WDT_TIMEOUT: 1       0=no_TO 1=TO (F8 clrs)
F9 CloseState:  0       0=STOP 1=RUN
FREE MODE Preload2 countdown in progress:  XXXX

WDIOC_ENABLE ioctl OK...FREE mode...no irqs...no cb thread installed

F7
WDIOC_KEEPALIVE ioctl OK ...reloads only if mode=wdt

Press F6 to STOP the WDT Device

Press x to exist the demo app

rmmod esbwdt 	to remove the esbwdt driver

