123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /*++
- Copyright (c) 2012 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- archsup.S
- Abstract:
- This module implements ARMv7 processor architecture features not
- implementable in C.
- Author:
- Evan Green 11-Aug-2012
- Environment:
- Kernel mode
- --*/
- //
- // ------------------------------------------------------------------ Includes
- //
- #include <minoca/kernel/arm.inc>
- //
- // --------------------------------------------------------------- Definitions
- //
- //
- // ---------------------------------------------------------------------- Code
- //
- ASSEMBLY_FILE_HEADER
- //
- // VOID
- // ArCleanEntireCache (
- // VOID
- // )
- //
- /*++
- Routine Description:
- This routine cleans the entire data cache.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- FUNCTION ArCleanEntireCache
- stmdb %sp!, {%r4-%r11} @ Save non-volatile registers.
- mrc p15, 1, %r0, c0, c0, 1 @ Read CLIDR into R0.
- ands %r3, %r0, #0x7000000 @
- mov %r3, %r3, LSR #23 @ Cache level value (naturally aligned).
- beq ArCleanEntireCacheEnd @
- mov %r10, #0 @
- ArCleanEntireCacheLoop1:
- add %r2, %r10, %r10, LSR #1 @ Work out 3 x cache level.
- mov %r1, %r0, LSR %r2 @ Bottom 3 bits are the Cache Type for
- and %r1, %r1, #7 @ this level. Get those 3 bits.
- cmp %r1, #2 @ Check to see if there's no cache or
- blt ArCleanEntireCacheSkip @ only instruction cache at this level.
- mcr p15, 2, %r10, c0, c0, 0 @ Write CSSELR from R10.
- ISB @ ISB to sync the change to CCSIDR.
- mrc p15, 1, %r1, c0, c0, 0 @ Read current CCSIDR
- and %r2, %r1, #7 @ Extract the line length field.
- add %r2, %r2, #4 @ Add 4 for the line length offset
- ldr %r4, =0x3FF @ (log2 16 bytes).
- ands %r4, %r4, %r1, LSR #3 @ R4 is the max number on the way size
- @ (right aligned).
- clz %r5, %r4 @ R5 is the bit position of way size
- @ increment.
- mov %r9, %r4 @ R9 is the working copy of the max way
- @ size (right aligned).
- ArCleanEntireCacheLoop2:
- ldr %r7, =0x00007FFF @
- ands %r7, %r7, %r1, LSR #13 @ R7 is the max number of the index size
- @ (right aligned).
- ArCleanEntireCacheLoop3:
- lsl %r11, %r9, %r5 @ Factor in the way number and cache
- orr %r11, %r10, %r11 @ number into R11.
- lsl %r4, %r7, %r2 @ Factor in the
- orr %r11, %r11, %r4 @ index number.
- mcr p15, 0, %r11, c7, c10, 2 @ DCCSW, clean by set/way.
- subs %r7, %r7, #1 @ Decrement the index.
- bge ArCleanEntireCacheLoop3 @
- subs %r9, %r9, #1 @ Decrement the way number.
- bge ArCleanEntireCacheLoop2 @
- ArCleanEntireCacheSkip:
- add %r10, %r10, #2 @ Increment the cache number.
- cmp %r3, %r10
- bgt ArCleanEntireCacheLoop1
- ArCleanEntireCacheEnd:
- mcr p15, 0, %r0, c7, c5, 0 @ Write to ICIALLU
- ldmia %sp!, {%r4-%r11} @ Restore non-volatile registers.
- DSB @ Data Synchronization barrier.
- bx %lr
- END_FUNCTION ArCleanEntireCache
- //
- // VOID
- // ArCleanInvalidateEntireCache (
- // VOID
- // )
- //
- /*++
- Routine Description:
- This routine cleans and invalidates the entire data cache.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- FUNCTION ArCleanInvalidateEntireCache
- stmdb %sp!, {%r4-%r11} @ Save non-volatile registers.
- mrc p15, 1, %r0, c0, c0, 1 @ Read CLIDR into R0.
- ands %r3, %r0, #0x7000000 @
- mov %r3, %r3, LSR #23 @ Cache level value (naturally aligned).
- beq ArCleanInvalidateEntireCacheEnd @
- mov %r10, #0 @
- ArCleanInvalidateEntireCacheLoop1:
- add %r2, %r10, %r10, LSR #1 @ Work out 3 x cache level.
- mov %r1, %r0, LSR %r2 @ Bottom 3 bits are the Cache Type for
- and %r1, %r1, #7 @ this level. Get those 3 bits.
- cmp %r1, #2 @ Check to see if there's no cache at
- blt ArCleanInvalidateEntireCacheSkip @ this level.
- mcr p15, 2, %r10, c0, c0, 0 @ Write CSSELR from R10.
- ISB @ ISB to sync the change to CCSIDR.
- mrc p15, 1, %r1, c0, c0, 0 @ Read current CCSIDR
- and %r2, %r1, #7 @ Extract the line length field.
- add %r2, %r2, #4 @ Add 4 for the line length offset
- ldr %r4, =0x3FF @ (log2 16 bytes).
- ands %r4, %r4, %r1, LSR #3 @ R4 is the max number on the way size
- @ (right aligned).
- clz %r5, %r4 @ R5 is the bit position of way size
- @ increment.
- mov %r9, %r4 @ R9 is the working copy of the max way
- @ size (right aligned).
- ArCleanInvalidateEntireCacheLoop2:
- ldr %r7, =0x00007FFF @
- ands %r7, %r7, %r1, LSR #13 @ R7 is the max number of the index size
- @ (right aligned).
- ArCleanInvalidateEntireCacheLoop3:
- lsl %r11, %r9, %r5 @ Factor in the way number and cache
- orr %r11, %r10, %r11 @ number into R11.
- lsl %r4, %r7, %r2 @ Factor in the
- orr %r11, %r11, %r4 @ index number.
- mcr p15, 0, %r11, c7, c14, 2 @ DCCISW, clean and invalidate set/way.
- subs %r7, %r7, #1 @ Decrement the index.
- bge ArCleanInvalidateEntireCacheLoop3
- subs %r9, %r9, #1 @ Decrement the way number.
- bge ArCleanInvalidateEntireCacheLoop2
- ArCleanInvalidateEntireCacheSkip:
- add %r10, %r10, #2 @ Increment the cache number.
- cmp %r3, %r10
- bgt ArCleanInvalidateEntireCacheLoop1
- ArCleanInvalidateEntireCacheEnd:
- mcr p15, 0, %r0, c7, c5, 0 @ Write to ICIALLU
- DSB
- ldmia %sp!, {%r4-%r11} @ Restore non-volatile registers.
- bx %lr
- END_FUNCTION ArCleanInvalidateEntireCache
- //
- // ULONG
- // ArGetMultiprocessorIdRegister (
- // VOID
- // )
- //
- /*++
- Routine Description:
- This routine gets the Multiprocessor ID register (MPIDR).
- Arguments:
- None.
- Return Value:
- Returns the value of the MPIDR.
- --*/
- FUNCTION ArGetMultiprocessorIdRegister
- mrc p15, 0, %r0, %c0, %c0, 5 @ Get the MPIDR
- bx %lr @
- END_FUNCTION ArGetMultiprocessorIdRegister
- //
- // ULONG
- // ArGetPerformanceControlRegister (
- // VOID
- // )
- //
- /*++
- Routine Description:
- This routine retrieves the PMCR (Performance Monitor Control Register).
- Arguments:
- None.
- Return Value:
- Returns the value of the PMCR.
- --*/
- FUNCTION ArGetPerformanceControlRegister
- mrc p15, 0, %r0, %c9, %c12, 0 @ Get the PMCR.
- bx %lr @
- END_FUNCTION ArGetPerformanceControlRegister
- //
- // VOID
- // ArSetPerformanceControlRegister (
- // ULONG Value
- // )
- //
- /*++
- Routine Description:
- This routine sets the PMCR (Performance Monitor Control Register).
- Arguments:
- Value - Supplies the value to set in the PMCR.
- Return Value:
- None.
- --*/
- FUNCTION ArSetPerformanceControlRegister
- mcr p15, 0, %r0, %c9, %c12, 0 @ Set the PMCR.
- bx %lr @
- END_FUNCTION ArSetPerformanceControlRegister
- //
- // VOID
- // ArClearPerformanceInterruptRegister (
- // ULONG Value
- // )
- //
- /*++
- Routine Description:
- This routine sets the PMINTENCLR (Performance Monitor Interrupt Clear)
- register.
- Arguments:
- Value - Supplies the value to set in the PMINTENCLR.
- Return Value:
- None.
- --*/
- FUNCTION ArClearPerformanceInterruptRegister
- mcr p15, 0, %r0, %c9, %c14, 2 @ Set the PMINTENCLR.
- bx %lr @
- END_FUNCTION ArClearPerformanceInterruptRegister
- //
- // VOID
- // ArSetPerformanceUserEnableRegister (
- // ULONG Value
- // )
- //
- /*++
- Routine Description:
- This routine sets the PMUSERENR (Performance Monitor User Enable Register).
- Arguments:
- Value - Supplies the value to set in the PMUSERENR.
- Return Value:
- None.
- --*/
- FUNCTION ArSetPerformanceUserEnableRegister
- mcr p15, 0, %r0, %c9, %c14, 0 @ Set the PMUSERENR.
- bx %lr @
- END_FUNCTION ArSetPerformanceUserEnableRegister
- //
- // ULONG
- // ArGetPerformanceCounterEnableRegister (
- // VOID
- // )
- //
- /*++
- Routine Description:
- This routine retrieves the PMCNTENSET (Performance Monitor Counter Enable
- Set) register.
- Arguments:
- None.
- Return Value:
- Returns the value of the PMCNTENSET.
- --*/
- FUNCTION ArGetPerformanceCounterEnableRegister
- mrc p15, 0, %r0, %c9, %c12, 1 @ Get the PMCNTENSET register.
- bx %lr @
- END_FUNCTION ArGetPerformanceCounterEnableRegister
- //
- // VOID
- // ArSetCycleCountEnableRegister (
- // ULONG Value
- // )
- //
- /*++
- Routine Description:
- This routine sets the PMCNTENSET (Performance Monitor Counter Enable
- Set) register.
- Arguments:
- Value - Supplies the value to set in the PMCNTENSET register.
- Return Value:
- None.
- --*/
- FUNCTION ArSetPerformanceCounterEnableRegister
- mcr p15, 0, %r0, %c9, %c12, 1 @ Set the PMCNTENSET register.
- bx %lr @
- END_FUNCTION ArSetPerformanceCounterEnableRegister
- //
- // ULONG
- // ArGetCycleCountRegister (
- // VOID
- // )
- //
- /*++
- Routine Description:
- This routine retrieves the PMCCNTR (Performance Monitor Cycle Counter)
- register.
- Arguments:
- None.
- Return Value:
- Returns the value of the PMCCNTR.
- --*/
- FUNCTION ArGetCycleCountRegister
- mrc p15, 0, %r0, %c9, %c13, 0 @ Get the PMCCNTR register.
- bx %lr @
- END_FUNCTION ArGetCycleCountRegister
- //
- // VOID
- // ArSetCycleCountRegister (
- // ULONG Value
- // )
- //
- /*++
- Routine Description:
- This routine sets the PMCCNTR (Performance Monitor Cycle Counter) register.
- Arguments:
- Value - Supplies the value to set in the PMCCNTR register.
- Return Value:
- None.
- --*/
- FUNCTION ArSetCycleCountRegister
- mcr p15, 0, %r0, %c9, %c13, 0 @ Set the PMCCNTR register.
- bx %lr @
- END_FUNCTION ArSetCycleCountRegister
- //
- // --------------------------------------------------------- Internal Functions
- //
|