107 lines
3.6 KiB
NASM
107 lines
3.6 KiB
NASM
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;;
|
||
|
;;; Microsoft Research Singularity ARM Bootstrap
|
||
|
;;;
|
||
|
;;; Xscale varient of the cycle counter routines
|
||
|
;;;
|
||
|
|
||
|
|defining ?g_GetCycleCount@Class_Microsoft_Singularity_Isal_Isa@@SA_KXZ| EQU 1
|
||
|
|defining ?g_EnableCycleCounter@Class_Microsoft_Singularity_Isal_Isa@@SAXXZ| EQU 1
|
||
|
|
||
|
include hal.inc
|
||
|
|
||
|
IMPORT |?g_EnableInterrupts@Class_Microsoft_Singularity_Isal_Isa@@SAXXZ|
|
||
|
IMPORT |?g_DisableInterrupts@Class_Microsoft_Singularity_Isal_Isa@@SA_NXZ|
|
||
|
|
||
|
TEXTAREA
|
||
|
|
||
|
CycleCountHi DCD 0 ; storage for upper 32--bits of cycle counter (extended)
|
||
|
|
||
|
;;;
|
||
|
;;; Reset cycle counter
|
||
|
;;;
|
||
|
;;; "void __cdecl ResetCycleCounter(void)"
|
||
|
;;;
|
||
|
LEAF_ENTRY ?ResetCycleCounter@@YAXXZ
|
||
|
mov r1, #0
|
||
|
mrc p14, 0, r1, c0, c0, 0 ; read PMCR
|
||
|
orr r1, r1, #4 ; set C
|
||
|
mcr p14, 0, r1, c0, c0, 0 ; set PMCR
|
||
|
bx lr
|
||
|
LEAF_END
|
||
|
|
||
|
;;;
|
||
|
;;; Check for cycle counter wrap and clean
|
||
|
;;;
|
||
|
;;; "bool __cdecl CycleCounterWrapped(void)"
|
||
|
;;;
|
||
|
LEAF_ENTRY ?CycleCounterWrapped@@YA_NXZ
|
||
|
mov r1, #0
|
||
|
bx lr
|
||
|
LEAF_END
|
||
|
|
||
|
;;;
|
||
|
;;; Enable cycle counter
|
||
|
;;;
|
||
|
;;; "void __cdecl EnableCycleCounter(void)"
|
||
|
;;;
|
||
|
LEAF_ENTRY ?g_EnableCycleCounter@Class_Microsoft_Singularity_Isal_Isa@@SAXXZ
|
||
|
mov r1, #0
|
||
|
mrc p14, 0, r1, c0, c1, 0 ; read PMCR
|
||
|
orr r1, r1, #1 ; set E (enable) bit, disable interrupts
|
||
|
mcr p14, 0, r1, c0, c1, 0 ; write PMCR
|
||
|
bx lr
|
||
|
LEAF_END
|
||
|
|
||
|
;;;
|
||
|
;;; Disable cycle counter
|
||
|
;;;
|
||
|
;;; "void __cdecl DisableCycleCounter(void)"
|
||
|
;;;
|
||
|
LEAF_ENTRY ?DisableCycleCounter@@YAXXZ
|
||
|
mov r1, #0
|
||
|
mrc p14, 0, r1, c0, c1, 0 ; read PMCR
|
||
|
bic r1, r1, #1 ; clear E (enable) bit
|
||
|
mcr p14, 0, r1, c0, c1, 0 ; write PMCR
|
||
|
bx lr
|
||
|
LEAF_END
|
||
|
|
||
|
;;;
|
||
|
;;; "public: static unsigned __int64 __cdecl Class_Microsoft_Singularity_Processor::g_GetCycleCount(void)"
|
||
|
;;;
|
||
|
NESTED_ENTRY ?g_GetCycleCount@Class_Microsoft_Singularity_Isal_Isa@@SA_KXZ
|
||
|
|
||
|
stmfd sp!, {r4,lr}
|
||
|
|
||
|
PROLOG_END
|
||
|
|
||
|
;; Disable interrupts, r0 becomes do_restore
|
||
|
bl |?g_DisableInterrupts@Class_Microsoft_Singularity_Isal_Isa@@SA_NXZ|
|
||
|
mov r2, r0 ; r2 becomes do_restore
|
||
|
|
||
|
;; Increment high bits if wrap has occurred
|
||
|
adr r3, CycleCountHi ; r3 is pointer to hi
|
||
|
ldr r0, [r3] ; r0 is cycle count hi
|
||
|
|
||
|
mrc p14, 0, r1, c5, c1, 0 ; r1 is FLAG
|
||
|
ands r1, r1, #1 ; r1 is CCNT wrapped
|
||
|
|
||
|
mcrne p14, 0, r1, c5, c1, 0 ; clear bit if set
|
||
|
addne r0, r0, r1 ; increment count hi
|
||
|
strne r0, [r3] ; store count hi
|
||
|
mov r3, r0 ; r3 is cycle count hi
|
||
|
mrc p14, 0, r4, c1, c1, 0 ; r4 becomes cycle cnt
|
||
|
|
||
|
;; Restore interrupts
|
||
|
cmp r2, #0
|
||
|
blne |?g_EnableInterrupts@Class_Microsoft_Singularity_Isal_Isa@@SAXXZ|
|
||
|
|
||
|
mov r0, r4 ; r0 is cycle count lo
|
||
|
mov r1, r3 ; r1 is cycle count hi
|
||
|
ldmfd sp!, {r4,lr}
|
||
|
|
||
|
bx lr
|
||
|
NESTED_END
|
||
|
|
||
|
END
|