Commit ea5e7447 authored by David S. Miller's avatar David S. Miller

sparc: Set reboot-cmd using reboot data hypervisor call if available.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e2eb9f81
...@@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request, ...@@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request,
#define HV_FAST_FIRE_GET_PERFREG 0x120 #define HV_FAST_FIRE_GET_PERFREG 0x120
#define HV_FAST_FIRE_SET_PERFREG 0x121 #define HV_FAST_FIRE_SET_PERFREG 0x121
#define HV_FAST_REBOOT_DATA_SET 0x172
#ifndef __ASSEMBLY__
extern unsigned long sun4v_reboot_data_set(unsigned long ra,
unsigned long len);
#endif
/* Function numbers for HV_CORE_TRAP. */ /* Function numbers for HV_CORE_TRAP. */
#define HV_CORE_SET_VER 0x00 #define HV_CORE_SET_VER 0x00
#define HV_CORE_PUTCHAR 0x01 #define HV_CORE_PUTCHAR 0x01
......
...@@ -15,12 +15,15 @@ ...@@ -15,12 +15,15 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <asm/hypervisor.h>
#include <asm/ldc.h> #include <asm/ldc.h>
#include <asm/vio.h> #include <asm/vio.h>
#include <asm/mdesc.h> #include <asm/mdesc.h>
#include <asm/head.h> #include <asm/head.h>
#include <asm/irq.h> #include <asm/irq.h>
#include "kernel.h"
#define DRV_MODULE_NAME "ds" #define DRV_MODULE_NAME "ds"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.0" #define DRV_MODULE_VERSION "1.0"
...@@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value) ...@@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value)
} }
} }
static char full_boot_str[256] __attribute__((aligned(32)));
static int reboot_data_supported;
void ldom_reboot(const char *boot_command) void ldom_reboot(const char *boot_command)
{ {
/* Don't bother with any of this if the boot_command /* Don't bother with any of this if the boot_command
* is empty. * is empty.
*/ */
if (boot_command && strlen(boot_command)) { if (boot_command && strlen(boot_command)) {
char full_boot_str[256]; unsigned long len;
strcpy(full_boot_str, "boot "); strcpy(full_boot_str, "boot ");
strcpy(full_boot_str + strlen("boot "), boot_command); strcpy(full_boot_str + strlen("boot "), boot_command);
len = strlen(full_boot_str);
ldom_set_var("reboot-command", full_boot_str); if (reboot_data_supported) {
unsigned long ra = kimage_addr_to_ra(full_boot_str);
unsigned long hv_ret;
hv_ret = sun4v_reboot_data_set(ra, len);
if (hv_ret != HV_EOK)
pr_err("SUN4V: Unable to set reboot data "
"hv_ret=%lu\n", hv_ret);
} else {
ldom_set_var("reboot-command", full_boot_str);
}
} }
sun4v_mach_sir(); sun4v_mach_sir();
} }
...@@ -1237,6 +1254,15 @@ static struct vio_driver ds_driver = { ...@@ -1237,6 +1254,15 @@ static struct vio_driver ds_driver = {
static int __init ds_init(void) static int __init ds_init(void)
{ {
unsigned long hv_ret, major, minor;
hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor);
if (hv_ret == HV_EOK) {
pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n",
major, minor);
reboot_data_supported = 1;
}
kthread_run(ds_thread, NULL, "kldomd"); kthread_run(ds_thread, NULL, "kldomd");
return vio_register_driver(&ds_driver); return vio_register_driver(&ds_driver);
......
...@@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf) ...@@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf)
retl retl
nop nop
ENDPROC(sun4v_niagara2_setperf) ENDPROC(sun4v_niagara2_setperf)
ENTRY(sun4v_reboot_data_set)
mov HV_FAST_REBOOT_DATA_SET, %o5
ta HV_FAST_TRAP
retl
nop
ENDPROC(sun4v_reboot_data_set)
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/head.h>
#include <asm/io.h>
/* cpu.c */ /* cpu.c */
extern const char *sparc_pmu_type; extern const char *sparc_pmu_type;
...@@ -14,6 +16,13 @@ extern int ncpus_probed; ...@@ -14,6 +16,13 @@ extern int ncpus_probed;
/* setup_64.c */ /* setup_64.c */
struct seq_file; struct seq_file;
extern void cpucap_info(struct seq_file *); extern void cpucap_info(struct seq_file *);
static inline unsigned long kimage_addr_to_ra(const char *p)
{
unsigned long val = (unsigned long) p;
return kern_base + (val - KERNBASE);
}
#endif #endif
#ifdef CONFIG_SPARC32 #ifdef CONFIG_SPARC32
......
...@@ -14,14 +14,9 @@ ...@@ -14,14 +14,9 @@
#include <asm/head.h> #include <asm/head.h>
#include <asm/io.h> #include <asm/io.h>
static int hv_supports_soft_state; #include "kernel.h"
static unsigned long kimage_addr_to_ra(const char *p)
{
unsigned long val = (unsigned long) p;
return kern_base + (val - KERNBASE); static int hv_supports_soft_state;
}
static void do_set_sstate(unsigned long state, const char *msg) static void do_set_sstate(unsigned long state, const char *msg)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment