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