dv-mn103tim.c revision 1.1 1 1.1 christos /* This file is part of the program GDB, the GNU debugger.
2 1.1 christos
3 1.1 christos Copyright (C) 1998-2014 Free Software Foundation, Inc.
4 1.1 christos Contributed by Cygnus Solutions.
5 1.1 christos
6 1.1 christos This program is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3 of the License, or
9 1.1 christos (at your option) any later version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>.
18 1.1 christos
19 1.1 christos */
20 1.1 christos
21 1.1 christos #include "sim-main.h"
22 1.1 christos #include "hw-main.h"
23 1.1 christos #include "sim-assert.h"
24 1.1 christos
25 1.1 christos /* DEVICE
26 1.1 christos
27 1.1 christos
28 1.1 christos mn103tim - mn103002 timers (8 and 16 bit)
29 1.1 christos
30 1.1 christos
31 1.1 christos DESCRIPTION
32 1.1 christos
33 1.1 christos Implements the mn103002 8 and 16 bit timers as described in the mn103002 user guide.
34 1.1 christos
35 1.1 christos
36 1.1 christos PROPERTIES
37 1.1 christos
38 1.1 christos reg = <8bit-timers-addr> <8bit-timers-size> <16bit-timers-addr> <16bit-timers-size>
39 1.1 christos
40 1.1 christos
41 1.1 christos BUGS
42 1.1 christos
43 1.1 christos */
44 1.1 christos
45 1.1 christos
46 1.1 christos /* The timers' register address blocks */
47 1.1 christos
48 1.1 christos struct mn103tim_block {
49 1.1 christos unsigned_word base;
50 1.1 christos unsigned_word bound;
51 1.1 christos };
52 1.1 christos
53 1.1 christos enum { TIMER8_BLOCK, TIMER16_BLOCK, NR_TIMER_BLOCKS };
54 1.1 christos
55 1.1 christos enum timer_register_types {
56 1.1 christos FIRST_MODE_REG = 0,
57 1.1 christos TM0MD = FIRST_MODE_REG,
58 1.1 christos TM1MD,
59 1.1 christos TM2MD,
60 1.1 christos TM3MD,
61 1.1 christos TM4MD,
62 1.1 christos TM5MD,
63 1.1 christos TM6MD,
64 1.1 christos LAST_MODE_REG = TM6MD,
65 1.1 christos FIRST_BASE_REG,
66 1.1 christos TM0BR = FIRST_BASE_REG,
67 1.1 christos TM1BR,
68 1.1 christos TM2BR,
69 1.1 christos TM3BR,
70 1.1 christos TM4BR,
71 1.1 christos TM5BR,
72 1.1 christos LAST_BASE_REG = TM5BR,
73 1.1 christos FIRST_COUNTER,
74 1.1 christos TM0BC = FIRST_COUNTER,
75 1.1 christos TM1BC,
76 1.1 christos TM2BC,
77 1.1 christos TM3BC,
78 1.1 christos TM4BC,
79 1.1 christos TM5BC,
80 1.1 christos TM6BC,
81 1.1 christos LAST_COUNTER = TM6BC,
82 1.1 christos TM6MDA,
83 1.1 christos TM6MDB,
84 1.1 christos TM6CA,
85 1.1 christos TM6CB,
86 1.1 christos LAST_TIMER_REG = TM6BC,
87 1.1 christos };
88 1.1 christos
89 1.1 christos
90 1.1 christos /* Don't include timer 6 because it's handled specially. */
91 1.1 christos #define NR_8BIT_TIMERS 4
92 1.1 christos #define NR_16BIT_TIMERS 2
93 1.1 christos #define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */
94 1.1 christos #define NR_TIMERS 7
95 1.1 christos
96 1.1 christos typedef struct _mn10300_timer_regs {
97 1.1 christos unsigned32 base;
98 1.1 christos unsigned8 mode;
99 1.1 christos } mn10300_timer_regs;
100 1.1 christos
101 1.1 christos typedef struct _mn10300_timer {
102 1.1 christos unsigned32 div_ratio, start;
103 1.1 christos struct hw_event *event;
104 1.1 christos } mn10300_timer;
105 1.1 christos
106 1.1 christos
107 1.1 christos struct mn103tim {
108 1.1 christos struct mn103tim_block block[NR_TIMER_BLOCKS];
109 1.1 christos mn10300_timer_regs reg[NR_REG_TIMERS];
110 1.1 christos mn10300_timer timer[NR_TIMERS];
111 1.1 christos
112 1.1 christos /* treat timer 6 registers specially. */
113 1.1 christos unsigned16 tm6md0, tm6md1, tm6bc, tm6ca, tm6cb;
114 1.1 christos unsigned8 tm6mda, tm6mdb; /* compare/capture mode regs for timer 6 */
115 1.1 christos };
116 1.1 christos
117 1.1 christos /* output port ID's */
118 1.1 christos
119 1.1 christos /* for mn103002 */
120 1.1 christos enum {
121 1.1 christos TIMER0_UFLOW,
122 1.1 christos TIMER1_UFLOW,
123 1.1 christos TIMER2_UFLOW,
124 1.1 christos TIMER3_UFLOW,
125 1.1 christos TIMER4_UFLOW,
126 1.1 christos TIMER5_UFLOW,
127 1.1 christos TIMER6_UFLOW,
128 1.1 christos TIMER6_CMPA,
129 1.1 christos TIMER6_CMPB,
130 1.1 christos };
131 1.1 christos
132 1.1 christos
133 1.1 christos static const struct hw_port_descriptor mn103tim_ports[] = {
134 1.1 christos
135 1.1 christos { "timer-0-underflow", TIMER0_UFLOW, 0, output_port, },
136 1.1 christos { "timer-1-underflow", TIMER1_UFLOW, 0, output_port, },
137 1.1 christos { "timer-2-underflow", TIMER2_UFLOW, 0, output_port, },
138 1.1 christos { "timer-3-underflow", TIMER3_UFLOW, 0, output_port, },
139 1.1 christos { "timer-4-underflow", TIMER4_UFLOW, 0, output_port, },
140 1.1 christos { "timer-5-underflow", TIMER5_UFLOW, 0, output_port, },
141 1.1 christos
142 1.1 christos { "timer-6-underflow", TIMER6_UFLOW, 0, output_port, },
143 1.1 christos { "timer-6-compare-a", TIMER6_CMPA, 0, output_port, },
144 1.1 christos { "timer-6-compare-b", TIMER6_CMPB, 0, output_port, },
145 1.1 christos
146 1.1 christos { NULL, },
147 1.1 christos };
148 1.1 christos
149 1.1 christos #define bits2to5_mask 0x3c
150 1.1 christos #define bits0to2_mask 0x07
151 1.1 christos #define load_mask 0x40
152 1.1 christos #define count_mask 0x80
153 1.1 christos #define count_and_load_mask (load_mask | count_mask)
154 1.1 christos #define clock_mask 0x03
155 1.1 christos #define clk_ioclk 0x00
156 1.1 christos #define clk_cascaded 0x03
157 1.1 christos
158 1.1 christos
159 1.1 christos /* Finish off the partially created hw device. Attach our local
160 1.1 christos callbacks. Wire up our port names etc */
161 1.1 christos
162 1.1 christos static hw_io_read_buffer_method mn103tim_io_read_buffer;
163 1.1 christos static hw_io_write_buffer_method mn103tim_io_write_buffer;
164 1.1 christos
165 1.1 christos static void
166 1.1 christos attach_mn103tim_regs (struct hw *me,
167 1.1 christos struct mn103tim *timers)
168 1.1 christos {
169 1.1 christos int i;
170 1.1 christos if (hw_find_property (me, "reg") == NULL)
171 1.1 christos hw_abort (me, "Missing \"reg\" property");
172 1.1 christos for (i = 0; i < NR_TIMER_BLOCKS; i++)
173 1.1 christos {
174 1.1 christos unsigned_word attach_address;
175 1.1 christos int attach_space;
176 1.1 christos unsigned attach_size;
177 1.1 christos reg_property_spec reg;
178 1.1 christos if (!hw_find_reg_array_property (me, "reg", i, ®))
179 1.1 christos hw_abort (me, "\"reg\" property must contain three addr/size entries");
180 1.1 christos hw_unit_address_to_attach_address (hw_parent (me),
181 1.1 christos ®.address,
182 1.1 christos &attach_space,
183 1.1 christos &attach_address,
184 1.1 christos me);
185 1.1 christos timers->block[i].base = attach_address;
186 1.1 christos hw_unit_size_to_attach_size (hw_parent (me),
187 1.1 christos ®.size,
188 1.1 christos &attach_size, me);
189 1.1 christos timers->block[i].bound = attach_address + (attach_size - 1);
190 1.1 christos hw_attach_address (hw_parent (me),
191 1.1 christos 0,
192 1.1 christos attach_space, attach_address, attach_size,
193 1.1 christos me);
194 1.1 christos }
195 1.1 christos }
196 1.1 christos
197 1.1 christos static void
198 1.1 christos mn103tim_finish (struct hw *me)
199 1.1 christos {
200 1.1 christos struct mn103tim *timers;
201 1.1 christos int i;
202 1.1 christos
203 1.1 christos timers = HW_ZALLOC (me, struct mn103tim);
204 1.1 christos set_hw_data (me, timers);
205 1.1 christos set_hw_io_read_buffer (me, mn103tim_io_read_buffer);
206 1.1 christos set_hw_io_write_buffer (me, mn103tim_io_write_buffer);
207 1.1 christos set_hw_ports (me, mn103tim_ports);
208 1.1 christos
209 1.1 christos /* Attach ourself to our parent bus */
210 1.1 christos attach_mn103tim_regs (me, timers);
211 1.1 christos
212 1.1 christos /* Initialize the timers */
213 1.1 christos for ( i=0; i < NR_REG_TIMERS; ++i )
214 1.1 christos {
215 1.1 christos timers->reg[i].mode = 0x00;
216 1.1 christos timers->reg[i].base = 0;
217 1.1 christos }
218 1.1 christos for ( i=0; i < NR_TIMERS; ++i )
219 1.1 christos {
220 1.1 christos timers->timer[i].event = NULL;
221 1.1 christos timers->timer[i].div_ratio = 0;
222 1.1 christos timers->timer[i].start = 0;
223 1.1 christos }
224 1.1 christos timers->tm6md0 = 0x00;
225 1.1 christos timers->tm6md1 = 0x00;
226 1.1 christos timers->tm6bc = 0x0000;
227 1.1 christos timers->tm6ca = 0x0000;
228 1.1 christos timers->tm6cb = 0x0000;
229 1.1 christos timers->tm6mda = 0x00;
230 1.1 christos timers->tm6mdb = 0x00;
231 1.1 christos }
232 1.1 christos
233 1.1 christos
234 1.1 christos
235 1.1 christos /* read and write */
236 1.1 christos
237 1.1 christos static int
238 1.1 christos decode_addr (struct hw *me,
239 1.1 christos struct mn103tim *timers,
240 1.1 christos unsigned_word address)
241 1.1 christos {
242 1.1 christos unsigned_word offset;
243 1.1 christos offset = address - timers->block[0].base;
244 1.1 christos
245 1.1 christos switch (offset)
246 1.1 christos {
247 1.1 christos case 0x00: return TM0MD;
248 1.1 christos case 0x01: return TM1MD;
249 1.1 christos case 0x02: return TM2MD;
250 1.1 christos case 0x03: return TM3MD;
251 1.1 christos case 0x10: return TM0BR;
252 1.1 christos case 0x11: return TM1BR;
253 1.1 christos case 0x12: return TM2BR;
254 1.1 christos case 0x13: return TM3BR;
255 1.1 christos case 0x20: return TM0BC;
256 1.1 christos case 0x21: return TM1BC;
257 1.1 christos case 0x22: return TM2BC;
258 1.1 christos case 0x23: return TM3BC;
259 1.1 christos case 0x80: return TM4MD;
260 1.1 christos case 0x82: return TM5MD;
261 1.1 christos case 0x84: /* fall through */
262 1.1 christos case 0x85: return TM6MD;
263 1.1 christos case 0x90: return TM4BR;
264 1.1 christos case 0x92: return TM5BR;
265 1.1 christos case 0xa0: return TM4BC;
266 1.1 christos case 0xa2: return TM5BC;
267 1.1 christos case 0xa4: return TM6BC;
268 1.1 christos case 0xb4: return TM6MDA;
269 1.1 christos case 0xb5: return TM6MDB;
270 1.1 christos case 0xc4: return TM6CA;
271 1.1 christos case 0xd4: return TM6CB;
272 1.1 christos default:
273 1.1 christos {
274 1.1 christos hw_abort (me, "bad address");
275 1.1 christos return -1;
276 1.1 christos }
277 1.1 christos }
278 1.1 christos }
279 1.1 christos
280 1.1 christos static void
281 1.1 christos read_mode_reg (struct hw *me,
282 1.1 christos struct mn103tim *timers,
283 1.1 christos int timer_nr,
284 1.1 christos void *dest,
285 1.1 christos unsigned nr_bytes)
286 1.1 christos {
287 1.1 christos unsigned16 val16;
288 1.1 christos unsigned32 val32;
289 1.1 christos
290 1.1 christos switch ( nr_bytes )
291 1.1 christos {
292 1.1 christos case 1:
293 1.1 christos /* Accessing 1 byte is ok for all mode registers. */
294 1.1 christos if ( timer_nr == 6 )
295 1.1 christos {
296 1.1 christos *(unsigned8*)dest = timers->tm6md0;
297 1.1 christos }
298 1.1 christos else
299 1.1 christos {
300 1.1 christos *(unsigned8*)dest = timers->reg[timer_nr].mode;
301 1.1 christos }
302 1.1 christos break;
303 1.1 christos
304 1.1 christos case 2:
305 1.1 christos if ( timer_nr == 6 )
306 1.1 christos {
307 1.1 christos *(unsigned16 *)dest = (timers->tm6md0 << 8) | timers->tm6md1;
308 1.1 christos }
309 1.1 christos else if ( timer_nr == 0 || timer_nr == 2 )
310 1.1 christos {
311 1.1 christos val16 = (timers->reg[timer_nr].mode << 8)
312 1.1 christos | timers->reg[timer_nr+1].mode;
313 1.1 christos *(unsigned16*)dest = val16;
314 1.1 christos }
315 1.1 christos else
316 1.1 christos {
317 1.1 christos hw_abort (me, "bad read size of 2 bytes to TM%dMD.", timer_nr);
318 1.1 christos }
319 1.1 christos break;
320 1.1 christos
321 1.1 christos case 4:
322 1.1 christos if ( timer_nr == 0 )
323 1.1 christos {
324 1.1 christos val32 = (timers->reg[0].mode << 24 )
325 1.1 christos | (timers->reg[1].mode << 16)
326 1.1 christos | (timers->reg[2].mode << 8)
327 1.1 christos | timers->reg[3].mode;
328 1.1 christos *(unsigned32*)dest = val32;
329 1.1 christos }
330 1.1 christos else
331 1.1 christos {
332 1.1 christos hw_abort (me, "bad read size of 4 bytes to TM%dMD.", timer_nr);
333 1.1 christos }
334 1.1 christos break;
335 1.1 christos
336 1.1 christos default:
337 1.1 christos hw_abort (me, "bad read size of %d bytes to TM%dMD.",
338 1.1 christos nr_bytes, timer_nr);
339 1.1 christos }
340 1.1 christos }
341 1.1 christos
342 1.1 christos
343 1.1 christos static void
344 1.1 christos read_base_reg (struct hw *me,
345 1.1 christos struct mn103tim *timers,
346 1.1 christos int timer_nr,
347 1.1 christos void *dest,
348 1.1 christos unsigned nr_bytes)
349 1.1 christos {
350 1.1 christos unsigned16 val16;
351 1.1 christos unsigned32 val32;
352 1.1 christos
353 1.1 christos /* Check nr_bytes: accesses of 1, 2 and 4 bytes allowed depending on timer. */
354 1.1 christos switch ( nr_bytes )
355 1.1 christos {
356 1.1 christos case 1:
357 1.1 christos /* Reading 1 byte is ok for all registers. */
358 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
359 1.1 christos {
360 1.1 christos *(unsigned8*)dest = timers->reg[timer_nr].base;
361 1.1 christos }
362 1.1 christos break;
363 1.1 christos
364 1.1 christos case 2:
365 1.1 christos if ( timer_nr == 1 || timer_nr == 3 )
366 1.1 christos {
367 1.1 christos hw_abort (me, "bad read size of 2 bytes to TM%dBR.", timer_nr);
368 1.1 christos }
369 1.1 christos else
370 1.1 christos {
371 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
372 1.1 christos {
373 1.1 christos val16 = (timers->reg[timer_nr].base<<8)
374 1.1 christos | timers->reg[timer_nr+1].base;
375 1.1 christos }
376 1.1 christos else
377 1.1 christos {
378 1.1 christos val16 = timers->reg[timer_nr].base;
379 1.1 christos }
380 1.1 christos *(unsigned16*)dest = val16;
381 1.1 christos }
382 1.1 christos break;
383 1.1 christos
384 1.1 christos case 4:
385 1.1 christos if ( timer_nr == 0 )
386 1.1 christos {
387 1.1 christos val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16)
388 1.1 christos | (timers->reg[2].base << 8) | timers->reg[3].base;
389 1.1 christos *(unsigned32*)dest = val32;
390 1.1 christos }
391 1.1 christos else if ( timer_nr == 4 )
392 1.1 christos {
393 1.1 christos val32 = (timers->reg[4].base << 16) | timers->reg[5].base;
394 1.1 christos *(unsigned32*)dest = val32;
395 1.1 christos }
396 1.1 christos else
397 1.1 christos {
398 1.1 christos hw_abort (me, "bad read size of 4 bytes to TM%dBR.", timer_nr);
399 1.1 christos }
400 1.1 christos break;
401 1.1 christos
402 1.1 christos default:
403 1.1 christos hw_abort (me, "bad read size must of %d bytes to TM%dBR.",
404 1.1 christos nr_bytes, timer_nr);
405 1.1 christos }
406 1.1 christos }
407 1.1 christos
408 1.1 christos
409 1.1 christos static void
410 1.1 christos read_counter (struct hw *me,
411 1.1 christos struct mn103tim *timers,
412 1.1 christos int timer_nr,
413 1.1 christos void *dest,
414 1.1 christos unsigned nr_bytes)
415 1.1 christos {
416 1.1 christos unsigned32 val;
417 1.1 christos
418 1.1 christos if ( NULL == timers->timer[timer_nr].event )
419 1.1 christos {
420 1.1 christos /* Timer is not counting, use value in base register. */
421 1.1 christos if ( timer_nr == 6 )
422 1.1 christos {
423 1.1 christos val = 0; /* timer 6 is an up counter */
424 1.1 christos }
425 1.1 christos else
426 1.1 christos {
427 1.1 christos val = timers->reg[timer_nr].base;
428 1.1 christos }
429 1.1 christos }
430 1.1 christos else
431 1.1 christos {
432 1.1 christos if ( timer_nr == 6 ) /* timer 6 is an up counter. */
433 1.1 christos {
434 1.1 christos val = hw_event_queue_time(me) - timers->timer[timer_nr].start;
435 1.1 christos }
436 1.1 christos else
437 1.1 christos {
438 1.1 christos /* ticks left = start time + div ratio - curr time */
439 1.1 christos /* Cannot use base register because it can be written during counting and it
440 1.1 christos doesn't affect counter until underflow occurs. */
441 1.1 christos
442 1.1 christos val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
443 1.1 christos - hw_event_queue_time(me);
444 1.1 christos }
445 1.1 christos }
446 1.1 christos
447 1.1 christos switch (nr_bytes) {
448 1.1 christos case 1:
449 1.1 christos *(unsigned8 *)dest = val;
450 1.1 christos break;
451 1.1 christos
452 1.1 christos case 2:
453 1.1 christos *(unsigned16 *)dest = val;
454 1.1 christos break;
455 1.1 christos
456 1.1 christos case 4:
457 1.1 christos *(unsigned32 *)dest = val;
458 1.1 christos break;
459 1.1 christos
460 1.1 christos default:
461 1.1 christos hw_abort(me, "bad read size for reading counter");
462 1.1 christos }
463 1.1 christos
464 1.1 christos }
465 1.1 christos
466 1.1 christos
467 1.1 christos static void
468 1.1 christos read_special_timer6_reg (struct hw *me,
469 1.1 christos struct mn103tim *timers,
470 1.1 christos int timer_nr,
471 1.1 christos void *dest,
472 1.1 christos unsigned nr_bytes)
473 1.1 christos {
474 1.1 christos unsigned32 val;
475 1.1 christos
476 1.1 christos switch (nr_bytes) {
477 1.1 christos case 1:
478 1.1 christos {
479 1.1 christos switch ( timer_nr ) {
480 1.1 christos case TM6MDA:
481 1.1 christos *(unsigned8 *)dest = timers->tm6mda;
482 1.1 christos break;
483 1.1 christos
484 1.1 christos case TM6MDB:
485 1.1 christos *(unsigned8 *)dest = timers->tm6mdb;
486 1.1 christos break;
487 1.1 christos
488 1.1 christos case TM6CA:
489 1.1 christos *(unsigned8 *)dest = timers->tm6ca;
490 1.1 christos break;
491 1.1 christos
492 1.1 christos case TM6CB:
493 1.1 christos *(unsigned8 *)dest = timers->tm6cb;
494 1.1 christos break;
495 1.1 christos
496 1.1 christos default:
497 1.1 christos break;
498 1.1 christos }
499 1.1 christos break;
500 1.1 christos }
501 1.1 christos
502 1.1 christos case 2:
503 1.1 christos if ( timer_nr == TM6CA )
504 1.1 christos {
505 1.1 christos *(unsigned16 *)dest = timers->tm6ca;
506 1.1 christos }
507 1.1 christos else if ( timer_nr == TM6CB )
508 1.1 christos {
509 1.1 christos *(unsigned16 *)dest = timers->tm6cb;
510 1.1 christos }
511 1.1 christos else
512 1.1 christos {
513 1.1 christos hw_abort(me, "bad read size for timer 6 mode A/B register");
514 1.1 christos }
515 1.1 christos break;
516 1.1 christos
517 1.1 christos default:
518 1.1 christos hw_abort(me, "bad read size for timer 6 register");
519 1.1 christos }
520 1.1 christos
521 1.1 christos }
522 1.1 christos
523 1.1 christos
524 1.1 christos static unsigned
525 1.1 christos mn103tim_io_read_buffer (struct hw *me,
526 1.1 christos void *dest,
527 1.1 christos int space,
528 1.1 christos unsigned_word base,
529 1.1 christos unsigned nr_bytes)
530 1.1 christos {
531 1.1 christos struct mn103tim *timers = hw_data (me);
532 1.1 christos enum timer_register_types timer_reg;
533 1.1 christos
534 1.1 christos HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
535 1.1 christos
536 1.1 christos timer_reg = decode_addr (me, timers, base);
537 1.1 christos
538 1.1 christos /* It can be either a mode register, a base register, a binary counter, */
539 1.1 christos /* or a special timer 6 register. Check in that order. */
540 1.1 christos if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
541 1.1 christos {
542 1.1 christos read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
543 1.1 christos }
544 1.1 christos else if ( timer_reg <= LAST_BASE_REG )
545 1.1 christos {
546 1.1 christos read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
547 1.1 christos }
548 1.1 christos else if ( timer_reg <= LAST_COUNTER )
549 1.1 christos {
550 1.1 christos read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
551 1.1 christos }
552 1.1 christos else if ( timer_reg <= LAST_TIMER_REG )
553 1.1 christos {
554 1.1 christos read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
555 1.1 christos }
556 1.1 christos else
557 1.1 christos {
558 1.1 christos hw_abort(me, "invalid timer register address.");
559 1.1 christos }
560 1.1 christos
561 1.1 christos return nr_bytes;
562 1.1 christos }
563 1.1 christos
564 1.1 christos
565 1.1 christos static void
566 1.1 christos do_counter_event (struct hw *me,
567 1.1 christos void *data)
568 1.1 christos {
569 1.1 christos struct mn103tim *timers = hw_data(me);
570 1.1 christos long timer_nr = (long) data;
571 1.1 christos int next_timer;
572 1.1 christos
573 1.1 christos /* Check if counting is still enabled. */
574 1.1 christos if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
575 1.1 christos {
576 1.1 christos /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
577 1.1 christos
578 1.1 christos /* Port event occurs on port of last cascaded timer. */
579 1.1 christos /* This works across timer range from 0 to NR_REG_TIMERS because */
580 1.1 christos /* the first 16 bit timer (timer 4) is not allowed to be set as */
581 1.1 christos /* a cascading timer. */
582 1.1 christos for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer )
583 1.1 christos {
584 1.1 christos if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded )
585 1.1 christos {
586 1.1 christos break;
587 1.1 christos }
588 1.1 christos }
589 1.1 christos hw_port_event (me, next_timer-1, 1);
590 1.1 christos
591 1.1 christos /* Schedule next timeout. */
592 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
593 1.1 christos /* FIX: Check if div_ratio has changed and if it's now 0. */
594 1.1 christos timers->timer[timer_nr].event
595 1.1 christos = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
596 1.1 christos do_counter_event, (void *)timer_nr);
597 1.1 christos }
598 1.1 christos else
599 1.1 christos {
600 1.1 christos timers->timer[timer_nr].event = NULL;
601 1.1 christos }
602 1.1 christos
603 1.1 christos }
604 1.1 christos
605 1.1 christos
606 1.1 christos static void
607 1.1 christos do_counter6_event (struct hw *me,
608 1.1 christos void *data)
609 1.1 christos {
610 1.1 christos struct mn103tim *timers = hw_data(me);
611 1.1 christos long timer_nr = (long) data;
612 1.1 christos int next_timer;
613 1.1 christos
614 1.1 christos /* Check if counting is still enabled. */
615 1.1 christos if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
616 1.1 christos {
617 1.1 christos /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
618 1.1 christos hw_port_event (me, timer_nr, 1);
619 1.1 christos
620 1.1 christos /* Schedule next timeout. */
621 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
622 1.1 christos /* FIX: Check if div_ratio has changed and if it's now 0. */
623 1.1 christos timers->timer[timer_nr].event
624 1.1 christos = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
625 1.1 christos do_counter6_event, (void *)timer_nr);
626 1.1 christos }
627 1.1 christos else
628 1.1 christos {
629 1.1 christos timers->timer[timer_nr].event = NULL;
630 1.1 christos }
631 1.1 christos
632 1.1 christos }
633 1.1 christos
634 1.1 christos static void
635 1.1 christos write_base_reg (struct hw *me,
636 1.1 christos struct mn103tim *timers,
637 1.1 christos int timer_nr,
638 1.1 christos const void *source,
639 1.1 christos unsigned nr_bytes)
640 1.1 christos {
641 1.1 christos unsigned i;
642 1.1 christos const unsigned8 *buf8 = source;
643 1.1 christos const unsigned16 *buf16 = source;
644 1.1 christos
645 1.1 christos /* If TMnCNE == 0 (counting is off), writing to the base register
646 1.1 christos (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
647 1.1 christos Else, the TMnBC is reloaded with the value from TMnBR when
648 1.1 christos underflow occurs. Since the counter register is not explicitly
649 1.1 christos maintained, this functionality is handled in read_counter. */
650 1.1 christos
651 1.1 christos /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
652 1.1 christos switch ( nr_bytes )
653 1.1 christos {
654 1.1 christos case 1:
655 1.1 christos /* Storing 1 byte is ok for all registers. */
656 1.1 christos timers->reg[timer_nr].base = buf8[0];
657 1.1 christos break;
658 1.1 christos
659 1.1 christos case 2:
660 1.1 christos if ( timer_nr == 1 || timer_nr == 3 )
661 1.1 christos {
662 1.1 christos hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
663 1.1 christos }
664 1.1 christos else
665 1.1 christos {
666 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
667 1.1 christos {
668 1.1 christos timers->reg[timer_nr].base = buf8[0];
669 1.1 christos timers->reg[timer_nr+1].base = buf8[1];
670 1.1 christos }
671 1.1 christos else
672 1.1 christos {
673 1.1 christos timers->reg[timer_nr].base = buf16[0];
674 1.1 christos }
675 1.1 christos }
676 1.1 christos break;
677 1.1 christos
678 1.1 christos case 4:
679 1.1 christos if ( timer_nr == 0 )
680 1.1 christos {
681 1.1 christos timers->reg[0].base = buf8[0];
682 1.1 christos timers->reg[1].base = buf8[1];
683 1.1 christos timers->reg[2].base = buf8[2];
684 1.1 christos timers->reg[3].base = buf8[3];
685 1.1 christos }
686 1.1 christos else if ( timer_nr == 4 )
687 1.1 christos {
688 1.1 christos timers->reg[4].base = buf16[0];
689 1.1 christos timers->reg[5].base = buf16[1];
690 1.1 christos }
691 1.1 christos else
692 1.1 christos {
693 1.1 christos hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
694 1.1 christos }
695 1.1 christos break;
696 1.1 christos
697 1.1 christos default:
698 1.1 christos hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
699 1.1 christos nr_bytes, timer_nr);
700 1.1 christos }
701 1.1 christos
702 1.1 christos }
703 1.1 christos
704 1.1 christos static void
705 1.1 christos write_mode_reg (struct hw *me,
706 1.1 christos struct mn103tim *timers,
707 1.1 christos long timer_nr,
708 1.1 christos const void *source,
709 1.1 christos unsigned nr_bytes)
710 1.1 christos /* for timers 0 to 5 */
711 1.1 christos {
712 1.1 christos unsigned i;
713 1.1 christos unsigned8 mode_val, next_mode_val;
714 1.1 christos unsigned32 div_ratio;
715 1.1 christos
716 1.1 christos if ( nr_bytes != 1 )
717 1.1 christos {
718 1.1 christos hw_abort (me, "bad write size of %d bytes to TM%ldMD.", nr_bytes,
719 1.1 christos timer_nr);
720 1.1 christos }
721 1.1 christos
722 1.1 christos mode_val = *(unsigned8 *)source;
723 1.1 christos timers->reg[timer_nr].mode = mode_val;
724 1.1 christos
725 1.1 christos if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
726 1.1 christos {
727 1.1 christos hw_abort(me, "Cannot load base reg and start counting simultaneously.");
728 1.1 christos }
729 1.1 christos if ( ( mode_val & bits2to5_mask ) != 0 )
730 1.1 christos {
731 1.1 christos hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
732 1.1 christos }
733 1.1 christos
734 1.1 christos if ( mode_val & count_mask )
735 1.1 christos {
736 1.1 christos /* - de-schedule any previous event. */
737 1.1 christos /* - add new event to queue to start counting. */
738 1.1 christos /* - assert that counter == base reg? */
739 1.1 christos
740 1.1 christos /* For cascaded timers, */
741 1.1 christos if ( (mode_val & clock_mask) == clk_cascaded )
742 1.1 christos {
743 1.1 christos if ( timer_nr == 0 || timer_nr == 4 )
744 1.1 christos {
745 1.1 christos hw_abort(me, "Timer %ld cannot be cascaded.", timer_nr);
746 1.1 christos }
747 1.1 christos }
748 1.1 christos else
749 1.1 christos {
750 1.1 christos div_ratio = timers->reg[timer_nr].base;
751 1.1 christos
752 1.1 christos /* Check for cascading. */
753 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
754 1.1 christos {
755 1.1 christos for ( i = timer_nr + 1; i <= 3; ++i )
756 1.1 christos {
757 1.1 christos next_mode_val = timers->reg[i].mode;
758 1.1 christos if ( ( next_mode_val & clock_mask ) == clk_cascaded )
759 1.1 christos {
760 1.1 christos /* Check that CNE is on. */
761 1.1 christos if ( ( next_mode_val & count_mask ) == 0 )
762 1.1 christos {
763 1.1 christos hw_abort (me, "cascaded timer not ready for counting");
764 1.1 christos }
765 1.1 christos ASSERT(timers->timer[i].event == NULL);
766 1.1 christos ASSERT(timers->timer[i].div_ratio == 0);
767 1.1 christos div_ratio = div_ratio
768 1.1 christos | (timers->reg[i].base << (8*(i-timer_nr)));
769 1.1 christos }
770 1.1 christos else
771 1.1 christos {
772 1.1 christos break;
773 1.1 christos }
774 1.1 christos }
775 1.1 christos }
776 1.1 christos else
777 1.1 christos {
778 1.1 christos /* Mode register for a 16 bit timer */
779 1.1 christos next_mode_val = timers->reg[timer_nr+1].mode;
780 1.1 christos if ( ( next_mode_val & clock_mask ) == clk_cascaded )
781 1.1 christos {
782 1.1 christos /* Check that CNE is on. */
783 1.1 christos if ( ( next_mode_val & count_mask ) == 0 )
784 1.1 christos {
785 1.1 christos hw_abort (me, "cascaded timer not ready for counting");
786 1.1 christos }
787 1.1 christos ASSERT(timers->timer[timer_nr+1].event == NULL);
788 1.1 christos ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
789 1.1 christos div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
790 1.1 christos }
791 1.1 christos }
792 1.1 christos
793 1.1 christos timers->timer[timer_nr].div_ratio = div_ratio;
794 1.1 christos
795 1.1 christos if ( NULL != timers->timer[timer_nr].event )
796 1.1 christos {
797 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
798 1.1 christos timers->timer[timer_nr].event = NULL;
799 1.1 christos }
800 1.1 christos
801 1.1 christos if ( div_ratio > 0 )
802 1.1 christos {
803 1.1 christos /* Set start time. */
804 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
805 1.1 christos timers->timer[timer_nr].event
806 1.1 christos = hw_event_queue_schedule(me, div_ratio,
807 1.1 christos do_counter_event,
808 1.1 christos (void *)(timer_nr));
809 1.1 christos }
810 1.1 christos }
811 1.1 christos }
812 1.1 christos else
813 1.1 christos {
814 1.1 christos /* Turn off counting */
815 1.1 christos if ( NULL != timers->timer[timer_nr].event )
816 1.1 christos {
817 1.1 christos ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
818 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
819 1.1 christos timers->timer[timer_nr].event = NULL;
820 1.1 christos }
821 1.1 christos else
822 1.1 christos {
823 1.1 christos if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
824 1.1 christos {
825 1.1 christos ASSERT(timers->timer[timer_nr].event == NULL);
826 1.1 christos }
827 1.1 christos }
828 1.1 christos
829 1.1 christos }
830 1.1 christos
831 1.1 christos }
832 1.1 christos
833 1.1 christos static void
834 1.1 christos write_tm6md (struct hw *me,
835 1.1 christos struct mn103tim *timers,
836 1.1 christos unsigned_word address,
837 1.1 christos const void *source,
838 1.1 christos unsigned nr_bytes)
839 1.1 christos {
840 1.1 christos unsigned8 mode_val0 = 0x00, mode_val1 = 0x00;
841 1.1 christos unsigned32 div_ratio;
842 1.1 christos long timer_nr = 6;
843 1.1 christos
844 1.1 christos unsigned_word offset = address - timers->block[0].base;
845 1.1 christos
846 1.1 christos if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
847 1.1 christos {
848 1.1 christos hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
849 1.1 christos }
850 1.1 christos
851 1.1 christos if ( offset == 0x84 ) /* address of TM6MD */
852 1.1 christos {
853 1.1 christos /* Fill in first byte of mode */
854 1.1 christos mode_val0 = *(unsigned8 *)source;
855 1.1 christos timers->tm6md0 = mode_val0;
856 1.1 christos
857 1.1 christos if ( ( mode_val0 & 0x26 ) != 0 )
858 1.1 christos {
859 1.1 christos hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
860 1.1 christos }
861 1.1 christos }
862 1.1 christos
863 1.1 christos if ( offset == 0x85 || nr_bytes == 2 )
864 1.1 christos {
865 1.1 christos /* Fill in second byte of mode */
866 1.1 christos if ( nr_bytes == 2 )
867 1.1 christos {
868 1.1 christos mode_val1 = *(unsigned8 *)source+1;
869 1.1 christos }
870 1.1 christos else
871 1.1 christos {
872 1.1 christos mode_val1 = *(unsigned8 *)source;
873 1.1 christos }
874 1.1 christos
875 1.1 christos timers->tm6md1 = mode_val1;
876 1.1 christos
877 1.1 christos if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
878 1.1 christos {
879 1.1 christos hw_abort(me, "Cannot load base reg and start counting simultaneously.");
880 1.1 christos }
881 1.1 christos if ( ( mode_val1 & bits0to2_mask ) != 0 )
882 1.1 christos {
883 1.1 christos hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
884 1.1 christos }
885 1.1 christos }
886 1.1 christos
887 1.1 christos if ( mode_val1 & count_mask )
888 1.1 christos {
889 1.1 christos /* - de-schedule any previous event. */
890 1.1 christos /* - add new event to queue to start counting. */
891 1.1 christos /* - assert that counter == base reg? */
892 1.1 christos
893 1.1 christos div_ratio = timers->tm6ca; /* binary counter for timer 6 */
894 1.1 christos timers->timer[timer_nr].div_ratio = div_ratio;
895 1.1 christos if ( NULL != timers->timer[timer_nr].event )
896 1.1 christos {
897 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
898 1.1 christos timers->timer[timer_nr].event = NULL;
899 1.1 christos }
900 1.1 christos
901 1.1 christos if ( div_ratio > 0 )
902 1.1 christos {
903 1.1 christos /* Set start time. */
904 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
905 1.1 christos timers->timer[timer_nr].event
906 1.1 christos = hw_event_queue_schedule(me, div_ratio,
907 1.1 christos do_counter6_event,
908 1.1 christos (void *)(timer_nr));
909 1.1 christos }
910 1.1 christos }
911 1.1 christos else
912 1.1 christos {
913 1.1 christos /* Turn off counting */
914 1.1 christos if ( NULL != timers->timer[timer_nr].event )
915 1.1 christos {
916 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
917 1.1 christos timers->timer[timer_nr].event = NULL;
918 1.1 christos }
919 1.1 christos }
920 1.1 christos }
921 1.1 christos
922 1.1 christos
923 1.1 christos
924 1.1 christos static void
925 1.1 christos write_special_timer6_reg (struct hw *me,
926 1.1 christos struct mn103tim *timers,
927 1.1 christos int timer_nr,
928 1.1 christos const void *source,
929 1.1 christos unsigned nr_bytes)
930 1.1 christos {
931 1.1 christos unsigned32 val;
932 1.1 christos
933 1.1 christos switch (nr_bytes) {
934 1.1 christos case 1:
935 1.1 christos {
936 1.1 christos switch ( timer_nr ) {
937 1.1 christos case TM6MDA:
938 1.1 christos timers->tm6mda = *(unsigned8 *)source;
939 1.1 christos break;
940 1.1 christos
941 1.1 christos case TM6MDB:
942 1.1 christos timers->tm6mdb = *(unsigned8 *)source;
943 1.1 christos break;
944 1.1 christos
945 1.1 christos case TM6CA:
946 1.1 christos timers->tm6ca = *(unsigned8 *)source;
947 1.1 christos break;
948 1.1 christos
949 1.1 christos case TM6CB:
950 1.1 christos timers->tm6cb = *(unsigned8 *)source;
951 1.1 christos break;
952 1.1 christos
953 1.1 christos default:
954 1.1 christos break;
955 1.1 christos }
956 1.1 christos break;
957 1.1 christos }
958 1.1 christos
959 1.1 christos case 2:
960 1.1 christos if ( timer_nr == TM6CA )
961 1.1 christos {
962 1.1 christos timers->tm6ca = *(unsigned16 *)source;
963 1.1 christos }
964 1.1 christos else if ( timer_nr == TM6CB )
965 1.1 christos {
966 1.1 christos timers->tm6cb = *(unsigned16 *)source;
967 1.1 christos }
968 1.1 christos else
969 1.1 christos {
970 1.1 christos hw_abort(me, "bad read size for timer 6 mode A/B register");
971 1.1 christos }
972 1.1 christos break;
973 1.1 christos
974 1.1 christos default:
975 1.1 christos hw_abort(me, "bad read size for timer 6 register");
976 1.1 christos }
977 1.1 christos
978 1.1 christos }
979 1.1 christos
980 1.1 christos
981 1.1 christos static unsigned
982 1.1 christos mn103tim_io_write_buffer (struct hw *me,
983 1.1 christos const void *source,
984 1.1 christos int space,
985 1.1 christos unsigned_word base,
986 1.1 christos unsigned nr_bytes)
987 1.1 christos {
988 1.1 christos struct mn103tim *timers = hw_data (me);
989 1.1 christos enum timer_register_types timer_reg;
990 1.1 christos
991 1.1 christos HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
992 1.1 christos (int) nr_bytes, *(unsigned32 *)source));
993 1.1 christos
994 1.1 christos timer_reg = decode_addr (me, timers, base);
995 1.1 christos
996 1.1 christos /* It can be either a mode register, a base register, a binary counter, */
997 1.1 christos /* or a special timer 6 register. Check in that order. */
998 1.1 christos if ( timer_reg <= LAST_MODE_REG )
999 1.1 christos {
1000 1.1 christos if ( timer_reg == 6 )
1001 1.1 christos {
1002 1.1 christos write_tm6md(me, timers, base, source, nr_bytes);
1003 1.1 christos }
1004 1.1 christos else
1005 1.1 christos {
1006 1.1 christos write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1007 1.1 christos source, nr_bytes);
1008 1.1 christos }
1009 1.1 christos }
1010 1.1 christos else if ( timer_reg <= LAST_BASE_REG )
1011 1.1 christos {
1012 1.1 christos write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1013 1.1 christos }
1014 1.1 christos else if ( timer_reg <= LAST_COUNTER )
1015 1.1 christos {
1016 1.1 christos hw_abort(me, "cannot write to counter");
1017 1.1 christos }
1018 1.1 christos else if ( timer_reg <= LAST_TIMER_REG )
1019 1.1 christos {
1020 1.1 christos write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1021 1.1 christos }
1022 1.1 christos else
1023 1.1 christos {
1024 1.1 christos hw_abort(me, "invalid reg type");
1025 1.1 christos }
1026 1.1 christos
1027 1.1 christos return nr_bytes;
1028 1.1 christos }
1029 1.1 christos
1030 1.1 christos
1031 1.1 christos const struct hw_descriptor dv_mn103tim_descriptor[] = {
1032 1.1 christos { "mn103tim", mn103tim_finish, },
1033 1.1 christos { NULL },
1034 1.1 christos };
1035