#include "sim-main.h"
#include "hw-main.h"
+#include "sim-assert.h"
/* DEVICE
TM6MDB,
TM6CA,
TM6CB,
+ LAST_TIMER_REG = TM6BC,
};
/* Don't include timer 6 because it's handled specially. */
#define NR_8BIT_TIMERS 4
#define NR_16BIT_TIMERS 2
-#define NR_TIMERS 6
+#define NR_REG_TIMERS 6 /* Exclude timer 6 - it's handled specially. */
+#define NR_TIMERS 7
-typedef struct _mn10300_timer {
- unsigned32 div_ratio, start, base;
+typedef struct _mn10300_timer_regs {
+ unsigned32 base;
unsigned8 mode;
+} mn10300_timer_regs;
+
+typedef struct _mn10300_timer {
+ unsigned32 div_ratio, start;
struct hw_event *event;
} mn10300_timer;
struct mn103tim {
struct mn103tim_block block[NR_TIMER_BLOCKS];
+ mn10300_timer_regs reg[NR_REG_TIMERS];
mn10300_timer timer[NR_TIMERS];
/* treat timer 6 registers specially. */
- unsigned16 tm6md, tm6bc, tm6mca, tm6mcb;
+ unsigned16 tm6md0, tm6md1, tm6bc, tm6ca, tm6cb;
unsigned8 tm6mda, tm6mdb; /* compare/capture mode regs for timer 6 */
- struct hw_event *event6;
};
/* output port ID's */
};
#define bits2to5_mask 0x3c
+#define bits0to2_mask 0x07
#define load_mask 0x40
#define count_mask 0x80
#define count_and_load_mask (load_mask | count_mask)
attach_mn103tim_regs (me, timers);
/* Initialize the timers */
+ for ( i=0; i < NR_REG_TIMERS; ++i )
+ {
+ timers->reg[i].mode = 0x00;
+ timers->reg[i].base = 0;
+ }
for ( i=0; i < NR_TIMERS; ++i )
{
timers->timer[i].event = NULL;
- timers->timer[i].mode = 0x00;
- timers->timer[i].base = 0;
timers->timer[i].div_ratio = 0;
timers->timer[i].start = 0;
}
- timers->tm6md = 0x0000;
+ timers->tm6md0 = 0x00;
+ timers->tm6md1 = 0x00;
timers->tm6bc = 0x0000;
- timers->tm6mca = 0x0000;
- timers->tm6mcb = 0x0000;
+ timers->tm6ca = 0x0000;
+ timers->tm6cb = 0x0000;
timers->tm6mda = 0x00;
timers->tm6mdb = 0x00;
}
case 0x23: return TM3BC;
case 0x80: return TM4MD;
case 0x82: return TM5MD;
- case 0x84: return TM6MD;
+ case 0x84: /* fall through */
+ case 0x85: return TM6MD;
case 0x90: return TM4BR;
case 0x92: return TM5BR;
case 0xa0: return TM4BC;
{
case 1:
/* Accessing 1 byte is ok for all mode registers. */
- *(unsigned8*)dest = timers->timer[timer_nr].mode;
+ if ( timer_nr == 6 )
+ {
+ *(unsigned8*)dest = timers->tm6md0;
+ }
+ else
+ {
+ *(unsigned8*)dest = timers->reg[timer_nr].mode;
+ }
break;
case 2:
if ( timer_nr == 6 )
{
- *(unsigned16 *)dest = timers->tm6md;
+ *(unsigned16 *)dest = (timers->tm6md0 << 8) | timers->tm6md1;
}
else if ( timer_nr == 0 || timer_nr == 2 )
{
- val16 = (timers->timer[timer_nr].mode << 8)
- | timers->timer[timer_nr+1].mode;
+ val16 = (timers->reg[timer_nr].mode << 8)
+ | timers->reg[timer_nr+1].mode;
*(unsigned16*)dest = val16;
}
else
case 4:
if ( timer_nr == 0 )
{
- val32 = (timers->timer[0].mode << 24 )
- | (timers->timer[1].mode << 16)
- | (timers->timer[2].mode << 8)
- | timers->timer[3].mode;
+ val32 = (timers->reg[0].mode << 24 )
+ | (timers->reg[1].mode << 16)
+ | (timers->reg[2].mode << 8)
+ | timers->reg[3].mode;
*(unsigned32*)dest = val32;
}
else
/* Reading 1 byte is ok for all registers. */
if ( timer_nr < NR_8BIT_TIMERS )
{
- *(unsigned8*)dest = timers->timer[timer_nr].base;
+ *(unsigned8*)dest = timers->reg[timer_nr].base;
}
break;
{
if ( timer_nr < NR_8BIT_TIMERS )
{
- val16 = (timers->timer[timer_nr].base<<8)
- | timers->timer[timer_nr+1].base;
+ val16 = (timers->reg[timer_nr].base<<8)
+ | timers->reg[timer_nr+1].base;
}
else
{
- val16 = timers->timer[timer_nr].base;
+ val16 = timers->reg[timer_nr].base;
}
*(unsigned16*)dest = val16;
}
case 4:
if ( timer_nr == 0 )
{
- val32 = (timers->timer[0].base << 24) | (timers->timer[1].base << 16)
- | (timers->timer[2].base << 8) | timers->timer[3].base;
+ val32 = (timers->reg[0].base << 24) | (timers->reg[1].base << 16)
+ | (timers->reg[2].base << 8) | timers->reg[3].base;
*(unsigned32*)dest = val32;
}
else if ( timer_nr == 4 )
{
- val32 = (timers->timer[4].base << 16) | timers->timer[5].base;
+ val32 = (timers->reg[4].base << 16) | timers->reg[5].base;
*(unsigned32*)dest = val32;
}
else
if ( NULL == timers->timer[timer_nr].event )
{
/* Timer is not counting, use value in base register. */
- val = timers->timer[timer_nr].base;
+ if ( timer_nr == 6 )
+ {
+ val = 0; /* timer 6 is an up counter */
+ }
+ else
+ {
+ val = timers->reg[timer_nr].base;
+ }
}
else
{
- /* ticks left = start time + div ratio - curr time */
- /* Cannot use base register because it can be written during counting and it
- doesn't affect counter until underflow occurs. */
-
- val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
- - hw_event_queue_time(me);
+ if ( timer_nr == 6 ) /* timer 6 is an up counter. */
+ {
+ val = hw_event_queue_time(me) - timers->timer[timer_nr].start;
+ }
+ else
+ {
+ /* ticks left = start time + div ratio - curr time */
+ /* Cannot use base register because it can be written during counting and it
+ doesn't affect counter until underflow occurs. */
+
+ val = timers->timer[timer_nr].start + timers->timer[timer_nr].div_ratio
+ - hw_event_queue_time(me);
+ }
}
switch (nr_bytes) {
}
+static void
+read_special_timer6_reg (struct hw *me,
+ struct mn103tim *timers,
+ int timer_nr,
+ void *dest,
+ unsigned nr_bytes)
+{
+ unsigned32 val;
+
+ switch (nr_bytes) {
+ case 1:
+ {
+ switch ( timer_nr ) {
+ case TM6MDA:
+ *(unsigned8 *)dest = timers->tm6mda;
+ break;
+
+ case TM6MDB:
+ *(unsigned8 *)dest = timers->tm6mdb;
+ break;
+
+ case TM6CA:
+ *(unsigned8 *)dest = timers->tm6ca;
+ break;
+
+ case TM6CB:
+ *(unsigned8 *)dest = timers->tm6cb;
+ break;
+
+ default:
+ }
+ break;
+ }
+
+ case 2:
+ if ( timer_nr == TM6CA )
+ {
+ *(unsigned16 *)dest = timers->tm6ca;
+ }
+ else if ( timer_nr == TM6CB )
+ {
+ *(unsigned16 *)dest = timers->tm6cb;
+ }
+ else
+ {
+ hw_abort(me, "bad read size for timer 6 mode A/B register");
+ }
+ break;
+
+ default:
+ hw_abort(me, "bad read size for timer 6 register");
+ }
+
+}
+
+
static unsigned
mn103tim_io_read_buffer (struct hw *me,
void *dest,
timer_reg = decode_addr (me, timers, base);
- /* It can be either a mode register, a base register or a binary counter. */
- /* Check in that order. */
+ /* It can be either a mode register, a base register, a binary counter, */
+ /* or a special timer 6 register. Check in that order. */
if ( timer_reg >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
{
read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
{
read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
}
+ else if ( timer_reg <= LAST_TIMER_REG )
+ {
+ read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
+ }
else
{
hw_abort(me, "invalid timer register address.");
{
struct mn103tim *timers = hw_data(me);
int timer_nr = (int) data;
+ int next_timer;
/* Check if counting is still enabled. */
- if ( (timers->timer[timer_nr].mode & count_mask) != 0 )
+ if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
{
/* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
- hw_port_event (me, timer_nr /*uflow_port[timer_nr]*/, 1 /* level */);
- /* Schedule next timeout. */
+ /* Port event occurs on port of last cascaded timer. */
+ /* This works across timer range from 0 to NR_REG_TIMERS because */
+ /* the first 16 bit timer (timer 4) is not allowed to be set as */
+ /* a cascading timer. */
+ for ( next_timer = timer_nr+1; next_timer < NR_REG_TIMERS; ++next_timer )
+ {
+ if ( (timers->reg[next_timer].mode & clock_mask) != clk_cascaded )
+ {
+ break;
+ }
+ }
+ hw_port_event (me, next_timer-1, 1);
+ /* Schedule next timeout. */
timers->timer[timer_nr].start = hw_event_queue_time(me);
- /* FIX: Check if div_ ratio has changed and if it's now 0. */
+ /* FIX: Check if div_ratio has changed and if it's now 0. */
timers->timer[timer_nr].event
= hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
do_counter_event, (void *)timer_nr);
}
+ else
+ {
+ timers->timer[timer_nr].event = NULL;
+ }
+
+}
+
+
+static void
+do_counter6_event (struct hw *me,
+ void *data)
+{
+ struct mn103tim *timers = hw_data(me);
+ int timer_nr = (int) data;
+ int next_timer;
+
+ /* Check if counting is still enabled. */
+ if ( (timers->reg[timer_nr].mode & count_mask) != 0 )
+ {
+ /* Generate an interrupt for the timer underflow (TIMERn_UFLOW). */
+ hw_port_event (me, timer_nr, 1);
+
+ /* Schedule next timeout. */
+ timers->timer[timer_nr].start = hw_event_queue_time(me);
+ /* FIX: Check if div_ratio has changed and if it's now 0. */
+ timers->timer[timer_nr].event
+ = hw_event_queue_schedule (me, timers->timer[timer_nr].div_ratio,
+ do_counter6_event, (void *)timer_nr);
+ }
+ else
+ {
+ timers->timer[timer_nr].event = NULL;
+ }
}
unsigned i;
const unsigned8 *buf8 = source;
const unsigned16 *buf16 = source;
- unsigned8 mode_val;
/* If TMnCNE == 0 (counting is off), writing to the base register
(TMnBR) causes a simultaneous write to the counter reg (TMnBC).
underflow occurs. Since the counter register is not explicitly
maintained, this functionality is handled in read_counter. */
- mode_val = timers->timer[timer_nr].mode;
-
/* Check nr_bytes: write of 1, 2 or 4 bytes allowed depending on timer. */
switch ( nr_bytes )
{
case 1:
/* Storing 1 byte is ok for all registers. */
- timers->timer[timer_nr].base = buf8[0];
+ timers->reg[timer_nr].base = buf8[0];
break;
case 2:
{
if ( timer_nr < NR_8BIT_TIMERS )
{
- timers->timer[timer_nr].base = buf8[0];
- timers->timer[timer_nr+1].base = buf8[1];
+ timers->reg[timer_nr].base = buf8[0];
+ timers->reg[timer_nr+1].base = buf8[1];
}
else
{
- timers->timer[timer_nr].base = buf16[0];
+ timers->reg[timer_nr].base = buf16[0];
}
}
break;
case 4:
if ( timer_nr == 0 )
{
- ASSERT(0);
- timers->timer[0].base = buf8[0];
- timers->timer[1].base = buf8[1];
- timers->timer[2].base = buf8[2];
- timers->timer[3].base = buf8[3];
+ timers->reg[0].base = buf8[0];
+ timers->reg[1].base = buf8[1];
+ timers->reg[2].base = buf8[2];
+ timers->reg[3].base = buf8[3];
}
else if ( timer_nr == 4 )
{
- timers->timer[4].base = buf16[0];
- timers->timer[5].base = buf16[1];
+ timers->reg[4].base = buf16[0];
+ timers->reg[5].base = buf16[1];
}
else
{
}
static void
-write_8bit_mode_reg (struct hw *me,
- struct mn103tim *timers,
- int timer_nr,
- const void *source,
- unsigned nr_bytes)
- /* for timers 0 to 3 */
+write_mode_reg (struct hw *me,
+ struct mn103tim *timers,
+ int timer_nr,
+ const void *source,
+ unsigned nr_bytes)
+ /* for timers 0 to 5 */
{
unsigned i;
unsigned8 mode_val, next_mode_val;
}
mode_val = *(unsigned8 *)source;
- timers->timer[timer_nr].mode = mode_val;
+ timers->reg[timer_nr].mode = mode_val;
if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
{
{
hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
}
-
+
if ( mode_val & count_mask )
{
/* - de-schedule any previous event. */
/* For cascaded timers, */
if ( (mode_val & clock_mask) == clk_cascaded )
{
- if ( timer_nr == 0 )
+ if ( timer_nr == 0 || timer_nr == 4 )
{
- hw_abort(me, "Timer 0 cannot be cascaded.");
+ hw_abort(me, "Timer %d cannot be cascaded.", timer_nr);
}
}
else
{
- div_ratio = timers->timer[timer_nr].base;
+ div_ratio = timers->reg[timer_nr].base;
/* Check for cascading. */
- next_mode_val = timers->timer[timer_nr+1].mode;
- if ( ( next_mode_val & clock_mask ) == clk_cascaded )
+ if ( timer_nr < NR_8BIT_TIMERS )
{
- /* Check that CNE is on. */
- if ( ( next_mode_val & count_mask ) == 0 )
+ for ( i = timer_nr + 1; i <= 3; ++i )
{
- hw_abort (me, "cascaded timer not ready for counting");
+ next_mode_val = timers->reg[i].mode;
+ if ( ( next_mode_val & clock_mask ) == clk_cascaded )
+ {
+ /* Check that CNE is on. */
+ if ( ( next_mode_val & count_mask ) == 0 )
+ {
+ hw_abort (me, "cascaded timer not ready for counting");
+ }
+ ASSERT(timers->timer[i].event == NULL);
+ ASSERT(timers->timer[i].div_ratio == 0);
+ div_ratio = div_ratio
+ | (timers->reg[i].base << (8*(i-timer_nr)));
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Mode register for a 16 bit timer */
+ next_mode_val = timers->reg[timer_nr+1].mode;
+ if ( ( next_mode_val & clock_mask ) == clk_cascaded )
+ {
+ /* Check that CNE is on. */
+ if ( ( next_mode_val & count_mask ) == 0 )
+ {
+ hw_abort (me, "cascaded timer not ready for counting");
+ }
+ ASSERT(timers->timer[timer_nr+1].event == NULL);
+ ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
+ div_ratio = div_ratio | (timers->reg[timer_nr+1].base << 16);
}
- ASSERT(timers->timer[timer_nr+1].event == NULL);
- ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
- div_ratio = div_ratio | (timers->timer[timer_nr+1].base << 8);
}
timers->timer[timer_nr].div_ratio = div_ratio;
{
/* Set start time. */
timers->timer[timer_nr].start = hw_event_queue_time(me);
-
timers->timer[timer_nr].event
= hw_event_queue_schedule(me, div_ratio,
do_counter_event,
/* Turn off counting */
if ( NULL != timers->timer[timer_nr].event )
{
- ASSERT((timers->timer[timer_nr].mode & clock_mask) != clk_cascaded);
+ ASSERT((timers->reg[timer_nr].mode & clock_mask) != clk_cascaded);
hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
timers->timer[timer_nr].event = NULL;
}
else
{
- if ( (timers->timer[timer_nr].mode & clock_mask) == clk_cascaded )
+ if ( (timers->reg[timer_nr].mode & clock_mask) == clk_cascaded )
{
ASSERT(timers->timer[timer_nr].event == NULL);
}
}
static void
-write_16bit_mode_reg (struct hw *me,
- struct mn103tim *timers,
- int timer_nr,
- const void *source,
- unsigned nr_bytes)
- /* for timers 4 and 5, not 6 */
+write_tm6md (struct hw *me,
+ struct mn103tim *timers,
+ unsigned_word address,
+ const void *source,
+ unsigned nr_bytes)
{
- unsigned i;
- unsigned8 mode_val, next_mode_val;
+ unsigned8 mode_val0 = 0x00, mode_val1 = 0x00;
unsigned32 div_ratio;
+ int timer_nr = 6;
- if ( nr_bytes != 1 )
+ unsigned_word offset = address - timers->block[0].base;
+
+ if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 )
{
- hw_abort (me, "bad write size of %d bytes to TM%dMD.", nr_bytes, timer_nr);
+ hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes);
}
- mode_val = *(unsigned8 *)source;
- timers->timer[timer_nr].mode = mode_val;
-
- if ( ( mode_val & count_and_load_mask ) == count_and_load_mask )
+ if ( offset == 0x84 ) /* address of TM6MD */
{
- hw_abort(me, "Cannot load base reg and start counting simultaneously.");
+ /* Fill in first byte of mode */
+ mode_val0 = *(unsigned8 *)source;
+ timers->tm6md0 = mode_val0;
+
+ if ( ( mode_val0 & 0x26 ) != 0 )
+ {
+ hw_abort(me, "Cannot write to bits 5, 3, and 2 of TM6MD");
+ }
}
- if ( ( mode_val & bits2to5_mask ) != 0 )
+
+ if ( offset == 0x85 || nr_bytes == 2 )
{
- hw_abort(me, "Cannot write to bits 2 to 5 of mode register");
+ /* Fill in second byte of mode */
+ if ( nr_bytes == 2 )
+ {
+ mode_val1 = *(unsigned8 *)source+1;
+ }
+ else
+ {
+ mode_val1 = *(unsigned8 *)source;
+ }
+
+ timers->tm6md1 = mode_val1;
+
+ if ( ( mode_val1 & count_and_load_mask ) == count_and_load_mask )
+ {
+ hw_abort(me, "Cannot load base reg and start counting simultaneously.");
+ }
+ if ( ( mode_val1 & bits0to2_mask ) != 0 )
+ {
+ hw_abort(me, "Cannot write to bits 8 to 10 of TM6MD");
+ }
}
-
- if ( mode_val & count_mask )
+ if ( mode_val1 & count_mask )
{
/* - de-schedule any previous event. */
/* - add new event to queue to start counting. */
/* - assert that counter == base reg? */
- /* For cascaded timers, */
- if ( (mode_val & clock_mask) == clk_cascaded )
+ div_ratio = timers->tm6ca; /* binary counter for timer 6 */
+ timers->timer[timer_nr].div_ratio = div_ratio;
+ if ( NULL != timers->timer[timer_nr].event )
{
- if ( timer_nr == 4 )
- {
- hw_abort(me, "Timer 4 cannot be cascaded.");
- }
+ hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
+ timers->timer[timer_nr].event = NULL;
}
- else
- {
- div_ratio = timers->timer[timer_nr].base;
-
- /* Check for cascading. */
- next_mode_val = timers->timer[timer_nr+1].mode;
- if ( ( next_mode_val & clock_mask ) == clk_cascaded )
- {
- /* Check that CNE is on. */
- if ( ( next_mode_val & count_mask ) == 0 )
- {
- hw_abort (me, "cascaded timer not ready for counting");
- }
- ASSERT(timers->timer[timer_nr+1].event == NULL);
- ASSERT(timers->timer[timer_nr+1].div_ratio == 0);
- div_ratio = div_ratio | (timers->timer[timer_nr+1].base << 16);
- }
- timers->timer[timer_nr].div_ratio = div_ratio;
-
- if ( NULL != timers->timer[timer_nr].event )
- {
- hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
- timers->timer[timer_nr].event = NULL;
- }
-
- if ( div_ratio > 0 )
- {
- /* Set start time. */
- timers->timer[timer_nr].start = hw_event_queue_time(me);
-
- timers->timer[timer_nr].event
- = hw_event_queue_schedule(me, div_ratio, do_counter_event,
- (void *)(timer_nr));
- }
+ if ( div_ratio > 0 )
+ {
+ /* Set start time. */
+ timers->timer[timer_nr].start = hw_event_queue_time(me);
+ timers->timer[timer_nr].event
+ = hw_event_queue_schedule(me, div_ratio,
+ do_counter6_event,
+ (void *)(timer_nr));
}
}
else
/* Turn off counting */
if ( NULL != timers->timer[timer_nr].event )
{
- ASSERT((timers->timer[timer_nr].mode & clock_mask) != clk_cascaded);
hw_event_queue_deschedule (me, timers->timer[timer_nr].event);
timers->timer[timer_nr].event = NULL;
}
- else
- {
- if ( (timers->timer[timer_nr].mode & clock_mask) == clk_cascaded )
- {
- ASSERT(timers->timer[timer_nr].event == NULL);
- }
- }
+ }
+}
+
+
+
+static void
+write_special_timer6_reg (struct hw *me,
+ struct mn103tim *timers,
+ int timer_nr,
+ const void *source,
+ unsigned nr_bytes)
+{
+ unsigned32 val;
+
+ switch (nr_bytes) {
+ case 1:
+ {
+ switch ( timer_nr ) {
+ case TM6MDA:
+ timers->tm6mda = *(unsigned8 *)source;
+ break;
+
+ case TM6MDB:
+ timers->tm6mdb = *(unsigned8 *)source;
+ break;
+
+ case TM6CA:
+ timers->tm6ca = *(unsigned8 *)source;
+ break;
+
+ case TM6CB:
+ timers->tm6cb = *(unsigned8 *)source;
+ break;
+ default:
+ }
+ break;
}
+
+ case 2:
+ if ( timer_nr == TM6CA )
+ {
+ timers->tm6ca = *(unsigned16 *)source;
+ }
+ else if ( timer_nr == TM6CB )
+ {
+ timers->tm6cb = *(unsigned16 *)source;
+ }
+ else
+ {
+ hw_abort(me, "bad read size for timer 6 mode A/B register");
+ }
+ break;
+ default:
+ hw_abort(me, "bad read size for timer 6 register");
+ }
+
}
+
static unsigned
mn103tim_io_write_buffer (struct hw *me,
const void *source,
timer_reg = decode_addr (me, timers, base);
- /* It can be either a mode register, a base register or a binary counter. */
- /* Check in that order. */
+ /* It can be either a mode register, a base register, a binary counter, */
+ /* or a special timer 6 register. Check in that order. */
if ( timer_reg <= LAST_MODE_REG )
{
- if ( timer_reg > 3 )
+ if ( timer_reg == 6 )
{
- write_16bit_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
- source, nr_bytes);
+ write_tm6md(me, timers, base, source, nr_bytes);
}
else
{
- write_8bit_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
- source, nr_bytes);
+ write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
+ source, nr_bytes);
}
}
else if ( timer_reg <= LAST_BASE_REG )
{
hw_abort(me, "cannot write to counter");
}
+ else if ( timer_reg <= LAST_TIMER_REG )
+ {
+ write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
+ }
else
{
hw_abort(me, "invalid reg type");