// Copyright (c) 2007-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\x86\x86utils.cia
//
//
#include <x86.h>
#include <nktest/nkutils.h>
extern "C" {
void __fastcall thread_request_signal(NThread* aThread);
extern TUint64 fcf;
extern TUint32 nfcf;
extern TUint32 nfcfs;
__NAKED__ void __cpu_idle()
{
asm("hlt");
asm("ret");
}
__NAKED__ void __cpu_yield()
{
X86_PAUSE
asm("ret");
}
__NAKED__ TLinAddr __stack_pointer()
{
asm("mov eax, esp");
asm("ret");
}
__NAKED__ TUint32 __cpu_status_reg()
{
asm("pushfd");
asm("pop eax");
asm("ret");
}
__NAKED__ TUint32 __cpu_id()
{
asm("xor eax, eax");
asm("str ax");
asm("ret");
}
__NAKED__ TUint32 __trace_cpu_num()
{
asm("xor eax, eax");
asm("str ax");
asm("sub al, 0x28");
asm("shr al, 3");
asm("ret");
}
TUint64 __NAKED__ fast_counter()
{
asm("rdtsc");
asm("ret");
}
TUint32 __NAKED__ norm_fast_counter()
{
asm("mov ecx, [%a0]": :"i"(&nfcfs));
asm("rdtsc");
asm("shrd eax, edx, cl");
asm("ret");
}
__NAKED__ void nfcfspin(TUint32 aTicks)
{
asm("mov ecx, [%a0]": :"i"(&nfcfs));
asm("push ebx");
asm("mov ebx, [esp+8]");
asm("rdtsc");
asm("shrd eax, edx, cl");
asm("add ebx, eax");
asm("nfcfspin1:");
asm("rdtsc");
asm("shrd eax, edx, cl");
asm("sub eax, ebx");
asm("js nfcfspin1");
asm("pop ebx");
asm("ret");
}
__NAKED__ void fcfspin(TUint64 aTicks)
{
asm("mov ecx, [esp+4]");
asm("push ebx");
asm("mov ebx, [esp+12]");
asm("rdtsc");
asm("add ecx, eax");
asm("adc ebx, edx");
asm("fcfspin1:");
asm("rdtsc");
asm("sub eax, ecx");
asm("sbb edx, ebx");
asm("js fcfspin1");
asm("pop ebx");
asm("ret");
}
__NAKED__ TUint32 set_bit0_if_nonnull(TUint32&)
{
asm("mov ecx, [esp+4]");
asm("mov eax, [ecx]");
asm("xx1:");
asm("cmp eax, 0");
asm("jz short done1");
asm("mov edx, eax");
asm("or edx, 1");
asm("lock cmpxchg [ecx], edx");
asm("jne short xx1");
asm("done1:");
asm("ret");
}
__NAKED__ void flip_bit0(TUint32&)
{
asm("mov ecx, [esp+4]");
asm("lock xor dword ptr [ecx], 1");
asm("ret");
}
__NAKED__ TUint32 swap_out_if_bit0_clear(TUint32&)
{
asm("mov ecx, [esp+4]");
asm("mov eax, [ecx]");
asm("xx2:");
asm("test eax, 1");
asm("jnz short done2");
asm("xor edx, edx");
asm("lock cmpxchg [ecx], edx");
asm("jne short xx2");
asm("done2:");
asm("ret");
}
__NAKED__ TUint32 __eflags()
{
asm("pushfd ");
asm("pop eax ");
asm("ret ");
}
}
__NAKED__ void RequestComplete(NThread* /*aThread*/, NRequestStatus*& /*aStatus*/, TInt /*aValue*/)
{
asm("mov ecx, [esp+8]");
asm("xor eax, eax");
asm("lock xchg eax, [ecx]");
asm("mov edx, [esp+12]");
asm("cmp eax, 0");
asm("jz done3");
asm("mov ecx, [esp+4]");
asm("mov [eax], edx");
asm("call %a0": :"i"(&thread_request_signal));
asm("done3:");
asm("ret");
}