Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/arm64/kernel/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  sleep.S   Sprache: Sparc

 
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/errno.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/assembler.h>
#include <asm/smp.h>

 .text
/*
 * Implementation of MPIDR_EL1 hash algorithm through shifting
 * and OR'ing.
 *
 * @dst: register containing hash result
 * @rs0: register containing affinity level 0 bit shift
 * @rs1: register containing affinity level 1 bit shift
 * @rs2: register containing affinity level 2 bit shift
 * @rs3: register containing affinity level 3 bit shift
 * @mpidr: register containing MPIDR_EL1 value
 * @mask: register containing MPIDR mask
 *
 * Pseudo C-code:
 *
 *u32 dst;
 *
 *compute_mpidr_hash(u32 rs0, u32 rs1, u32 rs2, u32 rs3, u64 mpidr, u64 mask) {
 * u32 aff0, aff1, aff2, aff3;
 * u64 mpidr_masked = mpidr & mask;
 * aff0 = mpidr_masked & 0xff;
 * aff1 = mpidr_masked & 0xff00;
 * aff2 = mpidr_masked & 0xff0000;
 * aff3 = mpidr_masked & 0xff00000000;
 * dst = (aff0 >> rs0 | aff1 >> rs1 | aff2 >> rs2 | aff3 >> rs3);
 *}
 * Input registers: rs0, rs1, rs2, rs3, mpidr, mask
 * Output register: dst
 * Note: input and output registers must be disjoint register sets
         (eg: a macro instance with mpidr = x1 and dst = x1 is invalid)
 */

 .macro compute_mpidr_hash dst, rs0, rs1, rs2, rs3, mpidr, mask
 and \mpidr, \mpidr, \mask  // mask out MPIDR bits
 and \dst, \mpidr, #0xff  // mask=aff0
 lsr \dst ,\dst, \rs0  // dst=aff0>>rs0
 and \mask, \mpidr, #0xff00  // mask = aff1
 lsr \mask ,\mask, \rs1
 orr \dst, \dst, \mask  // dst|=(aff1>>rs1)
 and \mask, \mpidr, #0xff0000 // mask = aff2
 lsr \mask ,\mask, \rs2
 orr \dst, \dst, \mask  // dst|=(aff2>>rs2)
 and \mask, \mpidr, #0xff00000000 // mask = aff3
 lsr \mask ,\mask, \rs3
 orr \dst, \dst, \mask  // dst|=(aff3>>rs3)
 .endm
/*
 * Save CPU state in the provided sleep_stack_data area, and publish its
 * location for cpu_resume()'s use in sleep_save_stash.
 *
 * cpu_resume() will restore this saved state, and return. Because the
 * link-register is saved and restored, it will appear to return from this
 * function. So that the caller can tell the suspend/resume paths apart,
 * __cpu_suspend_enter() will always return a non-zero value, whereas the
 * path through cpu_resume() will return 0.
 *
 *  x0 = struct sleep_stack_data area
 */

SYM_FUNC_START(__cpu_suspend_enter)
 stp x29, lr, [x0, #SLEEP_STACK_DATA_CALLEE_REGS]
 stp x19, x20, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+16]
 stp x21, x22, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+32]
 stp x23, x24, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+48]
 stp x25, x26, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+64]
 stp x27, x28, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+80]

 /* save the sp in cpu_suspend_ctx */
 mov x2, sp
 str x2, [x0, #SLEEP_STACK_DATA_SYSTEM_REGS + CPU_CTX_SP]

 /* find the mpidr_hash */
 ldr_l x1, sleep_save_stash
 mrs x7, mpidr_el1
 adr_l x9, mpidr_hash
 ldr x10, [x9, #MPIDR_HASH_MASK]
 /*
 * Following code relies on the struct mpidr_hash
 * members size.
 */

 ldp w3, w4, [x9, #MPIDR_HASH_SHIFTS]
 ldp w5, w6, [x9, #(MPIDR_HASH_SHIFTS + 8)]
 compute_mpidr_hash x8, x3, x4, x5, x6, x7, x10
 add x1, x1, x8, lsl #3

 str x0, [x1]
 add x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
 stp x29, lr, [sp, #-16]!
 bl cpu_do_suspend
 ldp x29, lr, [sp], #16
 mov x0, #1
 ret
SYM_FUNC_END(__cpu_suspend_enter)

 .pushsection ".idmap.text""a"
SYM_CODE_START(cpu_resume)
 mov x0, xzr
 bl init_kernel_el
 mov x19, x0   // preserve boot mode
 bl __cpu_setup
 /* enable the MMU early - so we can access sleep_save_stash by va */
 adrp x1, swapper_pg_dir
 adrp x2, idmap_pg_dir
 bl __enable_mmu
 ldr x8, =_cpu_resume
 br x8
SYM_CODE_END(cpu_resume)
 .ltorg
 .popsection

SYM_FUNC_START(_cpu_resume)
 mov x0, x19
 bl finalise_el2

 mrs x1, mpidr_el1
 adr_l x8, mpidr_hash  // x8 = struct mpidr_hash virt address

 /* retrieve mpidr_hash members to compute the hash */
 ldr x2, [x8, #MPIDR_HASH_MASK]
 ldp w3, w4, [x8, #MPIDR_HASH_SHIFTS]
 ldp w5, w6, [x8, #(MPIDR_HASH_SHIFTS + 8)]
 compute_mpidr_hash x7, x3, x4, x5, x6, x1, x2

 /* x7 contains hash index, let's use it to grab context pointer */
 ldr_l x0, sleep_save_stash
 ldr x0, [x0, x7, lsl #3]
 add x29, x0, #SLEEP_STACK_DATA_CALLEE_REGS
 add x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
 /* load sp from context */
 ldr x2, [x0, #CPU_CTX_SP]
 mov sp, x2
 /*
 * cpu_do_resume expects x0 to contain context address pointer
 */

 bl cpu_do_resume

#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
 mov x0, sp
 bl kasan_unpoison_task_stack_below
#endif

 ldp x19, x20, [x29, #16]
 ldp x21, x22, [x29, #32]
 ldp x23, x24, [x29, #48]
 ldp x25, x26, [x29, #64]
 ldp x27, x28, [x29, #80]
 ldp x29, lr, [x29]
 mov x0, #0
 ret
SYM_FUNC_END(_cpu_resume)

Messung V0.5
C=94 H=92 G=92

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.