cpu_ops.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020 Western Digital Corporation or its affiliates.
  4. */
  5. #include <linux/errno.h>
  6. #include <linux/mm.h>
  7. #include <linux/of.h>
  8. #include <linux/string.h>
  9. #include <linux/sched.h>
  10. #include <linux/sched/task_stack.h>
  11. #include <asm/cpu_ops.h>
  12. #include <asm/sbi.h>
  13. #include <asm/smp.h>
  14. const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
  15. void *__cpu_up_stack_pointer[NR_CPUS] __section(".data");
  16. void *__cpu_up_task_pointer[NR_CPUS] __section(".data");
  17. extern const struct cpu_operations cpu_ops_sbi;
  18. extern const struct cpu_operations cpu_ops_spinwait;
  19. void cpu_update_secondary_bootdata(unsigned int cpuid,
  20. struct task_struct *tidle)
  21. {
  22. int hartid = cpuid_to_hartid_map(cpuid);
  23. /* Make sure tidle is updated */
  24. smp_mb();
  25. WRITE_ONCE(__cpu_up_stack_pointer[hartid],
  26. task_stack_page(tidle) + THREAD_SIZE);
  27. WRITE_ONCE(__cpu_up_task_pointer[hartid], tidle);
  28. }
  29. void __init cpu_set_ops(int cpuid)
  30. {
  31. #if IS_ENABLED(CONFIG_RISCV_SBI)
  32. if (sbi_probe_extension(SBI_EXT_HSM) > 0) {
  33. if (!cpuid)
  34. pr_info("SBI v0.2 HSM extension detected\n");
  35. cpu_ops[cpuid] = &cpu_ops_sbi;
  36. } else
  37. #endif
  38. cpu_ops[cpuid] = &cpu_ops_spinwait;
  39. }