diff -r 000000000000 -r 96e5fb8b040d kernel/eka/drivers/trace/arm/btracex_impl.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/drivers/trace/arm/btracex_impl.cia Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,296 @@ +// 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: +// e32\drivers\trace\arm\btracex_impl.cia +// +// + + // adjust a0 for timestamp(s) +#ifdef BTRACE_INCLUDE_TIMESTAMPS +#ifdef USE_TIMESTAMP2 + asm("add r0, r0, #8 "); + asm("orr r0, r0, #%a0" : : "i" ((TInt)((BTrace::ETimestampPresent | BTrace::ETimestamp2Present)<= then done (3f==update_offsets) + asm("cmp r1, r3 "); // cmp tail,newHead + asm("bhi 3f "); // if > the done (3f==update_offsets) + asm("ldr r0, [r5, #%a0]" : : "i" _FOFF(TBTraceBuffer,iWrap)); // r0 = wrap + asm("tst r14, #%a0" : : "i" ((TInt)RBTrace::EFreeRunning)); + asm("beq trace_dropped "); // if we aren't in freerunning mode, drop the trace + asm("cmp r3, r7 "); // cmp newHead,end + asm("cmplo r3, r0 "); // cmp newHead,wrap + asm("ldrlob r1, [r12, r3, lsr #2] ");// r1 = word offset to next record after newHead + asm("mov r9, #0 "); // iRequestDataSize=0 + asm("addlo r1, r3, r1, lsl #2 "); // tail = newHead + offset to next record + asm("cmplo r1, r7 "); // cmp tail,end + asm("cmplo r1, r0 "); // cmp tail,wrap + asm("movhs r1, r6 "); // tail = start + + asm("2: "); // overwrite + asm("ldr r0, [r5, r1] "); // r1 = first word of record at new tail +#ifndef __SMP__ + // On single processor iTail can't have been updated since interrupts are off here + asm("orr r1, r1, #1 "); + asm("str r1, [r5, #%a0]" : : "i" _FOFF(TBTraceBuffer,iTail)); // update tail + asm("bic r1, r1, #1 "); +#endif + asm("orr r0, r0, #%a0" : : "i" ((TInt)(BTrace::EMissingRecord<<(BTrace::EFlagsIndex*8)))); + asm("str r0, [r5, r1] "); // set 'missing record' flag in next record to be read +#ifdef __SMP__ + // attempt to atomically update iTail + asm("9: "); + asm("add r5, r5, #%a0" : : "i" _FOFF(TBTraceBuffer,iTail)); // r5=&user_buffer.iTail + asm("orr r1, r1, #1 "); + LDREX(0,5); + asm("cmp r0, r2 "); // iTail = orig_tail ? + asm("movne r2, r0 "); // if not, orig_tail = iTail + asm("bne 8b "); // and go round again + STREX(0,1,5); // else try to update iTail with tail|1 + asm("cmp r0, #0 "); + asm("bne 9b "); + __DATA_MEMORY_BARRIER__(r0); // ensure update to iTail observed before overwrites + asm("sub r5, r5, #%a0" : : "i" _FOFF(TBTraceBuffer,iTail)); // r5=&user_buffer.iTail +#endif + + asm("3: "); // update_offsets + asm("sub r9, r9, r4 "); // iRequestDataSize -= size + asm("str r3, [r10, #%a0]" : : "i" _FOFF(TBTraceBufferK,iHead)); // OK to do this here since only used kernel side + asm("str r9, [r10, #%a0]" : : "i" _FOFF(TBTraceBufferK,iRequestDataSize)); + + asm("add r5, r5, r8 "); // r5 = address+head = destination to store trace + asm("mov r4, r4, asr #2 "); // r4 = size/4 = number of words in trace record + asm("add r11, r12, r8, asr #2 "); // r11 = address to store record sizes + // unused regs are now r0 r1 r2 r3 r6 r7 r8 r9 r12 r14 + + asm("ldr r14, [r10,#%a0]" : : "i" _FOFF(TBTraceBufferK,iDropped)); + asm("ldmia sp, {r6-r9} "); // r6 = aHeader, r7 = aHeader2, r8 = aContext, r9 = a1 + asm("cmp r14, #0 "); + asm("movne r14, #0 "); + asm("strne r14, [r10,#%a0]" : : "i" _FOFF(TBTraceBufferK,iDropped)); + asm("orrne r6, r6, #%a0" : : "i" ((TInt)(BTrace::EMissingRecord<