kerneltest/e32test/nkernsa/arm/armutils.cia
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 0 a41df078684a
child 43 c1f20ce4abcf
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// e32test\nkernsa\arm\armutils.cia
// 
//

#include <arm.h>
#include <nktest/nkutils.h>
#include <e32cia.h>

#ifdef __SMP__
#include <arm_tmr.h>
#endif

extern "C" {

void thread_request_signal(NThread* aThread);

extern TUint64 fcf;
extern TUint32 nfcf;
extern TUint32 nfcfs;

__NAKED__ void __cpu_idle()
	{
	ARM_WFI;
	__JUMP(,lr);
	}

__NAKED__ void __cpu_yield()
	{
	ARM_YIELD;
	__JUMP(,lr);
	}

__NAKED__ TLinAddr __stack_pointer()
	{
	asm("mov	r0, sp ");
	__JUMP(,lr);
	}

__NAKED__ TUint32 __cpu_status_reg()
	{
	asm("mrs	r0, cpsr ");
	__JUMP(,lr);
	}

__NAKED__ TUint32 __cpu_id()
	{
	asm("mrc	p15, 0, r0, c0, c0, 5 ");
	__JUMP(,lr);
	}

__NAKED__ TUint32 __trace_cpu_num()
	{
	asm("mrc	p15, 0, r0, c0, c0, 5 ");
	asm("and	r0, r0, #15 ");
	__JUMP(,lr);
	}

__NAKED__ TUint32 __get_rwno_tid()
	{
	GET_RWNO_TID(,r0);
	__JUMP(,lr);
	}

__NAKED__ TUint32 __get_static_data()
	{
	asm("ldr	r0, 1f ");
	asm("ldr	r0, [r0] ");
	__JUMP(,lr);
	asm("1:		");
	asm(".word	%a0" : : "i" ((TInt)&TheScheduler));
	}

#ifdef __SMP__
__NAKED__ TUint32 __get_local_timer_address()
	{
	GET_RWNO_TID(,r0);
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
	asm("nop ");
	asm("nop ");
	asm("nop ");
	__JUMP(,lr);
	}

__NAKED__ TUint32 __get_local_timer_count()
	{
	GET_RWNO_TID(,r0);
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r0, [r1, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
	asm("cmp	r0, #0 ");
	__JUMP(,lr);
	}

__NAKED__ TUint32 __set_local_timer_count()
	{
	GET_RWNO_TID(,r0);
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r0, [r1, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
	asm("str	r0, [r1, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
	__JUMP(,lr);
	}

__NAKED__ TUint32 __swp_local_timer_count()
	{
	GET_RWNO_TID(,r0);
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
	asm("nop ");
	asm("nop ");
	asm("nop ");
	asm("ldr	r0, [r1, #%a0]!" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
	asm("swp	r0, r0, [r1] ");
	__JUMP(,lr);
	}
#endif

TUint32 __NAKED__ norm_fast_counter()
	{
	asm("str	lr, [sp, #-4]! ");
	asm("bl "	CSM_CFUNC(fast_counter));
	asm("ldr	r2, __nfcfs ");
	asm("ldr	r2, [r2] ");
	asm("rsb	r3, r2, #32 ");
	asm("mov	r0, r0, lsr r2 ");
	asm("orr	r0, r0, r1, lsl r3 ");
	__POPRET("");

	asm("__nfcfs: ");
	asm(".word nfcfs ");
	}

__NAKED__ TUint32 set_bit0_if_nonnull(TUint32&)
	{
	__DATA_MEMORY_BARRIER_Z__(r12);
	asm("mov	r3, r0 ");
	asm("1: ");
	LDREX(0,3);
	asm("movs	r1, r0 ");
	asm("beq	2f ");
	asm("orr	r1, r1, #1 ");
	STREX(12,1,3);
	asm("cmp	r12, #0 ");
	asm("bne	1b ");
	asm("2: ");
	__DATA_MEMORY_BARRIER_Z__(r12);
	__JUMP(,lr);
	}

__NAKED__ void flip_bit0(TUint32&)
	{
	__DATA_MEMORY_BARRIER_Z__(r12);
	asm("1: ");
	LDREX(1,0);
	asm("eor	r1, r1, #1 ");
	STREX(12,1,0);
	asm("cmp	r12, #0 ");
	asm("bne	1b ");
	__DATA_MEMORY_BARRIER__(r12);
	__JUMP(,lr);
	}

__NAKED__ TUint32 swap_out_if_bit0_clear(TUint32&)
	{
	__DATA_MEMORY_BARRIER_Z__(r12);
	asm("mov	r3, r0 ");
	asm("1: ");
	LDREX(0,3);
	asm("tst	r0, #1 ");
	asm("bne	2f ");
	STREX(2,12,3);
	asm("cmp	r2, #0 ");
	asm("bne	1b ");
	asm("2: ");
	__DATA_MEMORY_BARRIER_Z__(r12);
	__JUMP(,lr);
	}

__NAKED__ TUint32 __cpsr()
	{
	asm("mrs	r0, cpsr ");
	__JUMP(,lr);
	}
}

__NAKED__ void RequestComplete(NThread* /*aThread*/, NRequestStatus*& /*aStatus*/, TInt /*aValue*/)
	{
	__DATA_MEMORY_BARRIER_Z__(r12);
	asm("str	lr, [sp, #-4]! ");
	asm("1: ");
	LDREX(3,1);
	STREX(14,12,1);
	asm("cmp	r14, #0 ");
	asm("bne	1b ");
	asm("cmp	r3, #0 ");
	asm("ldr	lr, [sp], #4 ");
	asm("strne	r2, [r3] ");
	asm("bne "	CSM_CFUNC(thread_request_signal));
	__JUMP(,lr);
	}