Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.13 198 lines 6.8 kB view raw
1README for MIPS time services 2 3Jun Sun 4jsun@mvista.com or jsun@junsun.net 5 6 7ABOUT 8----- 9This file describes the new arch/mips/kernel/time.c, related files and the 10services they provide. 11 12If you are short in patience and just want to know how to use time.c for a 13new board or convert an existing board, go to the last section. 14 15 16FILES, COMPATABILITY AND CONFIGS 17--------------------------------- 18 19The old arch/mips/kernel/time.c is renamed to old-time.c. 20 21A new time.c is put there, together with include/asm-mips/time.h. 22 23Two configs variables are introduced, CONFIG_OLD_TIME_C and CONFIG_NEW_TIME_C. 24So we allow boards using 25 26 1) old time.c (CONFIG_OLD_TIME_C) 27 2) new time.c (CONFIG_NEW_TIME_C) 28 3) neither (their own private time.c) 29 30However, it is expected every board will move to the new time.c in the near 31future. 32 33 34WHAT THE NEW CODE PROVIDES? 35--------------------------- 36 37The new time code provide the following services: 38 39 a) Implements functions required by Linux common code: 40 time_init 41 do_gettimeofday 42 do_settimeofday 43 44 b) provides an abstraction of RTC and null RTC implementation as default. 45 extern unsigned long (*rtc_get_time)(void); 46 extern int (*rtc_set_time)(unsigned long); 47 48 c) a set of gettimeoffset functions for different CPUs and different 49 needs. 50 51 d) high-level and low-level timer interrupt routines where the timer 52 interrupt source may or may not be the CPU timer. The high-level 53 routine is dispatched through do_IRQ() while the low-level is 54 dispatched in assemably code (usually int-handler.S) 55 56 57WHAT THE NEW CODE REQUIRES? 58--------------------------- 59 60For the new code to work properly, each board implementation needs to supply 61the following functions or values: 62 63 a) board_time_init - a function pointer. Invoked at the beginnig of 64 time_init(). It is optional. 65 1. (optional) set up RTC routines 66 2. (optional) calibrate and set the mips_counter_frequency 67 68 b) board_timer_setup - a function pointer. Invoked at the end of time_init() 69 1. (optional) over-ride any decisions made in time_init() 70 2. set up the irqaction for timer interrupt. 71 3. enable the timer interrupt 72 73 c) (optional) board-specific RTC routines. 74 75 d) (optional) mips_counter_frequency - It must be definied if the board 76 is using CPU counter for timer interrupt or it is using fixed rate 77 gettimeoffset(). 78 79 80PORTING GUIDE 81------------- 82 83Step 1: decide how you like to implement the time services. 84 85 a) does this board have a RTC? If yes, implement the two RTC funcs. 86 87 b) does the CPU have counter/compare registers? 88 89 If the answer is no, you need a timer to provide the timer interrupt 90 at 100 HZ speed. 91 92 You cannot use the fast gettimeoffset functions, i.e., 93 94 unsigned long fixed_rate_gettimeoffset(void); 95 unsigned long calibrate_div32_gettimeoffset(void); 96 unsigned long calibrate_div64_gettimeoffset(void); 97 98 You can use null_gettimeoffset() will gives the same time resolution as 99 jiffy. Or you can implement your own gettimeoffset (probably based on 100 some ad hoc hardware on your machine.) 101 102 c) The following sub steps assume your CPU has counter register. 103 Do you plan to use the CPU counter register as the timer interrupt 104 or use an exnternal timer? 105 106 In order to use CPU counter register as the timer interrupt source, you 107 must know the counter speed (mips_counter_frequency). It is usually the 108 same as the CPU speed or an integral divisor of it. 109 110 d) decide on whether you want to use high-level or low-level timer 111 interrupt routines. The low-level one is presumably faster, but should 112 not make too mcuh difference. 113 114 115Step 2: the machine setup() function 116 117 If you supply board_time_init(), set the function poointer. 118 119 Set the function pointer board_timer_setup() (mandatory) 120 121 122Step 3: implement rtc routines, board_time_init() and board_timer_setup() 123 if needed. 124 125 board_time_init() - 126 a) (optional) set up RTC routines, 127 b) (optional) calibrate and set the mips_counter_frequency 128 (only needed if you intended to use fixed_rate_gettimeoffset 129 or use cpu counter as timer interrupt source) 130 131 board_timer_setup() - 132 a) (optional) over-write any choices made above by time_init(). 133 b) machine specific code should setup the timer irqaction. 134 c) enable the timer interrupt 135 136 137 If the RTC chip is a common chip, I suggest the routines are put under 138 arch/mips/libs. For example, for DS1386 chip, one would create 139 rtc-ds1386.c under arch/mips/lib directory. Add the following line to 140 the arch/mips/lib/Makefile: 141 142 obj-$(CONFIG_DDB5476) += rtc-ds1386.o 143 144Step 4: if you are using low-level timer interrupt, change your interrupt 145 dispathcing code to check for timer interrupt and jump to 146 ll_timer_interrupt() directly if one is detected. 147 148Step 5: Modify arch/mips/config.in and add CONFIG_NEW_TIME_C to your machine. 149 Modify the appropriate defconfig if applicable. 150 151Final notes: 152 153For some tricky cases, you may need to add your own wrapper functions 154for some of the functions in time.c. 155 156For example, you may define your own timer interrupt routine, which does 157some of its own processing and then calls timer_interrupt(). 158 159You can also over-ride any of the built-in functions (gettimeoffset, 160RTC routines and/or timer interrupt routine). 161 162 163PORTING NOTES FOR SMP 164---------------------- 165 166If you have a SMP box, things are slightly more complicated. 167 168The time service running every jiffy is logically divided into two parts: 169 170 1) the one for the whole system (defined in timer_interrupt()) 171 2) the one that should run for each CPU (defined in local_timer_interrupt()) 172 173You need to decide on your timer interrupt sources. 174 175 case 1) - whole system has only one timer interrupt delivered to one CPU 176 177 In this case, you set up timer interrupt as in UP systems. In addtion, 178 you need to set emulate_local_timer_interrupt to 1 so that other 179 CPUs get to call local_timer_interrupt(). 180 181 THIS IS CURRENTLY NOT IMPLEMNETED. However, it is rather easy to write 182 one should such a need arise. You simply make a IPI call. 183 184 case 2) - each CPU has a separate timer interrupt 185 186 In this case, you need to set up IRQ such that each of them will 187 call local_timer_interrupt(). In addition, you need to arrange 188 one and only one of them to call timer_interrupt(). 189 190 You can also do the low-level version of those interrupt routines, 191 following similar dispatching routes described above. 192 193Note about do_gettimeoffset(): 194 195 It is very likely the CPU counter registers are not sync'ed up in a SMP box. 196 Therefore you cannot really use the many of the existing routines that 197 are based on CPU counter. You should wirte your own gettimeoffset rouinte 198 if you want intra-jiffy resolution.