Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Copyright (C) 1996-2000 Russell King - Converted to ARM.
0004  *  Original Copyright (C) 1995  Linus Torvalds
0005  */
0006 #include <linux/cpu.h>
0007 #include <linux/delay.h>
0008 #include <linux/reboot.h>
0009 
0010 #include <asm/cacheflush.h>
0011 #include <asm/idmap.h>
0012 #include <asm/virt.h>
0013 #include <asm/system_misc.h>
0014 
0015 #include "reboot.h"
0016 
0017 typedef void (*phys_reset_t)(unsigned long, bool);
0018 
0019 /*
0020  * Function pointers to optional machine specific functions
0021  */
0022 void (*pm_power_off)(void);
0023 EXPORT_SYMBOL(pm_power_off);
0024 
0025 /*
0026  * A temporary stack to use for CPU reset. This is static so that we
0027  * don't clobber it with the identity mapping. When running with this
0028  * stack, any references to the current task *will not work* so you
0029  * should really do as little as possible before jumping to your reset
0030  * code.
0031  */
0032 static u64 soft_restart_stack[16];
0033 
0034 static void __soft_restart(void *addr)
0035 {
0036     phys_reset_t phys_reset;
0037 
0038     /* Take out a flat memory mapping. */
0039     setup_mm_for_reboot();
0040 
0041     /* Clean and invalidate caches */
0042     flush_cache_all();
0043 
0044     /* Turn off caching */
0045     cpu_proc_fin();
0046 
0047     /* Push out any further dirty data, and ensure cache is empty */
0048     flush_cache_all();
0049 
0050     /* Switch to the identity mapping. */
0051     phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
0052 
0053     /* original stub should be restored by kvm */
0054     phys_reset((unsigned long)addr, is_hyp_mode_available());
0055 
0056     /* Should never get here. */
0057     BUG();
0058 }
0059 
0060 void _soft_restart(unsigned long addr, bool disable_l2)
0061 {
0062     u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
0063 
0064     /* Disable interrupts first */
0065     raw_local_irq_disable();
0066     local_fiq_disable();
0067 
0068     /* Disable the L2 if we're the last man standing. */
0069     if (disable_l2)
0070         outer_disable();
0071 
0072     /* Change to the new stack and continue with the reset. */
0073     call_with_stack(__soft_restart, (void *)addr, (void *)stack);
0074 
0075     /* Should never get here. */
0076     BUG();
0077 }
0078 
0079 void soft_restart(unsigned long addr)
0080 {
0081     _soft_restart(addr, num_online_cpus() == 1);
0082 }
0083 
0084 /*
0085  * Called by kexec, immediately prior to machine_kexec().
0086  *
0087  * This must completely disable all secondary CPUs; simply causing those CPUs
0088  * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
0089  * kexec'd kernel to use any and all RAM as it sees fit, without having to
0090  * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
0091  * functionality embodied in smp_shutdown_nonboot_cpus() to achieve this.
0092  */
0093 void machine_shutdown(void)
0094 {
0095     smp_shutdown_nonboot_cpus(reboot_cpu);
0096 }
0097 
0098 /*
0099  * Halting simply requires that the secondary CPUs stop performing any
0100  * activity (executing tasks, handling interrupts). smp_send_stop()
0101  * achieves this.
0102  */
0103 void machine_halt(void)
0104 {
0105     local_irq_disable();
0106     smp_send_stop();
0107     while (1);
0108 }
0109 
0110 /*
0111  * Power-off simply requires that the secondary CPUs stop performing any
0112  * activity (executing tasks, handling interrupts). smp_send_stop()
0113  * achieves this. When the system power is turned off, it will take all CPUs
0114  * with it.
0115  */
0116 void machine_power_off(void)
0117 {
0118     local_irq_disable();
0119     smp_send_stop();
0120     do_kernel_power_off();
0121 }
0122 
0123 /*
0124  * Restart requires that the secondary CPUs stop performing any activity
0125  * while the primary CPU resets the system. Systems with a single CPU can
0126  * use soft_restart() as their machine descriptor's .restart hook, since that
0127  * will cause the only available CPU to reset. Systems with multiple CPUs must
0128  * provide a HW restart implementation, to ensure that all CPUs reset at once.
0129  * This is required so that any code running after reset on the primary CPU
0130  * doesn't have to co-ordinate with other CPUs to ensure they aren't still
0131  * executing pre-reset code, and using RAM that the primary CPU's code wishes
0132  * to use. Implementing such co-ordination would be essentially impossible.
0133  */
0134 void machine_restart(char *cmd)
0135 {
0136     local_irq_disable();
0137     smp_send_stop();
0138 
0139     do_kernel_restart(cmd);
0140 
0141     /* Give a grace period for failure to restart of 1s */
0142     mdelay(1000);
0143 
0144     /* Whoops - the platform was unable to reboot. Tell the user! */
0145     printk("Reboot failed -- System halted\n");
0146     while (1);
0147 }