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