4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-08 18:19:08 +08:00
newlib-cygwin/libgloss/arc/arc-timer.c
Vladimir Isaev 6d5331054e arc: libgloss: Introduce hostlink interface
There is a special interface built in ARC simulators (such as
nSIM) called MetaWare hostlink IO which can be used to implement
system calls. This commit adds support for this interface to the
ARC port of libgloss.

Here is an example of using this interface:

    $ arc-elf32-gcc -mcpu=hs -specs=hl.specs main.c -o main
    $ nsimdrv -tcf $NSIM_HOME/etc/tcf/templates/hs48_full.tcf main
    Hello, World!

Signed-off-by: Vladimir Isaev <vvisaev@gmail.com>
2024-05-22 14:25:44 -04:00

130 lines
3.1 KiB
C

/*
* arc-timer.c -- provide API for ARC timers.
*
* Copyright (c) 2024 Synopsys Inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*
*/
#define ARC_TIM_BUILD 0x75
#define ARC_TIM_BUILD_VER_MASK 0x00FF
#define ARC_TIM_BUILD_TIM0_FL 0x0100
#define ARC_TIM_BUILD_TIM1_FL 0x0200
#define ARC_TIM_COUNT0 0x21
#define ARC_TIM_CONTROL0 0x22
#define ARC_TIM_LIMIT0 0x23
#define ARC_TIM_COUNT1 0x100
#define ARC_TIM_CONTROL1 0x101
#define ARC_TIM_LIMIT1 0x102
#define ARC_TIM_CONTROL_NH_FL 0x0002
/* Timer used by '_default' functions. */
const unsigned int arc_timer_default = 0;
/* Check if given timer exists. */
static int
_arc_timer_present (unsigned int tim)
{
unsigned int bcr = __builtin_arc_lr (ARC_TIM_BUILD);
unsigned int ver = bcr & ARC_TIM_BUILD_VER_MASK;
if (ver == 0)
return 0;
else if (ver == 1)
return 1;
else if (tim == 0)
return ((bcr & ARC_TIM_BUILD_TIM0_FL) != 0);
else if (tim == 1)
return ((bcr & ARC_TIM_BUILD_TIM1_FL) != 0);
else
return 0;
}
/* Get raw value of a given timer. */
static unsigned int
_arc_timer_read (unsigned int tim)
{
if (_arc_timer_present (tim))
{
if (tim == 0)
return __builtin_arc_lr (ARC_TIM_COUNT0);
else if (tim == 1)
return __builtin_arc_lr (ARC_TIM_COUNT1);
}
return 0;
}
/*
* Set default values to a given timer.
* Defaults: Not Halted bit is set, limit is 0xFFFFFFFF, count set to 0.
*/
static void
_arc_timer_reset (unsigned int tim)
{
unsigned int ctrl, tim_control, tim_count, tim_limit;
if (_arc_timer_present (tim))
{
if (tim == 0)
{
tim_control = ARC_TIM_CONTROL0;
tim_count = ARC_TIM_COUNT0;
tim_limit = ARC_TIM_LIMIT0;
}
else if (tim == 1)
{
tim_control = ARC_TIM_CONTROL1;
tim_count = ARC_TIM_COUNT1;
tim_limit = ARC_TIM_LIMIT1;
}
else
{
return;
}
ctrl = __builtin_arc_lr (tim_control);
/* Disable timer interrupt when programming. */
__builtin_arc_sr (0, tim_control);
/* Default limit is 24-bit, increase it to 32-bit. */
__builtin_arc_sr (0xFFFFFFFF, tim_limit);
/* Set NH bit to count only when processor is running. */
__builtin_arc_sr (ctrl | ARC_TIM_CONTROL_NH_FL, tim_control);
__builtin_arc_sr (0, tim_count);
}
}
/* Check if arc_timer_default exists. */
int
_arc_timer_default_present (void)
{
return _arc_timer_present (arc_timer_default);
}
/* Read arc_timer_default value. */
unsigned int
_arc_timer_default_read (void)
{
return _arc_timer_read (arc_timer_default);
}
/* Reset arc_timer_default. */
void
_arc_timer_default_reset (void)
{
_arc_timer_reset (arc_timer_default);
}