*BSD News Article 3423


Return to BSD News archive

Xref: sserve comp.unix.bsd:3467 comp.protocols.nfs:4191
Newsgroups: comp.unix.bsd,comp.protocols.nfs
Path: sserve!manuel!munnari.oz.au!uunet!uunet.ca!shark!latour!mcr
From: mcr@Sandelman.OCUnix.on.ca (Michael Richardson)
Subject: Das Blinken Lights (sp?)
Message-ID: <1992Aug10.074511.11599@Sandelman.OCUnix.on.ca>
Organization: Sandelman Software Works, Debugging Department, Ottawa, ON
References: <EICHIN.92Aug9004425@tsx-11.mit.edu> <1992Aug9.083431.5746@BitBlocks.COM>
Date: Mon, 10 Aug 1992 07:45:11 GMT
Lines: 137


  One of my favorite things about Sun equipement is the Diagnostic
LEDs on the back of the box. (I have a 3/60. I believe all the VME
based boxes have the Diag LEDs. I haven't bothered checking any Sparc
IPCs). I like it so much I have always put my 3/60 backwards so I can
see the LEDs (and it also makes access to the ports easier. It doesn't
sit on my desk)
  I think of them `Cylon' LEDs, although I guess KIT (Knight Rider)
might be more familiar to non-Battlestar Galactica watchers.

  Anyway, have a rediculous number of parallel ports on my 386bsd
system, I thought I'd hook something similar up. After bitching at
roomate for using all my solder and not buying any more, I finally
remembered to pick some up and a friend and I hooked up two last
night.
  Schematic for the curious:

   D    2 ---w---|>-\
   B    3 ---w---|>-+
   -    4 ---w---|>-+
   2    5 ---w---|>-+
   5    6 ---w---|>-+
  (M)   7 ---w---|>-+
        8 ---w---|>-+
        9 ---w---|>-+
                    |
       25 ----------/


  w - 320 ohm resistor
  |> - LED

  We hacked an appropriate outb(0x378,blah) call into isa/wd.c to output the low
byte of the disk cylinder to the parallel port and watched it the disk
seek. Pretty interesting to watch. Almost looks like an sci-fi movie
computer!
  Anyway, after sleeping a bit on where to stick the scanning motion
given that the idle task invokes hlt (did I want to pull that
instruction out? Having the process halt is actually pretty cool as
far as I'm concerned) I came across a solution...
  Just prior to the hlt instruction I call a C function, moveled.
moveled increments a counter each time it is called, and shifts the
LED each time the counter hits a value. My pondering was because I
figured that I would have to put a large processor delay in there
somewhere. The more the idle task ran, the quicker the processor delay
would happen. Since the hlt instruction will be interupted at least HZ
times a second, this provides a nice way to get a delay without
involving the processor, yet counts how often the idle task runs. I
had to play with CYLONSPEED a bit to get the timing right. 
  The LEDs are extremely usefull for diagnosing low level boot
problems since they are just two instructions. (4 if you have to save
edx somewhere in order to load the port address).

  Oh --- this is all based on 0.0 code since I wasn't able to get 0.1
to boot properly. When my ethernet driver is finished I'll be
upgrading via patches.
  Add 
i386/isa/cylonled.c	optional cylonled
  to i386/conf/files.i386
  and add:

  options	CYLONLED
  pseudo-device	cylonled

  to your kernel configuration. (If there is a better way to add code,
please tell me). We had two LED arrays running on my system, so please
change the address appropriately. I'm sure that this could be better
done via config(8).

  Anyway, here is the code:

*** /tmp/,RCSt1a11535	Mon Aug 10 03:39:42 1992
--- sys/i386/i386/locore.s	Mon Aug 10 03:35:54 1992
***************
*** 924,929 ****
--- 940,948 ----
  	call	_spl0
  	cmpl	$0,_whichqs
  	jne	sw1
+ #ifdef CYLONLED
+ 	call	_moveled
+ #endif /* CYLONLED */
  	hlt		# wait for interrupt
  	jmp	idle
  
*** /dev/null	Mon Aug 10 03:40:04 1992
--- sys/i386/isa/cylonled.c	Sun Aug  9 17:57:34 1992
***************
*** 0 ****
--- 1,42 ----
+ #include "sys/param.h"
+ #include "sys/proc.h"
+ #include "sys/user.h"
+ #include "sys/systm.h"
+ 
+ #define CYLONLEDLOC	0x378
+ #define CYLONLEDLOC1	0x3BC
+ #ifndef CYLONSPEED
+ #define CYLONSPEED	5
+ #endif
+ 
+ int cylonledspeed=CYLONSPEED;
+ 
+ void moveled()
+ {
+ 	static int  count=0;
+ 	static unsigned int ledval=1;
+ 	static int  dir=0;
+ 
+ 	
+ 	if(count++>cylonledspeed) { 
+ 		count=0;
+ 	
+ 		if(dir) {
+ 			ledval=ledval>>1;
+ 			if(ledval==0x01) {
+ 			  dir=0;
+ 			}
+ 		} else {
+ 			ledval=ledval<<1;
+ 			if(ledval==0x80) {
+ 			  dir=1;
+ 			}
+ 		}
+ /*		if(ledval==0) {
+ 		  printf("Led fucked!\n");
+ 		}*/
+ 	}
+ 	outb(CYLONLEDLOC,ledval);
+ 	outb(CYLONLEDLOC1,ledval);
+ }
+ 
-- 
   :!mcr!:            |  The postmaster never | So much mail, 
   Michael Richardson |    resolves twice.    |  so little time.
HOME: mcr@sandelman.ocunix.on.ca     Bell: (613) 237-5629
SCHOOL: 192228@physics.carleton.ca