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