Commit 22d6a1cba3e9ec9baf8ce4d8dd1d088e112a64f1

Authored by David S. Miller
1 parent 36b48973b8

[SPARC64]: Report proper system soft state to the hypervisor.

Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 12 changed files with 175 additions and 7 deletions Side-by-side Diff

arch/sparc64/kernel/Makefile
... ... @@ -12,7 +12,7 @@
12 12 irq.o ptrace.o time.o sys_sparc.o signal.o \
13 13 unaligned.o central.o pci.o starfire.o semaphore.o \
14 14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
15   - visemul.o prom.o of_device.o hvapi.o
  15 + visemul.o prom.o of_device.o hvapi.o sstate.o
16 16  
17 17 obj-$(CONFIG_STACKTRACE) += stacktrace.o
18 18 obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
arch/sparc64/kernel/entry.S
... ... @@ -1937,4 +1937,16 @@
1937 1937 stx %o1, [%o4]
1938 1938 retl
1939 1939 nop
  1940 +
  1941 + /* %o0: soft state
  1942 + * %o1: address of description string
  1943 + *
  1944 + * returns %o0: status
  1945 + */
  1946 + .globl sun4v_mach_set_soft_state
  1947 +sun4v_mach_set_soft_state:
  1948 + mov HV_FAST_MACH_SET_SOFT_STATE, %o5
  1949 + ta HV_FAST_TRAP
  1950 + retl
  1951 + nop
arch/sparc64/kernel/hvapi.c
... ... @@ -9,6 +9,7 @@
9 9  
10 10 #include <asm/hypervisor.h>
11 11 #include <asm/oplib.h>
  12 +#include <asm/sstate.h>
12 13  
13 14 /* If the hypervisor indicates that the API setting
14 15 * calls are unsupported, by returning HV_EBADTRAP or
... ... @@ -178,6 +179,8 @@
178 179 minor = 1;
179 180 if (sun4v_hvapi_register(group, major, &minor))
180 181 goto bad;
  182 +
  183 + sun4v_sstate_init();
181 184  
182 185 return;
183 186  
arch/sparc64/kernel/power.c
... ... @@ -19,6 +19,7 @@
19 19 #include <asm/prom.h>
20 20 #include <asm/of_device.h>
21 21 #include <asm/io.h>
  22 +#include <asm/sstate.h>
22 23  
23 24 #include <linux/unistd.h>
24 25  
... ... @@ -53,6 +54,7 @@
53 54  
54 55 void machine_power_off(void)
55 56 {
  57 + sstate_poweroff();
56 58 if (!serial_console || scons_pwroff) {
57 59 #ifdef CONFIG_PCI
58 60 if (power_reg) {
arch/sparc64/kernel/process.c
... ... @@ -45,6 +45,7 @@
45 45 #include <asm/mmu_context.h>
46 46 #include <asm/unistd.h>
47 47 #include <asm/hypervisor.h>
  48 +#include <asm/sstate.h>
48 49  
49 50 /* #define VERBOSE_SHOWREGS */
50 51  
... ... @@ -106,6 +107,7 @@
106 107  
107 108 void machine_halt(void)
108 109 {
  110 + sstate_halt();
109 111 if (!serial_console && prom_palette)
110 112 prom_palette (1);
111 113 if (prom_keyboard)
... ... @@ -116,6 +118,7 @@
116 118  
117 119 void machine_alt_power_off(void)
118 120 {
  121 + sstate_poweroff();
119 122 if (!serial_console && prom_palette)
120 123 prom_palette(1);
121 124 if (prom_keyboard)
... ... @@ -128,6 +131,7 @@
128 131 {
129 132 char *p;
130 133  
  134 + sstate_reboot();
131 135 p = strchr (reboot_command, '\n');
132 136 if (p) *p = 0;
133 137 if (!serial_console && prom_palette)
arch/sparc64/kernel/sstate.c
  1 +/* sstate.c: System soft state support.
  2 + *
  3 + * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
  4 + */
  5 +
  6 +#include <linux/kernel.h>
  7 +#include <linux/notifier.h>
  8 +#include <linux/init.h>
  9 +
  10 +#include <asm/hypervisor.h>
  11 +#include <asm/sstate.h>
  12 +#include <asm/oplib.h>
  13 +#include <asm/head.h>
  14 +#include <asm/io.h>
  15 +
  16 +static int hv_supports_soft_state;
  17 +
  18 +static unsigned long kimage_addr_to_ra(const char *p)
  19 +{
  20 + unsigned long val = (unsigned long) p;
  21 +
  22 + return kern_base + (val - KERNBASE);
  23 +}
  24 +
  25 +static void do_set_sstate(unsigned long state, const char *msg)
  26 +{
  27 + unsigned long err;
  28 +
  29 + if (!hv_supports_soft_state)
  30 + return;
  31 +
  32 + err = sun4v_mach_set_soft_state(state, kimage_addr_to_ra(msg));
  33 + if (err) {
  34 + printk(KERN_WARNING "SSTATE: Failed to set soft-state to "
  35 + "state[%lx] msg[%s], err=%lu\n",
  36 + state, msg, err);
  37 + }
  38 +}
  39 +
  40 +static const char booting_msg[32] __attribute__((aligned(32))) =
  41 + "Linux booting";
  42 +static const char running_msg[32] __attribute__((aligned(32))) =
  43 + "Linux running";
  44 +static const char halting_msg[32] __attribute__((aligned(32))) =
  45 + "Linux halting";
  46 +static const char poweroff_msg[32] __attribute__((aligned(32))) =
  47 + "Linux powering off";
  48 +static const char rebooting_msg[32] __attribute__((aligned(32))) =
  49 + "Linux rebooting";
  50 +static const char panicing_msg[32] __attribute__((aligned(32))) =
  51 + "Linux panicing";
  52 +
  53 +void sstate_booting(void)
  54 +{
  55 + do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg);
  56 +}
  57 +
  58 +void sstate_running(void)
  59 +{
  60 + do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg);
  61 +}
  62 +
  63 +void sstate_halt(void)
  64 +{
  65 + do_set_sstate(HV_SOFT_STATE_TRANSITION, halting_msg);
  66 +}
  67 +
  68 +void sstate_poweroff(void)
  69 +{
  70 + do_set_sstate(HV_SOFT_STATE_TRANSITION, poweroff_msg);
  71 +}
  72 +
  73 +void sstate_reboot(void)
  74 +{
  75 + do_set_sstate(HV_SOFT_STATE_TRANSITION, rebooting_msg);
  76 +}
  77 +
  78 +static int sstate_panic_event(struct notifier_block *n, unsigned long event, void *ptr)
  79 +{
  80 + do_set_sstate(HV_SOFT_STATE_TRANSITION, panicing_msg);
  81 +
  82 + return NOTIFY_DONE;
  83 +}
  84 +
  85 +static struct notifier_block sstate_panic_block = {
  86 + .notifier_call = sstate_panic_event,
  87 + .priority = INT_MAX,
  88 +};
  89 +
  90 +void __init sun4v_sstate_init(void)
  91 +{
  92 + unsigned long major, minor;
  93 +
  94 + major = 1;
  95 + minor = 0;
  96 + if (sun4v_hvapi_register(HV_GRP_SOFT_STATE, major, &minor))
  97 + return;
  98 +
  99 + hv_supports_soft_state = 1;
  100 +
  101 + prom_sun4v_guest_soft_state();
  102 + atomic_notifier_chain_register(&panic_notifier_list,
  103 + &sstate_panic_block);
  104 +}
arch/sparc64/mm/init.c
... ... @@ -43,6 +43,7 @@
43 43 #include <asm/tsb.h>
44 44 #include <asm/hypervisor.h>
45 45 #include <asm/prom.h>
  46 +#include <asm/sstate.h>
46 47  
47 48 extern void device_scan(void);
48 49  
... ... @@ -1347,6 +1348,8 @@
1347 1348  
1348 1349 kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
1349 1350 kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
  1351 +
  1352 + sstate_booting();
1350 1353  
1351 1354 /* Invalidate both kernel TSBs. */
1352 1355 memset(swapper_tsb, 0x40, sizeof(swapper_tsb));
arch/sparc64/prom/misc.c
... ... @@ -15,6 +15,25 @@
15 15 #include <asm/oplib.h>
16 16 #include <asm/system.h>
17 17  
  18 +int prom_service_exists(const char *service_name)
  19 +{
  20 + int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
  21 + P1275_INOUT(1, 1), service_name);
  22 +
  23 + if (err)
  24 + return 0;
  25 + return 1;
  26 +}
  27 +
  28 +void prom_sun4v_guest_soft_state(void)
  29 +{
  30 + const char *svc = "SUNW,soft-state-supported";
  31 +
  32 + if (!prom_service_exists(svc))
  33 + return;
  34 + p1275_cmd(svc, P1275_INOUT(0, 0));
  35 +}
  36 +
18 37 /* Reset and reboot the machine with the command 'bcommand'. */
19 38 void prom_reboot(const char *bcommand)
20 39 {
include/asm-sparc64/bugs.h
1   -/* $Id: bugs.h,v 1.1 1996/12/26 13:25:20 davem Exp $
2   - * include/asm-sparc64/bugs.h: Sparc probes for various bugs.
  1 +/* bugs.h: Sparc64 probes for various bugs.
3 2 *
4   - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  3 + * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
5 4 */
  5 +#include <asm/sstate.h>
6 6  
7   -
8 7 extern unsigned long loops_per_jiffy;
9 8  
10 9 static void __init check_bugs(void)
... ... @@ -12,5 +11,6 @@
12 11 #ifndef CONFIG_SMP
13 12 cpu_data(0).udelay_val = loops_per_jiffy;
14 13 #endif
  14 + sstate_running();
15 15 }
include/asm-sparc64/hypervisor.h
... ... @@ -162,10 +162,15 @@
162 162 * terminated 7-bit ASCII string of up to 31 characters not including the
163 163 * NULL termination.
164 164 */
165   -#define HV_FAST_MACH_SET_SOFT_STATE 0x03
  165 +#define HV_FAST_MACH_SET_SOFT_STATE 0x70
166 166 #define HV_SOFT_STATE_NORMAL 0x01
167 167 #define HV_SOFT_STATE_TRANSITION 0x02
168 168  
  169 +#ifndef __ASSEMBLY__
  170 +extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
  171 + unsigned long msg_string_ra);
  172 +#endif
  173 +
169 174 /* mach_get_soft_state()
170 175 * TRAP: HV_FAST_TRAP
171 176 * FUNCTION: HV_FAST_MACH_GET_SOFT_STATE
... ... @@ -181,7 +186,7 @@
181 186 * for the software state pointer are the same as for mach_set_soft_state()
182 187 * above.
183 188 */
184   -#define HV_FAST_MACH_GET_SOFT_STATE 0x04
  189 +#define HV_FAST_MACH_GET_SOFT_STATE 0x71
185 190  
186 191 /* CPU services.
187 192 *
... ... @@ -2204,6 +2209,7 @@
2204 2209 extern int sun4v_hvapi_get(unsigned long group,
2205 2210 unsigned long *major,
2206 2211 unsigned long *minor);
  2212 +extern void sun4v_hvapi_init(void);
2207 2213 #endif
2208 2214  
2209 2215 #endif /* !(_SPARC64_HYPERVISOR_H) */
include/asm-sparc64/oplib.h
... ... @@ -316,6 +316,8 @@
316 316  
317 317 extern int prom_pathtoinode(const char *path);
318 318 extern int prom_inst2pkg(int);
  319 +extern int prom_service_exists(const char *service_name);
  320 +extern void prom_sun4v_guest_soft_state(void);
319 321  
320 322 /* CPU probing helpers. */
321 323 struct device_node;
include/asm-sparc64/sstate.h
  1 +#ifndef _SPARC64_SSTATE_H
  2 +#define _SPARC64_SSTATE_H
  3 +
  4 +extern void sstate_booting(void);
  5 +extern void sstate_running(void);
  6 +extern void sstate_halt(void);
  7 +extern void sstate_poweroff(void);
  8 +extern void sstate_panic(void);
  9 +extern void sstate_reboot(void);
  10 +
  11 +extern void sun4v_sstate_init(void);
  12 +
  13 +#endif /* _SPARC64_SSTATE_H */