// --------------------------------------------------------------------------- void HAL_Time_Sleep_MicroSeconds(UINT32 uSec) { GLOBAL_LOCK(irq); UINT32 current = HAL_Time_CurrentTicks(); UINT32 maxDiff = CPU_MicrosecondsToTicks(uSec); if(maxDiff <= CPU_SLEEP_USEC_FIXED_OVERHEAD_CLOCKS) maxDiff = 0; else maxDiff -= CPU_SLEEP_USEC_FIXED_OVERHEAD_CLOCKS; // Subtract overhead while(((INT32)(HAL_Time_CurrentTicks() - current)) <= maxDiff); }
void __section(SectionForFlashOperations) HAL_Time_Sleep_MicroSeconds( UINT32 uSec ) { GLOBAL_LOCK(irq); UINT32 current = HAL_Time_CurrentTicks(); UINT32 maxDiff = CPU_MicrosecondsToTicks( uSec ); if(maxDiff <= STM32_SLEEP_USEC_FIXED_OVERHEAD_CLOCKS) maxDiff = 0; else maxDiff -= STM32_SLEEP_USEC_FIXED_OVERHEAD_CLOCKS; while(((INT32)(HAL_Time_CurrentTicks() - current)) <= maxDiff); }
void HAL_COMPLETION::DequeueAndExec() { NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); GLOBAL_LOCK(irq); HAL_COMPLETION* ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); HAL_COMPLETION* ptrNext = (HAL_COMPLETION*)ptr->Next(); // waitforevents does not have an associated completion, therefore we need to verify // than their is a next completion and that the current one has expired. if(ptrNext) { ASSERT(ptr->EventTimeTicks <= HAL_Time_CurrentTicks()); Events_Set(SYSTEM_EVENT_FLAG_SYSTEM_TIMER); ptr->Unlink(); // // In case there's no other request to serve, set the next interrupt to be 356 years since last powerup (@25kHz). // HAL_Time_SetCompare( ptrNext->Next() ? ptrNext->EventTimeTicks : HAL_Completion_IdleValue ); #if defined(_DEBUG) ptr->EventTimeTicks = 0; #endif // defined(_DEBUG) // let the ISR turn on interrupts, if it needs to ptr->Execute(); } }
void HAL_COMPLETION::EnqueueTicks( UINT64 EventTimeTicks ) { NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); ASSERT(EventTimeTicks != 0); GLOBAL_LOCK(irq); this->EventTimeTicks = EventTimeTicks; #if defined(_DEBUG) this->Start_RTC_Ticks = HAL_Time_CurrentTicks(); #endif HAL_COMPLETION* ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); HAL_COMPLETION* ptrNext; for(;(ptrNext = (HAL_COMPLETION*)ptr->Next()); ptr = ptrNext) { if(EventTimeTicks < ptr->EventTimeTicks) break; } g_HAL_Completion_List.InsertBeforeNode( ptr, this ); if(this == g_HAL_Completion_List.FirstNode()) { HAL_Time_SetCompare( EventTimeTicks ); } }
void HAL_COMPLETION::EnqueueDelta64( UINT64 uSecFromNow ) { NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); // grab time first to be closest to now as possible from when this function was called UINT64 Now = HAL_Time_CurrentTicks(); UINT64 EventTimeTicks = CPU_MicrosecondsToTicks( uSecFromNow ); EnqueueTicks( Now + EventTimeTicks ); }
void HAL_Time_SetCompare( UINT64 CompareValue ) { GLOBAL_LOCK(irq); g_nextEvent = CompareValue; TIM2->CCR1 = (UINT16)CompareValue; // compare to low bits if (HAL_Time_CurrentTicks() >= CompareValue) { // missed event // trigger immediate interrupt TIM2->EGR = TIM_EGR_CC1G; // trigger compare1 event } }
// --------------------------------------------------------------------------- void HAL_Time_SetCompare(UINT64 CompareValue) { GLOBAL_LOCK(irq); g_nextEvent = CompareValue; SYSTIMER->MR[0] = (UINT32)CompareValue; SYSTIMER->MCR |= 1; // Enable match interrupt if (HAL_Time_CurrentTicks() >= CompareValue) { // Missed event? // If so, trigger immediate interrupt NVIC->STIR = SYSTIMER_IRQn; } }
// --------------------------------------------------------------------------- void systimer_handler(void* param) { GLOBAL_LOCK(irq); SYSTIMER->IR = 1; // Clear interrupt if (HAL_Time_CurrentTicks() >= g_nextEvent) { // Past event time? // Handle it and schedule the next one, if there is one HAL_COMPLETION::DequeueAndExec(); } }
void Timer_Interrupt (void* param) // timer2 compare event { INTERRUPT_START TIM2->SR = ~TIM_SR_CC1IF; // reset interrupt flag if (HAL_Time_CurrentTicks() >= g_nextEvent) { // handle event HAL_COMPLETION::DequeueAndExec(); // this also schedules the next one, if there is one } INTERRUPT_END }
void AT91_GPIO_Driver::PIN_ISR_DESCRIPTOR::HandleDebounce( BOOL edge ) { ASSERT_IRQ_MUST_BE_OFF(); m_completion.Abort(); UINT8 statusMask = edge ? c_Status_AllowHighEdge : c_Status_AllowLowEdge ; if(m_status & statusMask) { m_completion.EnqueueTicks( HAL_Time_CurrentTicks() + g_AT91_GPIO_Driver.m_DebounceTicks ); } }
static void GenerateNewSslSeed() { UINT8 signature[ 128 ]; UINT8 IVPtr[ BLOCK_SIZE ]; BOOL success; UINT64 data[ 2 ] = { ++g_SSL_SeedData.Config.SeedCounter, HAL_Time_CurrentTicks() }; memset( &IVPtr[ 0 ], 0, sizeof(IVPtr) ); success = Crypto_Encrypt( (BYTE*)&g_SSL_SeedData.Config.SslSeedKey[ 0 ], (UINT8*)IVPtr, sizeof(IVPtr), (BYTE*)&data, sizeof(data), signature, sizeof(signature) ) == CRYPTO_SUCCESS ? S_OK : CLR_E_FAIL; ASSERT(success); ssl_rand_seed(signature, sizeof(signature)); if(!g_SSL_SeedData.m_completion.IsLinked()) { g_SSL_SeedData.m_completion.EnqueueDelta( 5 * 1000000ul ); // 5 seconds } }
CK_RV NetMFCrypto::GenerateKeyPair(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate , CK_ULONG ulPublicCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateCount, CK_OBJECT_HANDLE_PTR phPublicKey , CK_OBJECT_HANDLE_PTR phPrivateKey) { if(pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN) return CKR_MECHANISM_INVALID; KeySeed ks; UINT16 d0; UINT16 d1; UINT8 last = 0; for(int i=0; i<SEED_SIZE_BYTES; i++) { last = (HAL_Time_CurrentTicks() % 256) ^ (last<<3); ks.Seed[i] = last; } if(Crypto_CreateZenithKey((BYTE *)&ks, &d0, &d1) != CRYPTO_SUCCESS) { return false; } ks.delta[0] = d0; ks.delta[1] = d1; RSAKey* pPrivate = &s_RSAKeys[s_RSAKeyIndex]; *phPrivateKey = s_RSAKeyIndex++; RSAKey* pPublic = &s_RSAKeys[s_RSAKeyIndex]; *phPublicKey = s_RSAKeyIndex++; Crypto_GeneratePrivateKey(&ks, pPrivate); Crypto_PublicKeyFromPrivate(pPrivate, pPublic); return CKR_OK; }
void ApplicationEntryPoint() { INT32 timeout = 20000; // 20 second timeout bool enterBootMode = false; // crypto API needs to allocate memory. Initialize simple heap for it. UINT8* BaseAddress; UINT32 SizeInBytes; HeapLocation ( BaseAddress, SizeInBytes ); SimpleHeap_Initialize( BaseAddress, SizeInBytes ); g_eng.Initialize( HalSystemConfig.DebuggerPorts[ 0 ] ); // internal reset and stop check enterBootMode = g_PrimaryConfigManager.IsBootLoaderRequired( timeout ); // ODM defined method to enter bootloader mode if(!enterBootMode) { enterBootMode = WaitForTinyBooterUpload( timeout ); } if(!enterBootMode) { if(!g_eng.EnumerateAndLaunch()) { timeout = -1; enterBootMode = true; } } if(enterBootMode) { LCD_Clear(); hal_fprintf( STREAM_LCD, "TinyBooter v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION); hal_fprintf( STREAM_LCD, "%s Build Date:\r\n\t%s %s\r\n", HalName, __DATE__, __TIME__ ); DebuggerPort_Initialize( HalSystemConfig.DebuggerPorts[ 0 ] ); TinyBooter_OnStateChange( State_EnterBooterMode, NULL ); DebuggerPort_Flush( HalSystemConfig.DebugTextPort ); hal_printf( "TinyBooter v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION); hal_printf( "%s Build Date: %s %s\r\n", HalName, __DATE__, __TIME__ ); #if defined(__GNUC__) hal_printf("GNU Compiler version %d\r\n", __GNUC__); #elif defined(_ARC) hal_printf("ARC Compiler version %d\r\n", _ARCVER); #elif defined(__ADSPBLACKFIN__) hal_printf( "Blackfin Compiler version %d\r\n", __VERSIONNUM__ ); #elif defined(__RENESAS__) hal_printf( "Renesas Compiler version %d\r\n", __RENESAS_VERSION__ ); #else hal_printf( "ARM Compiler version %d\r\n", __ARMCC_VERSION ); #endif DebuggerPort_Flush( HalSystemConfig.DebugTextPort ); // // Send "presence" ping. // { CLR_DBG_Commands::Monitor_Ping cmd; cmd.m_source = CLR_DBG_Commands::Monitor_Ping::c_Ping_Source_TinyBooter; g_eng.m_controller.SendProtocolMessage( CLR_DBG_Commands::c_Monitor_Ping, WP_Flags::c_NonCritical, sizeof(cmd), (UINT8*)&cmd ); } UINT64 ticksStart = HAL_Time_CurrentTicks(); // // Wait for somebody to press a button; if no button press comes in, lauch the image // do { const UINT32 c_EventsMask = SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_USB_IN | SYSTEM_EVENT_FLAG_BUTTON; UINT32 events = ::Events_WaitForEvents( c_EventsMask, timeout ); if(events != 0) { Events_Clear( events ); } if(events & SYSTEM_EVENT_FLAG_BUTTON) { TinyBooter_OnStateChange( State_ButtonPress, (void*)&timeout ); } if(events & (SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_USB_IN)) { g_eng.ProcessCommands(); } if(LOADER_ENGINE_ISFLAGSET(&g_eng, Loader_Engine::c_LoaderEngineFlag_ValidConnection)) { LOADER_ENGINE_CLEARFLAG(&g_eng, Loader_Engine::c_LoaderEngineFlag_ValidConnection); TinyBooter_OnStateChange( State_ValidCommunication, (void*)&timeout ); ticksStart = HAL_Time_CurrentTicks(); } else if((timeout != -1) && (HAL_Time_CurrentTicks()-ticksStart) > CPU_MillisecondsToTicks((UINT32)timeout)) { TinyBooter_OnStateChange( State_Timeout, NULL ); g_eng.EnumerateAndLaunch(); } } while(true); } ::CPU_Reset(); }
INT64 HAL_Time_CurrentTime() { return CPU_TicksToTime( HAL_Time_CurrentTicks() ); }
bool WP_Message::Process() { UINT8* buf = (UINT8*)&m_header; int len; while(true) { switch(m_rxState) { case ReceiveState::Idle: return true; case ReceiveState::Initialize: Release(); m_rxState = ReceiveState::WaitingForHeader; m_pos = (UINT8*)&m_header; m_size = sizeof(m_header); break; case ReceiveState::WaitingForHeader: if(m_parent->m_phy->ReceiveBytes( m_parent->m_state, m_pos, m_size ) == false) return true; // // Synch to the start of a message. // while(true) { len = sizeof(m_header) - m_size; if(len <= 0) break; size_t lenCmp = __min( len, sizeof(m_header.m_signature) ); if(memcmp( &m_header, MARKER_DEBUGGER_V1, lenCmp ) == 0) break; if(memcmp( &m_header, MARKER_PACKET_V1 , lenCmp ) == 0) break; memmove( &buf[ 0 ], &buf[ 1 ], len-1 ); m_pos--; m_size++; } if(len >= sizeof(m_header.m_signature)) { m_rxState = ReceiveState::ReadingHeader; } break; case ReceiveState::ReadingHeader: if(m_parent->m_phy->ReceiveBytes( m_parent->m_state, m_pos, m_size ) == false) return true; if(m_size == 0) { m_rxState = ReceiveState::CompleteHeader; } break; case ReceiveState::CompleteHeader: { bool fBadPacket=true; if( VerifyHeader() ) { #if defined(BIG_ENDIAN) SwapEndian(); #endif if ( m_parent->m_app->ProcessHeader( m_parent->m_state, this ) ) { fBadPacket = false; if(m_header.m_size) { if(m_payload == NULL) // Bad, no buffer... { m_rxState = ReceiveState::Initialize; } else { m_payloadTicks = HAL_Time_CurrentTicks(); m_rxState = ReceiveState::ReadingPayload; m_pos = (UINT8*)m_payload; m_size = m_header.m_size; } } else { m_rxState = ReceiveState::CompletePayload; } } } if ( fBadPacket ) { if((m_header.m_flags & WP_Flags::c_NonCritical) == 0) { ReplyBadPacket( WP_Flags::c_BadHeader ); } m_rxState = ReceiveState::Initialize; } } break; case ReceiveState::ReadingPayload: { UINT64 curTicks = HAL_Time_CurrentTicks(); // If the time between consecutive payload bytes exceeds the timeout threshold then assume that // the rest of the payload is not coming. Reinitialize to synch on the next header. if(HAL_Time_TicksToTime( curTicks - m_payloadTicks ) < (UINT64)c_PayloadTimeout) { m_payloadTicks = curTicks; if(m_parent->m_phy->ReceiveBytes( m_parent->m_state, m_pos, m_size ) == false) return true; if(m_size == 0) { m_rxState = ReceiveState::CompletePayload; } } else { m_rxState = ReceiveState::Initialize; } } break; case ReceiveState::CompletePayload: if(VerifyPayload() == true) { m_parent->m_app->ProcessPayload( m_parent->m_state, this ); } else { ReplyBadPacket( WP_Flags::c_BadPayload ); } m_rxState = ReceiveState::Initialize; break; default: return false; } } }
/// Remove this method once dependency on this are gone. UINT64 Time_CurrentTicks() { return HAL_Time_CurrentTicks(); }
UINT32 Events_WaitForEvents( UINT32 sleepLevel, UINT32 WakeupSystemEvents, UINT32 Timeout_Milliseconds ) { NATIVE_PROFILE_PAL_EVENTS(); // do NOT call this routine with interrupts disabled, // as we can die here, since flags are only set in ISRs ASSERT_IRQ_MUST_BE_ON(); // schedule an interrupt for this far in the future // timeout is in milliseconds, convert to Sleep Counts UINT64 CountsRemaining = CPU_MillisecondsToTicks( Timeout_Milliseconds ); #if defined(HAL_PROFILE_ENABLED) Events_WaitForEvents_Calls++; #endif { GLOBAL_LOCK(irq); // then check to make sure the events haven't happened on the way in // we must do this before we sleep! UINT64 Expire = HAL_Time_CurrentTicks() + CountsRemaining; BOOL RunContinuations = TRUE; while(true) { UINT32 Events = Events_MaskedRead( WakeupSystemEvents ); if(Events) return Events; if(Expire <= HAL_Time_CurrentTicks()) return 0; // first check and possibly run any continuations // but only if we have slept after stalling if(RunContinuations && !SystemState_QueryNoLock( SYSTEM_STATE_NO_CONTINUATIONS )) { // restore interrupts before running a continuation irq.Release(); // if we stall on time, don't check again until after we sleep RunContinuations = HAL_CONTINUATION::Dequeue_And_Execute(); irq.Acquire(); } else { // try stalled continuations again after sleeping RunContinuations = TRUE; //lcd_printf("\fSleep=%6lld ", CountsRemaining); //lcd_printf( "Events=%08x", Events_MaskedRead(0xffffffff)); #if defined(HAL_TIMEWARP) if(s_timewarp_lastButton < HAL_Time_TicksToTime( HAL_Time_CurrentTicks() )) { CountsRemaining = Expire - HAL_Time_CurrentTicks(); if(CountsRemaining > 0) { s_timewarp_compensate += (CountsRemaining * 10*1000*1000) / CPU_TicksPerSecond(); } return 0; } #endif ASSERT_IRQ_MUST_BE_OFF(); HAL_COMPLETION::WaitForInterrupts( Expire, sleepLevel, WakeupSystemEvents ); irq.Probe(); // See if we have to serve any pending interrupts. } } } }
BOOL USART_Driver::AddCharToRxBuffer( int ComPortNum, char c ) { ASSERT_IRQ_MUST_BE_OFF(); if((ComPortNum < 0) || (ComPortNum >= TOTAL_USART_PORT)) return FALSE; HAL_USART_STATE& State = Hal_Usart_State[ComPortNum]; if (USART_FLAG_STATE(State, HAL_USART_STATE::c_TX_SWFLOW_CTRL)) { switch( c ) { case XOFF: State.TicksStartTxXOFF = HAL_Time_CurrentTicks(); CLEAR_USART_FLAG(State, HAL_USART_STATE::c_TX_XON_STATE); return TRUE; case XON: SET_USART_FLAG(State, HAL_USART_STATE::c_TX_XON_STATE); return TRUE; } } { GLOBAL_LOCK(irq); UINT8* Dst = State.RxQueue.Push(); if(Dst) { *Dst = c; if( State.RxQueue.NumberOfElements() >= State.RxBufferHighWaterMark ) { if( USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_SWFLOW_CTRL) ) { // Set our XOFF state SendXOFF( ComPortNum, XOFF_FLAG_FULL ); } if( USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_HWFLOW_CTRL) ) { // Hold off receiving characters (should pull HW handshake automatically) CPU_USART_RxBufferFullInterruptEnable(ComPortNum, FALSE); } } } else { SetEvent( ComPortNum, USART_EVENT_ERROR_RXOVER ); #if !defined(BUILD_RTM) lcd_printf("\fBuffer OVFLW\r\n"); hal_printf("Buffer OVFLW\r\n"); #endif return FALSE; } } SetEvent( ComPortNum, USART_EVENT_DATA_CHARS ); Events_Set( SYSTEM_EVENT_FLAG_COM_IN ); return TRUE; }
int USART_Driver::Write( int ComPortNum, const char* Data, size_t size ) { NATIVE_PROFILE_PAL_COM(); int totWrite = 0; const char* ptr = Data; int j; if((ComPortNum < 0) || (ComPortNum >= TOTAL_USART_PORT)) {ASSERT(FALSE); return -1;} if(0 == size ) return -1; if(NULL == Data ) {ASSERT(FALSE); return -1;} HAL_USART_STATE& State = Hal_Usart_State[ComPortNum]; if (IS_POWERSAVE_ENABLED(State) || (!IS_USART_INITIALIZED(State)))return -1; if (USART_FLAG_STATE(State, HAL_USART_STATE::c_TX_SWFLOW_CTRL) && (!USART_FLAG_STATE(State, HAL_USART_STATE::c_TX_XON_STATE))) { // A timeout is used for XOFF incase the XOFF value was lost or never sent. // USART_TX_XOFF_TIMEOUT_TICKS is defined in the platform selector file if((USART_TX_XOFF_TIMEOUT_INFINITE != USART_TX_XOFF_TIMEOUT_TICKS ) && (HAL_Time_CurrentTicks() - State.TicksStartTxXOFF) > USART_TX_XOFF_TIMEOUT_TICKS) { SET_USART_FLAG(State, HAL_USART_STATE::c_TX_XON_STATE); } else { return 0; } } // loop twice if needed because of our implementaition of a circular buffered QUEUE for(j=0; (j < 2) && (totWrite < size); j++) { // Keep interrupts off to keep queue access atomic GLOBAL_LOCK(irq); UINT8 *Dst; size_t nWritten; nWritten = size - totWrite; Dst = State.TxQueue.Push( nWritten ); if( Dst != NULL ) { memcpy(Dst, ptr, nWritten); // Move characters to transmit queue from buffer totWrite += nWritten; ptr += nWritten; } else if(!USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_HWFLOW_CTRL)) { SetEvent( ComPortNum, USART_EVENT_ERROR_TXFULL ); break; } } // we need to be atomic on PowerSave/USART_TxBufferEmptyInterruptEnable // since it gets set/cleared from ISR, and disables the clock, but // USART_TxBufferEmptyInterruptEnable turns the clock back on! // We don't want to turn on the USART clock if in power save mode { GLOBAL_LOCK(irq); if(size && !IS_POWERSAVE_ENABLED(State)) { // if we added chars, enable interrupts so characters will actually start flowing // we could do this early, then we race each iteration, and could cause a stall, // so we do this once to be efficient in the common case (buffer has room for all chars) CPU_USART_TxBufferEmptyInterruptEnable( ComPortNum, TRUE ); } } return totWrite; }