Intel(R) 3100 Chipset Watch Dog Timer

Linux Driver Release Notes

Overview:
=========
This document describes Linux software support for the Watchdog Timer
device integrated into the Intel integrated MCH and ICH.

Bill of Materials
=================
/wdt
   ReleaseNotes.txt       this file
   /driver
      iwdt.c       /dev/watchdog driver source
      iwdt.h       header file
      Makefile         make file
   /demoapp
      iwdtdemo.c   demo application

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

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

Distribution                            Kernel
====================================    ======
RedHat EL 4.0 Advanced server Update1   2.6.9 
Redhat EL 4.0 Work Station Update1      2.6.9

WDT Operating Modes:
====================
The WDT supports 2 operating modes:

1) Watchdog Timer Mode (Mode = WDT)
In this mode, the 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, Intel 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, Intel 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 WDT does NOT generate any interrupts when the 
35bit downcounter hit's zero.

See Intel Whitmore Lake 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/watchdog.txt
    Documentation/watchdog/watchdog-api.txt

The /dev/watchdog device implemented by the wdt 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 <<<

Intel WDT  Driver IOCTL List:
=============================

The wdt 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 wdt driver also implements a number of ioctls that allow user 
applications to control & configure the Intel 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.

Custom API's for Intel WDT based /dev/watchdog device from <iwdt.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=10' module parameter
                 at insmod time)

WDIOC_SET_INT_TYPE      set interrupt type for WDT. This can also be set at 
                module load time using 'wdt_intr_type'.
                    0 - SERIRQ (default)
                    1 - NMI
                    2 - SMI

WDIOC_GET_INT_TYPE      Returns type of interrupt it will generate when
                        timeout occurs.

See iwdtdemo.c for examples of how to write user space apps that can
interface to the Intel WDT using these ioctls.


Intel 'Mt. Arvon' CRB WDT Jumpers:
==================================

Connect J3C1 (WDT RST)
    open   - WDT_TOUT pin drives LED only no system RESET.
    closed - WDT_TOUT pin driver system RESET after 2nd timeout

If J3C1 is open and 2nd state timeout occurs, you will see illuminated LED 
at CR4D1. There is no system reset.

If J3C1 is closed and 2nd state timeout occurs, system will reset.

It is highly recommended that you use the J3C1 jumper open 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
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.

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

As previously stated, Intel 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)

Building the wdt driver:
========================
    cd wdt      <- cd into the wdt which has the sources
    make        <- issue make to build the driver

Loading/Removing wdt driver:
============================

Load with default module parameter settings:

    insmod iwdt.ko

Load with optional module parameters:

    insmod wdt modparm1=xxxx modparam2=yyyyy modparm3=yyyyy

Parameters      Range/Setting           Default Comments
==========      ======================  ======  ============================
wdt_margin1     1 to 1048575            60000   Default preload1 is ~60sec
wdt_margin2     1 to 1048575            60000   Default preload2 is ~60sec
wdt_mode        0 (WDT) or 1 (FREE)     0       Default mode is WDT
wdt_scale       0 (1Khz)or 1 (1Mhz)     0       Default scale is 1Khz
nowayout        0 or 1                  0       Write 'V' + close, stops wdt
wdt_intr_type   0, 1, or 2              0       Default type is SERIRQ 
wdt_index_port  0x4E or 0x20E           0x4E    WDT index port address
wdt_data_port   0x4F or 0x20F           0x4F    WDT data port address

To Remove wdt driver:

    rmmod iwdt

Loading the wdt driver with insmod configures the 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 wdt driver with rmmod will stop the wdt timer.


Running the demo app:
========================

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

Starting demo app:      ./iwdtdemo

Exiting demo app:       press x or ESC key


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

insmod iwdt.ko

./iwdtdemo

Intel 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: ----------+
===============================================           |
                                                          |
Intel 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 


Intel 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


Intel 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.


Intel 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.


Intel 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 iwdt to remove the wdt driver
