Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / ntp / html / hints / solaris.xtra.patchfreq
1 #!/bin/ksh
2
3 #
4 # File:         patchfreq
5 # Author:       Bryan Cantrill (bmc@eng.sun.com), Solaris Performance
6 # Modified:     Sat Apr 26 04:00:59 PDT 1997
7 #
8 # This is a little script to patch a 5.5 or 5.5.1 kernel to get around
9 # the cpu_tick_freq inaccuracy.  Before running this script, one must
10 # know the true frequency of one's CPU;  this can be derived by NTP,
11 # or by observing the clock relative to the time-of-day chip over a
12 # long period of time (the TOD will pull system time when it drifts
13 # by more than two seconds).
14 #
15 # Patching a kernel can render a machine unbootable;  do not run this
16 # script unless you are prepared to accept that possibility.  It
17 # is advisable to have a backout path (e.g. net booting, an alternate
18 # boot disk, an installation CD) should your machine fail to boot.
19 #
20 # This is not a product of Sun Microsystems, and is provided "as is",
21 # without warranty of any kind expressed or implied including, but not
22 # limited to, the suitability of this script for any purpose.
23 #
24
25 if [ $# -eq 0 ]; then
26         echo "Usage:  $0 cpu_tick_freq [ alternate_kernel ]"
27         exit 1
28 fi
29
30 cpu_tick_freq=$1
31 kernel=/platform/sun4u/kernel/unix
32
33 if [ $# -eq 2 ]; then
34         kernel=$2
35 fi
36
37 if [ ! -w $kernel ]; then
38         echo "$0:  Cannot open $kernel for writing."
39         exit 1
40 fi
41
42 arch=`echo utsname+404?s | adb $kernel | cut -d: -f2`
43
44 if [ ! $arch = "sun4u" ]; then
45         echo "Patch only applies to sun4u"
46         exit 1
47 fi
48
49 rel=`echo utsname+202?s | adb $kernel | cut -d: -f2`
50
51 if [ ! $rel = "5.5" ] && [ ! $rel = "5.5.1" ]; then
52         echo "Patch only applies to 5.5 or 5.5.1..."
53         exit 1
54 fi
55
56 nop="1000000"           # nop
57 store_mask="ffffe000"   # mask out low 13 bits
58 store="da256000"        # st      %o5, [%l5 + offset]
59
60 instr=`echo setcpudelay+34?X | adb $kernel | cut -d: -f 2 | nawk '{ print $1 }'`
61
62 if [ $instr = $nop ]; then
63         echo "Instruction already patched..."
64 else
65         let masked="(16#$store_mask & 16#$instr) - 16#$store"
66         if [ $masked -ne 0 ]; then
67                 echo "Couldn't find instruction to patch;  aborting."
68                 exit 1
69         fi
70
71         if ! echo setcpudelay+34?W $nop | adb -w $kernel 1> /dev/null
72         then
73                 echo "adb returned an unexpected error;  aborting."
74         fi
75 fi
76
77 echo "Patching cpu_tick_freq to $cpu_tick_freq..."
78
79 if ! echo cpu_tick_freq?W 0t$cpu_tick_freq | adb -w $kernel 1> /dev/null; then
80         echo "adb returned an unexpected error;  aborting."
81         exit 1
82 fi
83
84 echo "$kernel successfully patched."
85 exit 0