mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@215 b871894f-2f95-9b40-918c-086798483c85
465 lines
14 KiB
C
465 lines
14 KiB
C
/*---------------------------------------------------------------------------*
|
|
Project: CtrBrom - libraries - OS
|
|
File: os_timer.c
|
|
|
|
Copyright 2008 Nintendo. All rights reserved.
|
|
|
|
These coded instructions, statements, and computer programs contain
|
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
|
Company Ltd., and are protected by Federal copyright law. They may
|
|
not be disclosed to third parties or copied or duplicated in any form,
|
|
in whole or in part, without the prior written consent of Nintendo.
|
|
|
|
$Date:: $
|
|
$Rev$
|
|
$Author$
|
|
*---------------------------------------------------------------------------*/
|
|
#include <brom/os.h>
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
#ifdef SDK_ARM9
|
|
#define REG_OS_TMCNT_H_E_MASK REG_OS_TM0CNT_H_E_MASK
|
|
#define REG_OS_TMCNT_H_I_MASK REG_OS_TM0CNT_H_I_MASK
|
|
#define REG_OS_TMCNT_H_CH_MASK REG_OS_TM1CNT_H_CH_MASK
|
|
#endif // SDK_ARM9
|
|
|
|
//---- if OS reserved each timer, bit=1
|
|
static u8 i_osTimerReserved[OS_TIMER_NUM];
|
|
#ifdef SDK_ARM11
|
|
static u8 i_osTimerControl[OS_TIMER_NUM];
|
|
#endif // SDK_ARM11
|
|
|
|
u8 i_osIsTimerReserved(int timerNum);
|
|
void i_osSetTimerReserved(int timerNum);
|
|
void i_osUnsetTimerReserved(int timerNum);
|
|
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osInitTimer
|
|
|
|
Description: Initialize Timers
|
|
|
|
Arguments: None
|
|
|
|
Returns: None
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
void osInitTimer( void )
|
|
{
|
|
static BOOL isInit;
|
|
|
|
if ( isInit == FALSE )
|
|
{
|
|
OSIntrMode intr = osDisableInterrupts();
|
|
|
|
isInit = TRUE;
|
|
|
|
#ifdef SDK_ARM11
|
|
|
|
osStopTimer(OS_TIMER_0);
|
|
osStopTimer(OS_TIMER_1);
|
|
osResetWatchdog();
|
|
osDisableWatchdog();
|
|
|
|
i_osTimerControl[OS_TIMER_0] = 0;
|
|
i_osTimerControl[OS_TIMER_1] = 0;
|
|
|
|
#else // SDK_ARM9
|
|
|
|
osStopTimer64();
|
|
|
|
#endif // SDK_ARM9
|
|
|
|
osRestoreInterrupts( intr );
|
|
}
|
|
}
|
|
|
|
|
|
//================================================================================
|
|
/*---------------------------------------------------------------------------*
|
|
Name: i_osIsTimerReserved
|
|
|
|
Description: check if specified timer is reserved for OS
|
|
|
|
Arguments: timerNum : timerNo (0-3)
|
|
|
|
Returns: non-0 if reserved
|
|
*---------------------------------------------------------------------------*/
|
|
u8 i_osIsTimerReserved( int timer_id )
|
|
{
|
|
return i_osTimerReserved[timer_id];
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: i_osSetTimerReserved
|
|
|
|
Description: set specified timer to reserved for OS
|
|
|
|
Arguments: timerNum : timerNo (0-3)
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void i_osSetTimerReserved( int timer_id )
|
|
{
|
|
i_osTimerReserved[timer_id] = TRUE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: i_osUnsetTimerReserved
|
|
|
|
Description: unset specified timer to reserved for OS
|
|
|
|
Arguments: timerNum : timerNo (0-3)
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void i_osUnsetTimerReserved( int timer_id )
|
|
{
|
|
i_osTimerReserved[timer_id] = FALSE;
|
|
}
|
|
|
|
//================================================================================
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osStartTimer
|
|
|
|
Description: set timer(s) and start
|
|
|
|
Arguments: id timerNo
|
|
count count value to be set to timer
|
|
preScale preScale
|
|
|
|
Returns: None
|
|
*---------------------------------------------------------------------------*/
|
|
#ifdef SDK_ARM11
|
|
//
|
|
// use 1 timer, 16bit counter, timer<id> interrupt occurs by overflow
|
|
//
|
|
void osStartTimer( OSTimer id, OSTimerCount count, OSTimerPrescaler preScale )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_0 <= id && id < OS_TIMER_NUM);
|
|
SDK_ASSERT(2 <= preScale && preScale <= (256*2));
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
|
|
preScale /= 2;
|
|
if ( preScale )
|
|
{
|
|
preScale--;
|
|
}
|
|
|
|
osSetTimerCount(id, count);
|
|
osSetTimerControl(id, REG_OS_TM_CNT_E_MASK | REG_OS_TM_CNT_IT_MASK |
|
|
i_osTimerControl[id] |
|
|
(preScale << REG_OS_TM_CNT_PS_SHIFT));
|
|
}
|
|
|
|
#else // SDK_ARM9
|
|
//
|
|
// use 1 timer, 16bit counter, timer<id> interrupt occurs by overflow
|
|
//
|
|
void osStartTimer( OSTimer id, u16 count, OSTimerPrescaler preScale )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_0 <= id && id < OS_TIMER_NUM);
|
|
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
|
|
osSetTimerCount(id, (u16)~count);
|
|
osSetTimerControl(id, (u16)(REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | preScale));
|
|
}
|
|
|
|
//
|
|
// use 2 timers, 32bit counter, timer<id+1> interrupt occurs by overflow
|
|
//
|
|
void osStartTimer32( OSTimer32 id, u32 count, OSTimerPrescaler preScale )
|
|
{
|
|
SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23);
|
|
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
|
|
|
|
osSetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff));
|
|
osSetTimerCount((OSTimer)id, (u16)(~count & 0xffff));
|
|
|
|
osSetTimerControl((OSTimer)((int)id + 1),
|
|
REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK);
|
|
osSetTimerControl((OSTimer)id, (u16)(REG_OS_TMCNT_H_E_MASK | preScale));
|
|
}
|
|
|
|
//
|
|
// use 3 timers, 48bit counter, timer<id+2> interrupt occurs by overflow
|
|
//
|
|
void osStartTimer48( OSTimer48 id, u64 count, OSTimerPrescaler preScale )
|
|
{
|
|
SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123);
|
|
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
|
|
SDK_ASSERT(!i_osIsTimerReserved(id + 2));
|
|
|
|
osSetTimerCount((OSTimer)((int)id + 2), (u16)((~count >> 32) & 0xffff));
|
|
osSetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff));
|
|
osSetTimerCount((OSTimer)id, (u16)(~count & 0xffff));
|
|
|
|
osSetTimerControl((OSTimer)((int)id + 2),
|
|
REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK);
|
|
osSetTimerControl((OSTimer)((int)id + 1), REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK);
|
|
osSetTimerControl((OSTimer)id, (u16)(REG_OS_TMCNT_H_E_MASK | preScale));
|
|
}
|
|
|
|
//
|
|
// use all 4 timers, 64bit counter, timer3 interrupt occurs by overflow
|
|
//
|
|
void osStartTimer64( u64 count, OSTimerPrescaler preScale )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_0));
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_1));
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_2));
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_3));
|
|
|
|
osSetTimerCount(OS_TIMER_3, (u16)((~count >> 48) & 0xffff));
|
|
osSetTimerCount(OS_TIMER_2, (u16)((~count >> 32) & 0xffff));
|
|
osSetTimerCount(OS_TIMER_1, (u16)((~count >> 16) & 0xffff));
|
|
osSetTimerCount(OS_TIMER_0, (u16)(~count & 0xffff));
|
|
|
|
osSetTimerControl(OS_TIMER_3,
|
|
REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK);
|
|
osSetTimerControl(OS_TIMER_2, REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK);
|
|
osSetTimerControl(OS_TIMER_1, REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK);
|
|
osSetTimerControl(OS_TIMER_0, (u16)(REG_OS_TMCNT_H_E_MASK | preScale));
|
|
}
|
|
|
|
#endif // SDK_ARM9
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: i_osStopTimer
|
|
|
|
Description: stop timer(s)
|
|
|
|
Arguments: id timerNo
|
|
|
|
Returns: None
|
|
*---------------------------------------------------------------------------*/
|
|
//
|
|
// stop a timer
|
|
//
|
|
void osStopTimer( OSTimer id )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_0 <= id && id < OS_TIMER_NUM);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
|
|
osSetTimerControl(id, 0);
|
|
#ifdef SDK_ARM11
|
|
osClearTimerEventFlag(id);
|
|
#endif // SDK_ARM11
|
|
}
|
|
|
|
#ifdef SDK_ARM9
|
|
|
|
//
|
|
// stop 2 timers
|
|
//
|
|
void osStopTimer32( OSTimer32 id )
|
|
{
|
|
SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
|
|
|
|
osStopTimer((OSTimer)((int)id + 1));
|
|
osStopTimer((OSTimer)id);
|
|
}
|
|
|
|
//
|
|
// stop 3 timers
|
|
//
|
|
void i_osStopTimer48( OSTimer48 id )
|
|
{
|
|
SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123);
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(id));
|
|
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
|
|
SDK_ASSERT(!i_osIsTimerReserved(id + 2));
|
|
|
|
osStopTimer((OSTimer)((int)id + 2));
|
|
osStopTimer((OSTimer)((int)id + 1));
|
|
osStopTimer((OSTimer)id);
|
|
}
|
|
|
|
//
|
|
// stop all 4 timers
|
|
//
|
|
void osStopTimer64( void )
|
|
{
|
|
//---- check if system reserved
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_0));
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_1));
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_2));
|
|
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_3));
|
|
|
|
osStopTimer(OS_TIMER_3);
|
|
osStopTimer(OS_TIMER_2);
|
|
osStopTimer(OS_TIMER_1);
|
|
osStopTimer(OS_TIMER_0);
|
|
}
|
|
|
|
#endif // SDK_ARM9
|
|
|
|
#ifdef SDK_ARM11
|
|
#include <brom/code32.h>
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osGetPerfMonitor
|
|
|
|
Description: Get Performance Monitor
|
|
|
|
Arguments: monitorNum : monitorNo (0-2)
|
|
|
|
Returns: count
|
|
*---------------------------------------------------------------------------*/
|
|
asm u32 osGetPerfMonitor( OSMoniter mon )
|
|
{
|
|
cmp r0, #__cpp(OS_MONITOR_1)
|
|
beq FSYM(1)
|
|
cmp r0, #__cpp(OS_MONITOR_2)
|
|
beq FSYM(2)
|
|
mrc p15, 0, r0, c15, c12, 1
|
|
b FSYM(3)
|
|
LSYM(1)
|
|
mrc p15, 0, r0, c15, c12, 2
|
|
b FSYM(3)
|
|
LSYM(2)
|
|
mrc p15, 0, r0, c15, c12, 3
|
|
LSYM(3)
|
|
bx lr
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osSetPerfMonitor
|
|
|
|
Description: Set Performance Monitor
|
|
|
|
Arguments: monitorNum : monitorNo (0-2)
|
|
count
|
|
|
|
Returns: previous count
|
|
*---------------------------------------------------------------------------*/
|
|
asm u32 osSetPerfMonitor( OSMoniter mon, u32 count )
|
|
{
|
|
cmp r0, #__cpp(OS_MONITOR_1)
|
|
beq FSYM(1)
|
|
cmp r0, #__cpp(OS_MONITOR_2)
|
|
beq FSYM(2)
|
|
mrc p15, 0, r0, c15, c12, 1
|
|
mcr p15, 0, r1, c15, c12, 1
|
|
b FSYM(3)
|
|
LSYM(1)
|
|
mrc p15, 0, r0, c15, c12, 1
|
|
mcr p15, 0, r1, c15, c12, 1
|
|
b FSYM(3)
|
|
LSYM(2)
|
|
mrc p15, 0, r0, c15, c12, 1
|
|
mcr p15, 0, r1, c15, c12, 1
|
|
LSYM(3)
|
|
bx lr
|
|
}
|
|
|
|
#include <brom/codereset.h>
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osIsEnableTimerReload
|
|
|
|
Description: check if specified timer is enabling reload
|
|
|
|
Arguments: timerNum : timerNo (0-1)
|
|
|
|
Returns: non-0 if repeated
|
|
*---------------------------------------------------------------------------*/
|
|
u8 osIsEnableTimerReload( OSTimer timer_id )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_0 <= id && id < OS_TIMER_NUM);
|
|
return i_osTimerControl[timer_id] & REG_OS_WD_CNT_RLD_MASK ? TRUE : FALSE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osEnableTimerReload
|
|
|
|
Description: enable specified timer to reload
|
|
|
|
Arguments: timerNum : timerNo (0-1)
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void osEnableTimerReload( OSTimer timer_id )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_0 <= id && id < OS_TIMER_NUM);
|
|
|
|
OSIntrMode intr = osDisableInterrupts();
|
|
|
|
i_osTimerControl[timer_id] |= REG_OS_WD_CNT_RLD_MASK;
|
|
|
|
osRestoreInterrupts( intr );
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osDisableTimerReload
|
|
|
|
Description: disable specified timer to reload
|
|
|
|
Arguments: timerNum : timerNo (0-1)
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void osDisableTimerReload( OSTimer timer_id )
|
|
{
|
|
SDK_ASSERT(OS_TIMER_0 <= id && id < OS_TIMER_NUM);
|
|
|
|
OSIntrMode intr = osDisableInterrupts();
|
|
|
|
i_osTimerControl[timer_id] &= ~REG_OS_WD_CNT_RLD_MASK;
|
|
|
|
osRestoreInterrupts( intr );
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osResetWatchdog
|
|
|
|
Description: Reset Watchdog
|
|
|
|
Arguments: None
|
|
|
|
Returns: None
|
|
*---------------------------------------------------------------------------*/
|
|
void osResetWatchdog( void )
|
|
{
|
|
reg_OS_WD_RST = TRUE;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osDisableWatchdog
|
|
|
|
Description: Disable Watchdog
|
|
|
|
Arguments: None
|
|
|
|
Returns: None
|
|
*---------------------------------------------------------------------------*/
|
|
void osDisableWatchdog( void )
|
|
{
|
|
OSIntrMode intr = osDisableInterrupts();
|
|
|
|
reg_OS_WD_DIS = OSi_WATCHDOG_DISABLE_CODE_0;
|
|
reg_OS_WD_DIS = OSi_WATCHDOG_DISABLE_CODE_1;
|
|
|
|
osRestoreInterrupts( intr );
|
|
}
|
|
|
|
#endif // SDK_ARM11
|
|
|