dv-mn103tim.c revision 1.10 1 1.1 christos /* This file is part of the program GDB, the GNU debugger.
2 1.1 christos
3 1.10 christos Copyright (C) 1998-2023 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.1 christos LAST_TIMER_REG = TM6BC,
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.10 christos uint32_t val;
478 1.1 christos
479 1.1 christos switch (nr_bytes) {
480 1.1 christos case 1:
481 1.1 christos {
482 1.1 christos switch ( timer_nr ) {
483 1.1 christos case TM6MDA:
484 1.10 christos *(uint8_t *)dest = timers->tm6mda;
485 1.1 christos break;
486 1.1 christos
487 1.1 christos case TM6MDB:
488 1.10 christos *(uint8_t *)dest = timers->tm6mdb;
489 1.1 christos break;
490 1.1 christos
491 1.1 christos case TM6CA:
492 1.10 christos *(uint8_t *)dest = timers->tm6ca;
493 1.1 christos break;
494 1.1 christos
495 1.1 christos case TM6CB:
496 1.10 christos *(uint8_t *)dest = timers->tm6cb;
497 1.1 christos break;
498 1.1 christos
499 1.1 christos default:
500 1.1 christos break;
501 1.1 christos }
502 1.1 christos break;
503 1.1 christos }
504 1.1 christos
505 1.1 christos case 2:
506 1.1 christos if ( timer_nr == TM6CA )
507 1.1 christos {
508 1.10 christos *(uint16_t *)dest = timers->tm6ca;
509 1.1 christos }
510 1.1 christos else if ( timer_nr == TM6CB )
511 1.1 christos {
512 1.10 christos *(uint16_t *)dest = timers->tm6cb;
513 1.1 christos }
514 1.1 christos else
515 1.1 christos {
516 1.1 christos hw_abort(me, "bad read size for timer 6 mode A/B register");
517 1.1 christos }
518 1.1 christos break;
519 1.1 christos
520 1.1 christos default:
521 1.1 christos hw_abort(me, "bad read size for timer 6 register");
522 1.1 christos }
523 1.1 christos
524 1.1 christos }
525 1.1 christos
526 1.1 christos
527 1.1 christos static unsigned
528 1.1 christos mn103tim_io_read_buffer (struct hw *me,
529 1.1 christos void *dest,
530 1.1 christos int space,
531 1.1 christos unsigned_word base,
532 1.1 christos unsigned nr_bytes)
533 1.1 christos {
534 1.1 christos struct mn103tim *timers = hw_data (me);
535 1.1 christos enum timer_register_types timer_reg;
536 1.1 christos
537 1.1 christos HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
538 1.1 christos
539 1.1 christos timer_reg = decode_addr (me, timers, base);
540 1.1 christos
541 1.1 christos /* It can be either a mode register, a base register, a binary counter, */
542 1.1 christos /* or a special timer 6 register. Check in that order. */
543 1.1 christos if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
544 1.1 christos {
545 1.1 christos read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
546 1.1 christos }
547 1.1 christos else if ( timer_reg <= LAST_BASE_REG )
548 1.1 christos {
549 1.1 christos read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
550 1.1 christos }
551 1.1 christos else if ( timer_reg <= LAST_COUNTER )
552 1.1 christos {
553 1.1 christos read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
554 1.1 christos }
555 1.1 christos else if ( timer_reg <= LAST_TIMER_REG )
556 1.1 christos {
557 1.1 christos read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
558 1.1 christos }
559 1.1 christos else
560 1.1 christos {
561 1.1 christos hw_abort(me, "invalid timer register address.");
562 1.1 christos }
563 1.1 christos
564 1.1 christos return nr_bytes;
565 1.1 christos }
566 1.1 christos
567 1.1 christos
568 1.1 christos static void
569 1.1 christos do_counter_event (struct hw *me,
570 1.1 christos void *data)
571 1.1 christos {
572 1.1 christos struct mn103tim *timers = hw_data(me);
573 1.10 christos long timer_nr = (uintptr_t) data;
574 1.1 christos int next_timer;
575 1.1 christos
576 1.1 christos /* Check if counting is still enabled. */
577 1.1 christos if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
578 1.1 christos {
579 1.1 christos /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
580 1.1 christos
581 1.1 christos /* Port event occurs on port of last cascaded timer. */
582 1.1 christos /* This works across timer range from 0 to NR_REG_TIMERS because */
583 1.1 christos /* the first 16 bit timer (timer 4) is not allowed to be set as */
584 1.1 christos /* a cascading timer. */
585 1.1 christos for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer )
586 1.1 christos {
587 1.1 christos if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded )
588 1.1 christos {
589 1.1 christos break;
590 1.1 christos }
591 1.1 christos }
592 1.1 christos hw_port_event (me, next_timer-1, 1);
593 1.1 christos
594 1.1 christos /* Schedule next timeout. */
595 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
596 1.1 christos /* FIX: Check if div_ratio has changed and if it's now 0. */
597 1.1 christos timers->timer[timer_nr].event
598 1.1 christos = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
599 1.10 christos do_counter_event, (void *)(uintptr_t)timer_nr);
600 1.1 christos }
601 1.1 christos else
602 1.1 christos {
603 1.1 christos timers->timer[timer_nr].event = NULL;
604 1.1 christos }
605 1.1 christos
606 1.1 christos }
607 1.1 christos
608 1.1 christos
609 1.1 christos static void
610 1.1 christos do_counter6_event (struct hw *me,
611 1.1 christos void *data)
612 1.1 christos {
613 1.1 christos struct mn103tim *timers = hw_data(me);
614 1.10 christos long timer_nr = (uintptr_t) data;
615 1.1 christos int next_timer;
616 1.1 christos
617 1.1 christos /* Check if counting is still enabled. */
618 1.1 christos if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
619 1.1 christos {
620 1.1 christos /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
621 1.1 christos hw_port_event (me, timer_nr, 1);
622 1.1 christos
623 1.1 christos /* Schedule next timeout. */
624 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
625 1.1 christos /* FIX: Check if div_ratio has changed and if it's now 0. */
626 1.1 christos timers->timer[timer_nr].event
627 1.1 christos = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
628 1.10 christos do_counter6_event, (void *)(uintptr_t)timer_nr);
629 1.1 christos }
630 1.1 christos else
631 1.1 christos {
632 1.1 christos timers->timer[timer_nr].event = NULL;
633 1.1 christos }
634 1.1 christos
635 1.1 christos }
636 1.1 christos
637 1.1 christos static void
638 1.1 christos write_base_reg (struct hw *me,
639 1.1 christos struct mn103tim *timers,
640 1.1 christos int timer_nr,
641 1.1 christos const void *source,
642 1.1 christos unsigned nr_bytes)
643 1.1 christos {
644 1.1 christos unsigned i;
645 1.10 christos const uint8_t *buf8 = source;
646 1.10 christos const uint16_t *buf16 = source;
647 1.1 christos
648 1.1 christos /* If TMnCNE == 0 (counting is off), writing to the base register
649 1.1 christos (TMnBR) causes a simultaneous write to the counter reg (TMnBC).
650 1.1 christos Else, the TMnBC is reloaded with the value from TMnBR when
651 1.1 christos underflow occurs. Since the counter register is not explicitly
652 1.1 christos maintained, this functionality is handled in read_counter. */
653 1.1 christos
654 1.1 christos /* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
655 1.1 christos switch ( nr_bytes )
656 1.1 christos {
657 1.1 christos case 1:
658 1.1 christos /* Storing 1 byte is ok for all registers. */
659 1.1 christos timers->reg[timer_nr].base = buf8[0];
660 1.1 christos break;
661 1.1 christos
662 1.1 christos case 2:
663 1.1 christos if ( timer_nr == 1 || timer_nr == 3 )
664 1.1 christos {
665 1.1 christos hw_abort (me, "bad write size of 2 bytes to TM%dBR.", timer_nr);
666 1.1 christos }
667 1.1 christos else
668 1.1 christos {
669 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
670 1.1 christos {
671 1.1 christos timers->reg[timer_nr].base = buf8[0];
672 1.1 christos timers->reg[timer_nr+1].base = buf8[1];
673 1.1 christos }
674 1.1 christos else
675 1.1 christos {
676 1.1 christos timers->reg[timer_nr].base = buf16[0];
677 1.1 christos }
678 1.1 christos }
679 1.1 christos break;
680 1.1 christos
681 1.1 christos case 4:
682 1.1 christos if ( timer_nr == 0 )
683 1.1 christos {
684 1.1 christos timers->reg[0].base = buf8[0];
685 1.1 christos timers->reg[1].base = buf8[1];
686 1.1 christos timers->reg[2].base = buf8[2];
687 1.1 christos timers->reg[3].base = buf8[3];
688 1.1 christos }
689 1.1 christos else if ( timer_nr == 4 )
690 1.1 christos {
691 1.1 christos timers->reg[4].base = buf16[0];
692 1.1 christos timers->reg[5].base = buf16[1];
693 1.1 christos }
694 1.1 christos else
695 1.1 christos {
696 1.1 christos hw_abort (me, "bad write size of 4 bytes to TM%dBR.", timer_nr);
697 1.1 christos }
698 1.1 christos break;
699 1.1 christos
700 1.1 christos default:
701 1.1 christos hw_abort (me, "bad write size must of %d bytes to TM%dBR.",
702 1.1 christos nr_bytes, timer_nr);
703 1.1 christos }
704 1.1 christos
705 1.1 christos }
706 1.1 christos
707 1.1 christos static void
708 1.1 christos write_mode_reg (struct hw *me,
709 1.1 christos struct mn103tim *timers,
710 1.1 christos long timer_nr,
711 1.1 christos const void *source,
712 1.1 christos unsigned nr_bytes)
713 1.1 christos /* for timers 0 to 5 */
714 1.1 christos {
715 1.1 christos unsigned i;
716 1.10 christos uint8_t mode_val, next_mode_val;
717 1.10 christos uint32_t div_ratio;
718 1.1 christos
719 1.1 christos if ( nr_bytes != 1 )
720 1.1 christos {
721 1.1 christos hw_abort (me, "bad write size of %d bytes to TM%ldMD.", nr_bytes,
722 1.1 christos timer_nr);
723 1.1 christos }
724 1.1 christos
725 1.10 christos mode_val = *(uint8_t *)source;
726 1.1 christos timers->reg[timer_nr].mode = mode_val;
727 1.1 christos
728 1.1 christos if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
729 1.1 christos {
730 1.1 christos hw_abort(me, "Cannot load base reg and start counting simultaneously.");
731 1.1 christos }
732 1.1 christos if ( ( mode_val & bits2to5_mask ) != 0 )
733 1.1 christos {
734 1.1 christos hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
735 1.1 christos }
736 1.1 christos
737 1.1 christos if ( mode_val & count_mask )
738 1.1 christos {
739 1.1 christos /* - de-schedule any previous event. */
740 1.1 christos /* - add new event to queue to start counting. */
741 1.1 christos /* - assert that counter == base reg? */
742 1.1 christos
743 1.1 christos /* For cascaded timers, */
744 1.1 christos if ( (mode_val & clock_mask) == clk_cascaded )
745 1.1 christos {
746 1.1 christos if ( timer_nr == 0 || timer_nr == 4 )
747 1.1 christos {
748 1.1 christos hw_abort(me, "Timer %ld cannot be cascaded.", timer_nr);
749 1.1 christos }
750 1.1 christos }
751 1.1 christos else
752 1.1 christos {
753 1.1 christos div_ratio = timers->reg[timer_nr].base;
754 1.1 christos
755 1.1 christos /* Check for cascading. */
756 1.1 christos if ( timer_nr < NR_8BIT_TIMERS )
757 1.1 christos {
758 1.1 christos for ( i = timer_nr + 1; i <= 3; ++i )
759 1.1 christos {
760 1.1 christos next_mode_val = timers->reg[i].mode;
761 1.1 christos if ( ( next_mode_val & clock_mask ) == clk_cascaded )
762 1.1 christos {
763 1.1 christos /* Check that CNE is on. */
764 1.1 christos if ( ( next_mode_val & count_mask ) == 0 )
765 1.1 christos {
766 1.1 christos hw_abort (me, "cascaded timer not ready for counting");
767 1.1 christos }
768 1.1 christos ASSERT(timers->timer[i].event == NULL);
769 1.1 christos ASSERT(timers->timer[i].div_ratio == 0);
770 1.1 christos div_ratio = div_ratio
771 1.1 christos | (timers->reg[i].base << (8*(i-timer_nr)));
772 1.1 christos }
773 1.1 christos else
774 1.1 christos {
775 1.1 christos break;
776 1.1 christos }
777 1.1 christos }
778 1.1 christos }
779 1.1 christos else
780 1.1 christos {
781 1.1 christos /* Mode register for a 16 bit timer */
782 1.1 christos next_mode_val = timers->reg[timer_nr+1].mode;
783 1.1 christos if ( ( next_mode_val & clock_mask ) == clk_cascaded )
784 1.1 christos {
785 1.1 christos /* Check that CNE is on. */
786 1.1 christos if ( ( next_mode_val & count_mask ) == 0 )
787 1.1 christos {
788 1.1 christos hw_abort (me, "cascaded timer not ready for counting");
789 1.1 christos }
790 1.1 christos ASSERT(timers->timer[timer_nr+1].event == NULL);
791 1.1 christos ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
792 1.1 christos div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
793 1.1 christos }
794 1.1 christos }
795 1.1 christos
796 1.1 christos timers->timer[timer_nr].div_ratio = div_ratio;
797 1.1 christos
798 1.1 christos if ( NULL != timers->timer[timer_nr].event )
799 1.1 christos {
800 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
801 1.1 christos timers->timer[timer_nr].event = NULL;
802 1.1 christos }
803 1.1 christos
804 1.1 christos if ( div_ratio > 0 )
805 1.1 christos {
806 1.1 christos /* Set start time. */
807 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
808 1.1 christos timers->timer[timer_nr].event
809 1.1 christos = hw_event_queue_schedule(me, div_ratio,
810 1.1 christos do_counter_event,
811 1.10 christos (void *)(uintptr_t)timer_nr);
812 1.1 christos }
813 1.1 christos }
814 1.1 christos }
815 1.1 christos else
816 1.1 christos {
817 1.1 christos /* Turn off counting */
818 1.1 christos if ( NULL != timers->timer[timer_nr].event )
819 1.1 christos {
820 1.1 christos ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
821 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
822 1.1 christos timers->timer[timer_nr].event = NULL;
823 1.1 christos }
824 1.1 christos else
825 1.1 christos {
826 1.1 christos if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
827 1.1 christos {
828 1.1 christos ASSERT(timers->timer[timer_nr].event == NULL);
829 1.1 christos }
830 1.1 christos }
831 1.1 christos
832 1.1 christos }
833 1.1 christos
834 1.1 christos }
835 1.1 christos
836 1.1 christos static void
837 1.1 christos write_tm6md (struct hw *me,
838 1.1 christos struct mn103tim *timers,
839 1.1 christos unsigned_word address,
840 1.1 christos const void *source,
841 1.1 christos unsigned nr_bytes)
842 1.1 christos {
843 1.10 christos uint8_t mode_val0 = 0x00, mode_val1 = 0x00;
844 1.10 christos uint32_t div_ratio;
845 1.1 christos long timer_nr = 6;
846 1.1 christos
847 1.1 christos unsigned_word offset = address - timers->block[0].base;
848 1.1 christos
849 1.1 christos if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
850 1.1 christos {
851 1.1 christos hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
852 1.1 christos }
853 1.1 christos
854 1.1 christos if ( offset == 0x84 ) /* address of TM6MD */
855 1.1 christos {
856 1.1 christos /* Fill in first byte of mode */
857 1.10 christos mode_val0 = *(uint8_t *)source;
858 1.1 christos timers->tm6md0 = mode_val0;
859 1.1 christos
860 1.1 christos if ( ( mode_val0 & 0x26 ) != 0 )
861 1.1 christos {
862 1.1 christos hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
863 1.1 christos }
864 1.1 christos }
865 1.1 christos
866 1.1 christos if ( offset == 0x85 || nr_bytes == 2 )
867 1.1 christos {
868 1.1 christos /* Fill in second byte of mode */
869 1.1 christos if ( nr_bytes == 2 )
870 1.1 christos {
871 1.10 christos mode_val1 = *(uint8_t *)source+1;
872 1.1 christos }
873 1.1 christos else
874 1.1 christos {
875 1.10 christos mode_val1 = *(uint8_t *)source;
876 1.1 christos }
877 1.1 christos
878 1.1 christos timers->tm6md1 = mode_val1;
879 1.1 christos
880 1.1 christos if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
881 1.1 christos {
882 1.1 christos hw_abort(me, "Cannot load base reg and start counting simultaneously.");
883 1.1 christos }
884 1.1 christos if ( ( mode_val1 & bits0to2_mask ) != 0 )
885 1.1 christos {
886 1.1 christos hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
887 1.1 christos }
888 1.1 christos }
889 1.1 christos
890 1.1 christos if ( mode_val1 & count_mask )
891 1.1 christos {
892 1.1 christos /* - de-schedule any previous event. */
893 1.1 christos /* - add new event to queue to start counting. */
894 1.1 christos /* - assert that counter == base reg? */
895 1.1 christos
896 1.1 christos div_ratio = timers->tm6ca; /* binary counter for timer 6 */
897 1.1 christos timers->timer[timer_nr].div_ratio = div_ratio;
898 1.1 christos if ( NULL != timers->timer[timer_nr].event )
899 1.1 christos {
900 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
901 1.1 christos timers->timer[timer_nr].event = NULL;
902 1.1 christos }
903 1.1 christos
904 1.1 christos if ( div_ratio > 0 )
905 1.1 christos {
906 1.1 christos /* Set start time. */
907 1.1 christos timers->timer[timer_nr].start = hw_event_queue_time(me);
908 1.1 christos timers->timer[timer_nr].event
909 1.1 christos = hw_event_queue_schedule(me, div_ratio,
910 1.1 christos do_counter6_event,
911 1.10 christos (void *)(uintptr_t)timer_nr);
912 1.1 christos }
913 1.1 christos }
914 1.1 christos else
915 1.1 christos {
916 1.1 christos /* Turn off counting */
917 1.1 christos if ( NULL != timers->timer[timer_nr].event )
918 1.1 christos {
919 1.1 christos hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
920 1.1 christos timers->timer[timer_nr].event = NULL;
921 1.1 christos }
922 1.1 christos }
923 1.1 christos }
924 1.1 christos
925 1.1 christos
926 1.1 christos
927 1.1 christos static void
928 1.1 christos write_special_timer6_reg (struct hw *me,
929 1.1 christos struct mn103tim *timers,
930 1.1 christos int timer_nr,
931 1.1 christos const void *source,
932 1.1 christos unsigned nr_bytes)
933 1.1 christos {
934 1.10 christos uint32_t val;
935 1.1 christos
936 1.1 christos switch (nr_bytes) {
937 1.1 christos case 1:
938 1.1 christos {
939 1.1 christos switch ( timer_nr ) {
940 1.1 christos case TM6MDA:
941 1.10 christos timers->tm6mda = *(uint8_t *)source;
942 1.1 christos break;
943 1.1 christos
944 1.1 christos case TM6MDB:
945 1.10 christos timers->tm6mdb = *(uint8_t *)source;
946 1.1 christos break;
947 1.1 christos
948 1.1 christos case TM6CA:
949 1.10 christos timers->tm6ca = *(uint8_t *)source;
950 1.1 christos break;
951 1.1 christos
952 1.1 christos case TM6CB:
953 1.10 christos timers->tm6cb = *(uint8_t *)source;
954 1.1 christos break;
955 1.1 christos
956 1.1 christos default:
957 1.1 christos break;
958 1.1 christos }
959 1.1 christos break;
960 1.1 christos }
961 1.1 christos
962 1.1 christos case 2:
963 1.1 christos if ( timer_nr == TM6CA )
964 1.1 christos {
965 1.10 christos timers->tm6ca = *(uint16_t *)source;
966 1.1 christos }
967 1.1 christos else if ( timer_nr == TM6CB )
968 1.1 christos {
969 1.10 christos timers->tm6cb = *(uint16_t *)source;
970 1.1 christos }
971 1.1 christos else
972 1.1 christos {
973 1.1 christos hw_abort(me, "bad read size for timer 6 mode A/B register");
974 1.1 christos }
975 1.1 christos break;
976 1.1 christos
977 1.1 christos default:
978 1.1 christos hw_abort(me, "bad read size for timer 6 register");
979 1.1 christos }
980 1.1 christos
981 1.1 christos }
982 1.1 christos
983 1.1 christos
984 1.1 christos static unsigned
985 1.1 christos mn103tim_io_write_buffer (struct hw *me,
986 1.1 christos const void *source,
987 1.1 christos int space,
988 1.1 christos unsigned_word base,
989 1.1 christos unsigned nr_bytes)
990 1.1 christos {
991 1.1 christos struct mn103tim *timers = hw_data (me);
992 1.1 christos enum timer_register_types timer_reg;
993 1.1 christos
994 1.1 christos HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
995 1.10 christos (int) nr_bytes, *(uint32_t *)source));
996 1.1 christos
997 1.1 christos timer_reg = decode_addr (me, timers, base);
998 1.1 christos
999 1.1 christos /* It can be either a mode register, a base register, a binary counter, */
1000 1.1 christos /* or a special timer 6 register. Check in that order. */
1001 1.1 christos if ( timer_reg <= LAST_MODE_REG )
1002 1.1 christos {
1003 1.1 christos if ( timer_reg == 6 )
1004 1.1 christos {
1005 1.1 christos write_tm6md(me, timers, base, source, nr_bytes);
1006 1.1 christos }
1007 1.1 christos else
1008 1.1 christos {
1009 1.1 christos write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
1010 1.1 christos source, nr_bytes);
1011 1.1 christos }
1012 1.1 christos }
1013 1.1 christos else if ( timer_reg <= LAST_BASE_REG )
1014 1.1 christos {
1015 1.1 christos write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
1016 1.1 christos }
1017 1.1 christos else if ( timer_reg <= LAST_COUNTER )
1018 1.1 christos {
1019 1.1 christos hw_abort(me, "cannot write to counter");
1020 1.1 christos }
1021 1.1 christos else if ( timer_reg <= LAST_TIMER_REG )
1022 1.1 christos {
1023 1.1 christos write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
1024 1.1 christos }
1025 1.1 christos else
1026 1.1 christos {
1027 1.1 christos hw_abort(me, "invalid reg type");
1028 1.1 christos }
1029 1.1 christos
1030 1.1 christos return nr_bytes;
1031 1.1 christos }
1032 1.1 christos
1033 1.1 christos
1034 1.1 christos const struct hw_descriptor dv_mn103tim_descriptor[] = {
1035 1.1 christos { "mn103tim", mn103tim_finish, },
1036 1.1 christos { NULL },
1037 1.1 christos };
1038