linux/arch/sparc64/kernel/sstate.c
<<
>>
Prefs
   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
  16static int hv_supports_soft_state;
  17
  18static 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
  25static 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
  40static const char booting_msg[32] __attribute__((aligned(32))) =
  41        "Linux booting";
  42static const char running_msg[32] __attribute__((aligned(32))) =
  43        "Linux running";
  44static const char halting_msg[32] __attribute__((aligned(32))) =
  45        "Linux halting";
  46static const char poweroff_msg[32] __attribute__((aligned(32))) =
  47        "Linux powering off";
  48static const char rebooting_msg[32] __attribute__((aligned(32))) =
  49        "Linux rebooting";
  50static const char panicing_msg[32] __attribute__((aligned(32))) =
  51        "Linux panicing";
  52
  53void sstate_booting(void)
  54{
  55        do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg);
  56}
  57
  58void sstate_running(void)
  59{
  60        do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg);
  61}
  62
  63void sstate_halt(void)
  64{
  65        do_set_sstate(HV_SOFT_STATE_TRANSITION, halting_msg);
  66}
  67
  68void sstate_poweroff(void)
  69{
  70        do_set_sstate(HV_SOFT_STATE_TRANSITION, poweroff_msg);
  71}
  72
  73void sstate_reboot(void)
  74{
  75        do_set_sstate(HV_SOFT_STATE_TRANSITION, rebooting_msg);
  76}
  77
  78static 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
  85static struct notifier_block sstate_panic_block = {
  86        .notifier_call  =       sstate_panic_event,
  87        .priority       =       INT_MAX,
  88};
  89
  90void __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}
 105