123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 |
- /*
- * Copyright 2018-2020 NXP
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
- #include <asm_macros.S>
- #include "bl31_data.h"
- #include "plat_psci.h"
- #include "platform_def.h"
- .global _getCoreData
- .global _setCoreData
- .global _getCoreState
- .global _setCoreState
- .global _init_global_data
- .global _get_global_data
- .global _set_global_data
- .global _initialize_psci
- .global _init_task_flags
- .global _set_task1_start
- .global _set_task1_done
- /* Function returns the specified data field value from the specified cpu
- * core data area
- * in: x0 = core mask lsb
- * x1 = data field name/offset
- * out: x0 = data value
- * uses x0, x1, x2, [x13, x14, x15]
- */
- func _getCoreData
- /* generate a 0-based core number from the input mask */
- clz x2, x0
- mov x0, #63
- sub x0, x0, x2
- /* x0 = core number (0-based) */
- /* x1 = field offset */
- /* determine if this is bootcore or secondary core */
- cbnz x0, 1f
- /* get base address for bootcore data */
- ldr x2, =BC_PSCI_BASE
- add x2, x2, x1
- b 2f
- 1: /* get base address for secondary core data */
- /* x0 = core number (0-based) */
- /* x1 = field offset */
- /* generate number of regions to offset */
- mov x2, #SEC_REGION_SIZE
- mul x2, x2, x0
- /* x1 = field offset */
- /* x2 = region offset */
- /* generate the total offset to data element */
- sub x1, x2, x1
- /* x1 = total offset to data element */
- /* get the base address */
- ldr x2, =SECONDARY_TOP
- /* apply offset to base addr */
- sub x2, x2, x1
- 2:
- /* x2 = data element address */
- dc ivac, x2
- dsb sy
- isb
- /* read data */
- ldr x0, [x2]
- ret
- endfunc _getCoreData
- /* Function returns the SoC-specific state of the specified cpu
- * in: x0 = core mask lsb
- * out: x0 = data value
- * uses x0, x1, x2, [x13, x14, x15]
- */
- func _getCoreState
- mov x1, #CORE_STATE_DATA
- /* generate a 0-based core number from the input mask */
- clz x2, x0
- mov x0, #63
- sub x0, x0, x2
- /* x0 = core number (0-based) */
- /* x1 = field offset */
- /* determine if this is bootcore or secondary core */
- cbnz x0, 1f
- /* get base address for bootcore data */
- ldr x2, =BC_PSCI_BASE
- add x2, x2, x1
- b 2f
- 1: /* get base address for secondary core data */
- /* x0 = core number (0-based) */
- /* x1 = field offset */
- /* generate number of regions to offset */
- mov x2, #SEC_REGION_SIZE
- mul x2, x2, x0
- /* x1 = field offset */
- /* x2 = region offset */
- /* generate the total offset to data element */
- sub x1, x2, x1
- /* x1 = total offset to data element */
- /* get the base address */
- ldr x2, =SECONDARY_TOP
- /* apply offset to base addr */
- sub x2, x2, x1
- 2:
- /* x2 = data element address */
- dc ivac, x2
- dsb sy
- isb
- /* read data */
- ldr x0, [x2]
- ret
- endfunc _getCoreState
- /* Function writes the specified data value into the specified cpu
- * core data area
- * in: x0 = core mask lsb
- * x1 = data field offset
- * x2 = data value to write/store
- * out: none
- * uses x0, x1, x2, x3, [x13, x14, x15]
- */
- func _setCoreData
- /* x0 = core mask */
- /* x1 = field offset */
- /* x2 = data value */
- clz x3, x0
- mov x0, #63
- sub x0, x0, x3
- /* x0 = core number (0-based) */
- /* x1 = field offset */
- /* x2 = data value */
- /* determine if this is bootcore or secondary core */
- cbnz x0, 1f
- /* get base address for bootcore data */
- ldr x3, =BC_PSCI_BASE
- add x3, x3, x1
- b 2f
- 1: /* get base address for secondary core data */
- /* x0 = core number (0-based) */
- /* x1 = field offset */
- /* x2 = data value */
- /* generate number of regions to offset */
- mov x3, #SEC_REGION_SIZE
- mul x3, x3, x0
- /* x1 = field offset */
- /* x2 = data value */
- /* x3 = region offset */
- /* generate the total offset to data element */
- sub x1, x3, x1
- /* x1 = total offset to data element */
- /* x2 = data value */
- ldr x3, =SECONDARY_TOP
- /* apply offset to base addr */
- sub x3, x3, x1
- 2:
- /* x2 = data value */
- /* x3 = data element address */
- str x2, [x3]
- dc cvac, x3
- dsb sy
- isb
- ret
- endfunc _setCoreData
- /* Function stores the specified core state
- * in: x0 = core mask lsb
- * x1 = data value to write/store
- * out: none
- * uses x0, x1, x2, x3, [x13, x14, x15]
- */
- func _setCoreState
- mov x2, #CORE_STATE_DATA
- clz x3, x0
- mov x0, #63
- sub x0, x0, x3
- /* x0 = core number (0-based) */
- /* x1 = data value */
- /* x2 = field offset */
- /* determine if this is bootcore or secondary core */
- cbnz x0, 1f
- /* get base address for bootcore data */
- ldr x3, =BC_PSCI_BASE
- add x3, x3, x2
- b 2f
- 1: /* get base address for secondary core data */
- /* x0 = core number (0-based) */
- /* x1 = data value */
- /* x2 = field offset */
- /* generate number of regions to offset */
- mov x3, #SEC_REGION_SIZE
- mul x3, x3, x0
- /* x1 = data value */
- /* x2 = field offset */
- /* x3 = region offset */
- /* generate the total offset to data element */
- sub x2, x3, x2
- /* x1 = data value */
- /* x2 = total offset to data element */
- ldr x3, =SECONDARY_TOP
- /* apply offset to base addr */
- sub x3, x3, x2
- 2:
- /* x1 = data value */
- /* x3 = data element address */
- str x1, [x3]
- dc civac, x3
- dsb sy
- isb
- ret
- endfunc _setCoreState
- /* Function sets the task1 start
- * in: w0 = value to set flag to
- * out: none
- * uses x0, x1
- */
- func _set_task1_start
- ldr x1, =SMC_TASK1_BASE
- add x1, x1, #TSK_START_OFFSET
- str w0, [x1]
- dc cvac, x1
- dsb sy
- isb
- ret
- endfunc _set_task1_start
- /* Function sets the state of the task 1 done flag
- * in: w0 = value to set flag to
- * out: none
- * uses x0, x1
- */
- func _set_task1_done
- ldr x1, =SMC_TASK1_BASE
- add x1, x1, #TSK_DONE_OFFSET
- str w0, [x1]
- dc cvac, x1
- dsb sy
- isb
- ret
- endfunc _set_task1_done
- /* Function initializes the smc global data entries
- * Note: the constant LAST_SMC_GLBL_OFFSET must reference the last entry in the
- * smc global region
- * in: none
- * out: none
- * uses x0, x1, x2
- */
- func _init_global_data
- ldr x1, =SMC_GLBL_BASE
- /* x1 = SMC_GLBL_BASE */
- mov x2, #LAST_SMC_GLBL_OFFSET
- add x2, x2, x1
- 1:
- str xzr, [x1]
- dc cvac, x1
- cmp x2, x1
- add x1, x1, #8
- b.hi 1b
- dsb sy
- isb
- ret
- endfunc _init_global_data
- /* Function gets the value of the specified global data element
- * in: x0 = offset of data element
- * out: x0 = requested data element
- * uses x0, x1
- */
- func _get_global_data
- ldr x1, =SMC_GLBL_BASE
- add x1, x1, x0
- dc ivac, x1
- isb
- ldr x0, [x1]
- ret
- endfunc _get_global_data
- /* Function sets the value of the specified global data element
- * in: x0 = offset of data element
- * x1 = value to write
- * out: none
- * uses x0, x1, x2
- */
- func _set_global_data
- ldr x2, =SMC_GLBL_BASE
- add x0, x0, x2
- str x1, [x0]
- dc cvac, x0
- dsb sy
- isb
- ret
- endfunc _set_global_data
- /* Function initializes the core data areas
- * only executed by the boot core
- * in: none
- * out: none
- * uses: x0, x1, x2, x3, x4, x5, x6, x7, [x13, x14, x15]
- */
- func _initialize_psci
- mov x7, x30
- /* initialize the bootcore psci data */
- ldr x5, =BC_PSCI_BASE
- mov x6, #CORE_RELEASED
- str x6, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5], #8
- dc cvac, x5
- str xzr, [x5]
- dc cvac, x5
- dsb sy
- isb
- /* see if we have any secondary cores */
- mov x4, #PLATFORM_CORE_COUNT
- sub x4, x4, #1
- cbz x4, 3f
- /* initialize the secondary core's psci data */
- ldr x5, =SECONDARY_TOP
- /* core mask lsb for core 1 */
- mov x3, #2
- sub x5, x5, #SEC_REGION_SIZE
- /* x3 = core1 mask lsb */
- /* x4 = number of secondary cores */
- /* x5 = core1 psci data base address */
- 2:
- /* set core state in x6 */
- mov x0, x3
- mov x6, #CORE_IN_RESET
- bl _soc_ck_disabled
- cbz x0, 1f
- mov x6, #CORE_DISABLED
- 1:
- add x2, x5, #CORE_STATE_DATA
- str x6, [x2]
- dc cvac, x2
- add x2, x5, #SPSR_EL3_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #CNTXT_ID_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #START_ADDR_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #LINK_REG_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #GICC_CTLR_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #ABORT_FLAG_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #SCTLR_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #CPUECTLR_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #AUX_01_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #AUX_02_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #AUX_03_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #AUX_04_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #AUX_05_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #SCR_EL3_DATA
- str xzr, [x2]
- dc cvac, x2
- add x2, x5, #HCR_EL2_DATA
- str xzr, [x2]
- dc cvac, x2
- dsb sy
- isb
- sub x4, x4, #1
- cbz x4, 3f
- /* generate next core mask */
- lsl x3, x3, #1
- /* decrement base address to next data area */
- sub x5, x5, #SEC_REGION_SIZE
- b 2b
- 3:
- mov x30, x7
- ret
- endfunc _initialize_psci
- /* Function initializes the soc init task flags
- * in: none
- * out: none
- * uses x0, x1, [x13, x14, x15]
- */
- func _init_task_flags
- /* get the base address of the first task structure */
- ldr x0, =SMC_TASK1_BASE
- /* x0 = task1 base address */
- str wzr, [x0, #TSK_START_OFFSET]
- str wzr, [x0, #TSK_DONE_OFFSET]
- str wzr, [x0, #TSK_CORE_OFFSET]
- dc cvac, x0
- /* move to task2 structure */
- add x0, x0, #SMC_TASK_OFFSET
- str wzr, [x0, #TSK_START_OFFSET]
- str wzr, [x0, #TSK_DONE_OFFSET]
- str wzr, [x0, #TSK_CORE_OFFSET]
- dc cvac, x0
- /* move to task3 structure */
- add x0, x0, #SMC_TASK_OFFSET
- str wzr, [x0, #TSK_START_OFFSET]
- str wzr, [x0, #TSK_DONE_OFFSET]
- str wzr, [x0, #TSK_CORE_OFFSET]
- dc cvac, x0
- /* move to task4 structure */
- add x0, x0, #SMC_TASK_OFFSET
- str wzr, [x0, #TSK_START_OFFSET]
- str wzr, [x0, #TSK_DONE_OFFSET]
- str wzr, [x0, #TSK_CORE_OFFSET]
- dc cvac, x0
- dsb sy
- isb
- ret
- endfunc _init_task_flags
|