[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

mips64orion _CPU_ISR_Set_level



joel at oarcorp.com's Mail:

> _CPU_ISR_Set_level does what it has to as best it can for a port. :)
Attached you find a version of _CPU_ISR_{Get,Set}_level() which maps RTEMS
levels 0..8 to the respective MIPS CPU interrupt masks (all enabled, SwInt0
disabled, SwInt0+SwInt1 disabled, ..., all interrupts disabled).

I integrated these (along with some other things) in RTEMS 3.6.0 but
unfortunately didn't have the time to cleanup my sources in order to submit
the changes.  If it matters:  We run RTEMS 3.6.0 on a Galileo 4 Eval Board
w/ a R4600/R4700 CPU.

> The i386 just recognizes on and off as well.  THe set level implementation
> for the i386 is this:
If I understand things correctly, the RTEMS kernel requires only
``all interrupts on/off'' and support for different interrupt levels is only
for the benefit of applications!?

Regards
	\franz
--
Franz G. Fischer -------------------------------- Franz.Fischer at lpr.ei.tum.de
Lab for Process Control and Real-Time Systems, TU Muenchen,  D-80290 Muenchen
-------------- next part --------------
/*PAGE
 *
 *  _CPU_ISR_Get_level
 *  _CPU_ISR_Set_level
 *
 *  Get/set interrupt level, converting from the CPU's interrupt
 *  level (or on this CPU mask) representation to/from RTEMS' levels
 *  (0..8 in our case)
 */
 
/*
 * map RTEMS interrupt levels 0..8 (0..16, because of
 * CPU_MODES_INTERRUPT_MASK = 0x0f) to the respective MIPS CPU
 * interrupt mask bits.  */
const unsigned32	_CPU_imask_table[16] = {
    (SR_IMASK0|SR_IE),		/* level 0, all enabled, 0xff */
    (SR_IMASK1|SR_IE),
    (SR_IMASK2|SR_IE),
    (SR_IMASK3|SR_IE),
    (SR_IMASK4|SR_IE),
    (SR_IMASK5|SR_IE),
    (SR_IMASK6|SR_IE),
    (SR_IMASK7|SR_IE),
    (SR_IMASK8|SR_IE),		/* level 8, all disabled, 0x00 */
    (SR_IMASK8|SR_IE),
    (SR_IMASK8|SR_IE),
    (SR_IMASK8|SR_IE),
    (SR_IMASK8|SR_IE),
    (SR_IMASK8|SR_IE),
    (SR_IMASK8|SR_IE),
    (SR_IMASK8|SR_IE)
};

/* map (shifted) interrupt mask bits to (RTEMS) interrupt level 0 (all
 * enabled) .. 8 (all disabled)  */
const unsigned char	_CPU_ilevel_table[256] = {
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x00..0x0f */
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x10..0x1f */
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x20..0x2f */
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x30..0x3f */

    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x40..0x4f */
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x50..0x5f */
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x60..0x6f */
    8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,		/* 0x70..0x7f */

    7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7,		/* 0x80..0x8f */
    7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7,		/* 0x90..0x9f */
    7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7,		/* 0xa0..0xaf */
    7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7,		/* 0xb0..0xbf */

    6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6,		/* 0xc0..0xcf */
    6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6,		/* 0xd0..0xdf */
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,		/* 0xe0..0xef */
    4,4,4,4, 4,4,4,4, 3,3,3,3, 2,2,1,0,		/* 0xf0..0xff */
};

unsigned32 _CPU_ISR_Get_level( void )
{
  /*
   *  This routine returns the current rtems interrupt level.
    imask = ((c0_sr | _CPU_global_imask) & SR_IMASK) >> SR_IMASKSHIFT;
   */
    unsigned32	c0_sr, imask;

    mips_get_sr(c0_sr);
    imask = (c0_sr & SR_IMASK) >> SR_IMASKSHIFT;
    return(_CPU_ilevel_table[(c0_sr & SR_IMASK) >> SR_IMASKSHIFT]);
}

void _CPU_ISR_Set_level( unsigned32 level )
{
  /*
   *  This routine returns the current rtems interrupt level.
   */
    unsigned32	c0_sr, imask;

    mips_get_sr(c0_sr);
    c0_sr &= ~SR_IMASK;
    imask = _CPU_imask_table[level & CPU_MODES_INTERRUPT_MASK];
    c0_sr |= imask;
    mips_set_sr(c0_sr);
    return;
}