Fixed broken pte bit definitions. I fixed this long ago in pte.h, but
[unix-history] / contrib / xntpd / ppsclock / README
CommitLineData
09169146
GW
1# README,v 3.1 1993/07/06 01:09:46 jbj Exp
2
3PPSCLOCK 1.3 BETA Release
4
5Please send bugs and comments to ppsclock@ee.lbl.gov.
6
7This is SunOS 4 tty STREAMS module that can be used to interface
8the one-pulse-per-second output of an accurate external clock
9(e.g., a GPS receiver) to NTP. This module records the value of
10the Unix clock each time the 1pps pulse happens. The recorded
11value can then be read by an application using a CIOGETEV ioctl.
12
13We have been running this module with xntp3, SunOS 4.1.2 and a
14Magnavox MX4200 GPS receiver (a very nice, relatively inexpensive
15GPS box for use with NTP) and have been happy with the results:
16The time from when the GPS sends the 1pps pulse to when this code
17grabs the Unix time is an almost constant 15us on a SparcStation 1+
18and 9us on a SparcStation 2 (there is conditionally compiled code
19in the driver that may help if you want to measure this interval
20yourself -- see below).
21
22Since the GPS is typically connected via an RS-232 serial port
23& since the SparcStation has too few serial ports, this module
24gets the 1pps signal via the same port used to get the GPS data.
25We do this by connecting the GPS 1pps output to `Carrier Detect'
26(RS-232 pin 8) on serial cable between the GPS & the Sparc.
27Since `Carrier Detect' transitions cause a high priority zs
28`service' interrupt on the Sparc (which is separate from the zs
29`data' interrupt used to collect ascii data from the GPS), this
30is a cheap way to turn the 1pps pulse into a Sparc interrupt.
31However, since `Carrier Detect' now has a non-standard meaning on
32the clock serial line, *YOU MUST SET "SOFT CARRIER" ON THE CLOCK
33SERIAL PORT* (i.e., the port you push this streams module onto).
34But note that this module changes the meaning of the `Carrier
35Detect' interrupt *only* on the port(s) it's pushed on; other
36serial ports continue to work as they always have & the special
37interpretation of `Carrier Detect' will go away whenever this
38steams module is popped (e.g., if xntpd exits).
39
40In order to use the 1pps pulse to correct both the Unix clock
41offset and frequency, the time between when the external clock
42signals 1pps and when this module records the Unix clock should
43be as small as possible and should be repeatable. The totally
44braindead AT&T STREAMS code makes it very difficult to achieve
45these objectives: The allocb/wput overhead adds about 700us of
46latency on a SS-1+ and the worthless stream 'scheduler' combined
47with doing everything at a relatively low interrupt priority
48adds about +-400us of jitter. So, to get a high quality time
49stamp, this module uses STREAMS *only* to get the ioctl request.
50It gets the 1pps signal by avoiding STREAMS code entirely and
51inserting itself directly into the hardware interrupt service path
52for the 1pps pulse. It does this by being *very* chummy with
53Sun's `zs' serial driver -- it basically steals the modem control
54interrupt from the zs. So *THIS IS NOT A GENERIC STREAMS MODULE*.
55It is designed to work with Sun's zs driver under SunOS 4.
56Expect it to break under Solaris-2. Expect it to not run on
57anything but a Sun.
58
59Also note that for our GPS clock, `1 second' seems to occur at the
60leading edge of the pulse so that's when we grab the timestamp. If
61your clock indicates 1pps on the trailing edge you should change the line:
62 if ((s0 & ZSRR0_CD) != 0) {
63in ppsclock_intr to:
64 if ((s0 & ZSRR0_CD) == 0) {
65to grab the time stamp on the trailing edge of the pulse.
66
67One final note about running this code on a Sun Sparcstation 1; we have
68found that you need revision 1.3 or higher proms with the Sun 4/60;
69this is because 1.2 and earlier roms listen to BOTH the A and B serial
70ports while selftesting; if you have something like a GPS receiver
71talking once a second at 4800 baud to a serial port, even if it's not
72the console serial port, the system will see a "break" and abort
73booting up. This makes it impossible to automatically reboot after a
74crash.
75
76
77Measuring Performance
78---------------------
79We have frequently found the need for some non-invasive means
80to measure internal system performance numbers such as interrupt
81latencies. The following trick works pretty well: The SparcStation
82has a front panel LED that the system turns on at boot time then
83never changes. There is a register (the 'auxio' register) that the
84kernel can write to change the state of this LED & it costs almost
85exactly 1us to turn the LED off then on again. So, for example,
86you can measure the interrupt latency to when we grab unix time
87stamp by attaching a scope probe to the LED (it's easiest to stick
88the probe into the LED's connector on the motherboard) then trigger
89the scope off the appropriate edge of the 1pps pulse from the GPS.
90If you want to measure the amount of time some system routine
91takes, you can turn the LED off before calling the routine and
92on afterwards so the pulse width on the scope is a direct measure
93of the routine's execution time. If you want to play with this,
94there's code in ppsclock.c (conditional on the define PPSCLOCKLED)
95that will toggle the LED in the hardware interrupt handler for
96the 1pps intr. The time from whichever edge of the 1pps pulse
97you chose to stamp to when the LED goes off is the interrupt
98latency & the LED off time is a measure of the cost to call Sun's
99routine uniqtime (which reads the Unix time to 1us accuracy).
100
101By the way, if you try this & think the cost of calling Sun's
102`uniqtime' is appalling (42-85us/call -- we thought this was
103appalling) this distribution includes a replacement for it,
104microtime.s, that runs 10 times faster than Sun's code (~3us/call)
105& gives you a more accurate time. (If you install this, it will
106improve anything that gets high-res unix kernel time, including
107the gettimeofday system call that xntp uses).
108
109
110
111INSTALLATION
112------------
113These are some (sketchy) notes on installation of the SunOS 4 pps clock
114streams module.
115
116This directory contains:
117
118 README - this file
119 RELEASE - version of this releasethis
120 CHANGES - description of differences between releases
121 magnavox.ps - PostScript schematic (Magnavox rs422/rs232 converter)
122 b-and-b.ps - PostScript schematic (B&B rs422/rs232 converter)
123 Makefile - compilation rules
124 ppstest - ppsclock test program (works with Magnavox
125 MX4200 GPS -- you can probably use this as
126 sample code illustrating the use of this
127 streams module if you have some other kind
128 of clock).
129 sys - SunOS 4 kernel modules
130 sys/genassym - genassym program for object-only (non-source) sites
131
132KERNEL CONFIGURATION
133--------------------
134
135 (1) Copy sys/sundev/ppsclock.c to /sys/sundev.
136
137 (2) Copy sys/sys/ppsclock.h to /sys/sys (and /usr/include/sys if it
138 is separate directory).
139
140 (3) If you want to use the fast microtime module, copy
141 sys/sun4c/microtime.s to /sys/sun4c.
142
143 (4) Use sys/sun/str_conf.c.patch to patch /sys/sun/str_conf.c.
144 Alternately, manually install the following lines in the
145 appropriate places:
146
147 #include "zs.h"
148 [...]
149 #if NZS > 0
150 #include "sys/ppsclock.h"
151 extern struct streamtab ppsclockinfo;
152 #endif
153 [...]
154 #if NZS > 0
155 { PPSCLOCKSTR, &ppsclockinfo },
156 #endif
157
158 (5) Use sun4c/conf/files.patch to patch /sys/sun4c/conf/files.
159 Alternately, manually install the following line in the
160 appropriate place:
161
162 sundev/ppsclock.c optional zs device-driver
163
164 In addition, if you want to use the fast microtime module,
165 use sun4c/conf/files.microtime.patch to patch
166 /sys/sun4c/conf/files. Alternately, manually install the
167 following line in the appropriate place:
168
169 sun4c/microtime.s standard
170
171 If you are using SunOS 4.1.3 and wish to support the sun4m
172 architecture, apply the corresponding patches from the sun4m
173 tree.
174
175 (6) If you want to use the fast microtime module, and have full
176 SunOS 4 source, use /sys/os/kern_clock.c.patch to patch
177 /sys/os/kern_clock.c. Alternately, edit /sys/os/kern_clock.c
178 and bracket the code for uniqtime() with the following two
179 lines:
180
181 #if !defined(sun4c) && !defined(sun4m)
182 #endif
183
184 If you DO NOT have full SunOS 4 source but still want to use
185 the fast microtime, change the symbol table entry in for
186 _uniqtime to _Uniqtime as follows:
187
188 hell 1 % cd /sys/sun4c/OBJ # or /sys/sun4m
189 hell 2 % mv kern_clock.o kern_clock.o.virgin
190 hell 2 % cp kern_clock.o.virgin kern_clock.o
191 hell 3 % chmod +w kern_clock.o
192 hell 5 % strings -o -a kern_clock.o | grep -w _uniqtime
193 7892 _uniqtime
194 hell 6 % adb -w kern_clock.o
195 ?m 0 0xffffffff 0
196 0t7892?s
197 _dk_ndrive+0x12cc: _uniqtime
198 .?x
199 _dk_ndrive+0x12cc: 5f75
200 .?w5f55
201 _dk_ndrive+0x12cc: 0x5f75 = 0x5f55
202 .?s
203 _dk_ndrive+0x12cc: _Uniqtime
204 ^D
205
206 (7) If you DO NOT have full SunOS 4 source, you are missing the
207 source to genassym. Copy the "mini" genassym source from
208 genassym/genassym.c to /sys/sun4c (and into /sys/sun4m if you
209 have SunOS 4.1.3 and wish to support the sun4m architecture).
210
211 Next, use sun4c/conf/Makefile.src.patch to patch
212 /sys/sun4c/conf/Makefile.src (and possibly
213 /sys/sun4m/conf/Makefile.src).
214
215 Alternately, manually install the following rules in the
216 prototype Makefile(s).
217
218 assym.s: ${MACHINE}/genassym.c
219 ${CC} -E ${CPPOPTS} ${MACHINE}/genassym.c > ./a.out.c
220 cc ${COPTS} ./a.out.c
221 ./a.out >assym.s
222 rm -f ./a.out ./a.out.c
223
224 (8) Config, build, and boot the new kernel.
225
226 (9) If you have an MX4200, build the test program in the ppstest
227 directory and run it. It waits for a message at 4800
228 baud and then prints both the message and the time stamp
229 of the last "carrier detect" transition.