1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Intel Corporation.
  24  * All rights reserved.
  25  */
  26 /*
  27  * Interfaces to support System Board Dynamic Reconfiguration.
  28  */
  29 
  30 #ifndef _SYS_ACPIDEV_DR_H
  31 #define _SYS_ACPIDEV_DR_H
  32 #include <sys/types.h>
  33 #include <sys/obpdefs.h>
  34 #include <sys/cpuvar.h>
  35 #include <sys/memlist.h>
  36 #include <sys/sunddi.h>
  37 #include <acpica/include/acpi.h>
  38 #include <sys/acpica.h>
  39 #include <sys/acpidev.h>
  40 #include <sys/acpidev_rsc.h>
  41 
  42 #ifdef __cplusplus
  43 extern "C" {
  44 #endif
  45 
  46 #ifdef  _KERNEL
  47 
  48 /* Maximum number of DR capable system boards supported. */
  49 #define ACPIDEV_DR_MAX_BOARDS           0x40
  50 #define ACPIDEV_DR_SEGS_PER_MEM_DEV     0x10
  51 #define ACPIDEV_DR_MEMLISTS_PER_SEG     0x10
  52 #define ACPIDEV_DR_MAX_MEMLIST_ENTRIES  0x10000
  53 
  54 #define ACPIDEV_DR_PROP_PORTID          "portid"
  55 #define ACPIDEV_DR_PROP_BOARDNUM        OBP_BOARDNUM
  56 #define ACPIDEV_DR_PROP_DEVNAME         OBP_NAME
  57 
  58 /*
  59  * Format strings for DR capable system boards.
  60  * They will be used as attachment point names.
  61  */
  62 #define ACPIDEV_DR_CPU_BD_FMT           "CPU%u"
  63 #define ACPIDEV_DR_MEMORY_BD_FMT        "MEM%u"
  64 #define ACPIDEV_DR_IO_BD_FMT            "IO%u"
  65 #define ACPIDEV_DR_SYSTEM_BD_FMT        "SB%u"
  66 
  67 typedef enum {
  68         ACPIDEV_INVALID_BOARD = 0,
  69         ACPIDEV_CPU_BOARD,
  70         ACPIDEV_MEMORY_BOARD,
  71         ACPIDEV_IO_BOARD,
  72         ACPIDEV_SYSTEM_BOARD
  73 } acpidev_board_type_t;
  74 
  75 /* Check whether the system is DR capable. */
  76 extern int acpidev_dr_capable(void);
  77 
  78 extern uint32_t acpidev_dr_max_boards(void);
  79 extern uint32_t acpidev_dr_max_mem_units_per_board(void);
  80 extern uint32_t acpidev_dr_max_io_units_per_board(void);
  81 extern uint32_t acpidev_dr_max_cmp_units_per_board(void);
  82 extern uint32_t acpidev_dr_max_cpu_units_per_cmp(void);
  83 extern uint32_t acpidev_dr_max_segments_per_mem_device(void);
  84 extern uint32_t acpidev_dr_max_memlists_per_segment(void);
  85 extern ACPI_STATUS acpidev_dr_get_mem_alignment(ACPI_HANDLE hdl, uint64_t *ap);
  86 
  87 /* Initialize support of DR operations. */
  88 extern void acpidev_dr_init(void);
  89 
  90 /* Scan for DR capable boards and setup environment for DR operations. */
  91 extern void acpidev_dr_check(acpidev_walk_info_t *infop);
  92 
  93 /*
  94  * Initialize DR interfaces to enable DR operations.
  95  */
  96 extern ACPI_STATUS acpidev_dr_initialize(dev_info_t *pdip);
  97 
  98 /* Get ACPI handle of the DR capable board. */
  99 extern ACPI_STATUS acpidev_dr_get_board_handle(uint_t board,
 100     ACPI_HANDLE *hdlp);
 101 
 102 /* Get board type of the DR capable board. */
 103 extern acpidev_board_type_t acpidev_dr_get_board_type(ACPI_HANDLE hdl);
 104 
 105 /* Get board number of the DR capable board. */
 106 extern ACPI_STATUS acpidev_dr_get_board_number(ACPI_HANDLE hdl,
 107     uint32_t *bnump);
 108 
 109 /* Get board name of the DR capable board. */
 110 extern ACPI_STATUS acpidev_dr_get_board_name(ACPI_HANDLE hdl,
 111     char *buf, size_t len);
 112 
 113 /* Get attachment point of the DR capable board. */
 114 extern ACPI_STATUS acpidev_dr_get_attachment_point(ACPI_HANDLE hdl,
 115     char *buf, size_t len);
 116 
 117 /*
 118  * Figure out device type of the object/device.
 119  * It only supports device types which may be involved in DR operations.
 120  */
 121 extern acpidev_class_id_t acpidev_dr_device_get_class(ACPI_HANDLE hdl);
 122 
 123 /* Get memory device index/id. */
 124 extern ACPI_STATUS acpidev_dr_device_get_memory_index(ACPI_HANDLE hdl,
 125     uint32_t *idxp);
 126 
 127 /* Check whether the device is a DR capable board or not. */
 128 extern int acpidev_dr_device_is_board(ACPI_HANDLE hdl);
 129 
 130 /* Check whether the device is present or not. */
 131 extern int acpidev_dr_device_is_present(ACPI_HANDLE hdl);
 132 
 133 /* Check whether the device is powered-on or not. */
 134 extern int acpidev_dr_device_is_powered(ACPI_HANDLE hdl);
 135 
 136 /* Check whether the device is DR capable. */
 137 extern int acpidev_dr_device_hotplug_capable(ACPI_HANDLE hdl);
 138 
 139 /* Check whether the device has an eject device list. */
 140 extern int acpidev_dr_device_has_edl(ACPI_HANDLE hdl);
 141 
 142 /*
 143  * Simulate OBP property interfaces to support drmach driver,
 144  * so we can keep drmach in consistency with SPARC version.
 145  * Return size of data copied to buf if it's big enough,
 146  * otherwise return size of buffer needed.
 147  */
 148 extern int acpidev_dr_device_getprop(ACPI_HANDLE hdl, char *name,
 149     caddr_t buf, size_t len);
 150 
 151 /*
 152  * Get "reg" or "assigned-address" property of the device.
 153  * Return "assigned-address" property if assigned is non-zero,
 154  * otherwise return "reg" property.
 155  * Caller needs to release returned resources by calling
 156  * acpidev_dr_device_free_regspec().
 157  */
 158 extern ACPI_STATUS acpidev_dr_device_get_regspec(ACPI_HANDLE hdl,
 159     boolean_t assigned, acpidev_regspec_t **regpp, uint_t *cntp);
 160 
 161 /* Free resources returned by acpidev_dr_device_get_regspec(). */
 162 extern void acpidev_dr_device_free_regspec(acpidev_regspec_t *regp,
 163     uint_t count);
 164 
 165 /* Walk devices in eject device list (ACPI _EDL method). */
 166 extern ACPI_STATUS acpidev_dr_device_walk_edl(ACPI_HANDLE hdl,
 167     ACPI_WALK_CALLBACK cb, void *arg, void **retval);
 168 
 169 /* Walk devices in eject dependency list (ACPI _EJD method). */
 170 extern ACPI_STATUS acpidev_dr_device_walk_ejd(ACPI_HANDLE hdl,
 171     ACPI_WALK_CALLBACK cb, void *arg, void **retval);
 172 
 173 /*
 174  * Walk child and dependent devices which may be involved in DR operations.
 175  * PCI host bridges embedded in physical processors may be presented in eject
 176  * device list instead of as children of processors.
 177  */
 178 extern ACPI_STATUS acpidev_dr_device_walk_device(ACPI_HANDLE hdl,
 179     uint_t max_lvl, ACPI_WALK_CALLBACK cb, void *arg, void **retval);
 180 
 181 /* Check whether the device is in working state without any error. */
 182 extern ACPI_STATUS acpidev_dr_device_check_status(ACPI_HANDLE hdl);
 183 
 184 /* Power on the device. */
 185 extern ACPI_STATUS acpidev_dr_device_poweron(ACPI_HANDLE hdl);
 186 
 187 /* Power off the device. */
 188 extern ACPI_STATUS acpidev_dr_device_poweroff(ACPI_HANDLE hdl);
 189 
 190 /*
 191  * Create device nodes for hot-added devices under hdl.
 192  * Return:
 193  * AE_OK: on success
 194  * AE_SUPPORT: if it's not capable of DR operation.
 195  * AE_ERROR: for other errors
 196  */
 197 extern ACPI_STATUS acpidev_dr_device_insert(ACPI_HANDLE hdl);
 198 
 199 /*
 200  * Destroy device nodes to be removed under hdl.
 201  * AE_OK: on success
 202  * AE_SUPPORT: if it's not capable of DR operation.
 203  * AE_ERROR: for other errors
 204  */
 205 extern ACPI_STATUS acpidev_dr_device_remove(ACPI_HANDLE hdl);
 206 
 207 /* Block dynamic reconfiguration operations. */
 208 extern void acpidev_dr_lock_all(void);
 209 
 210 /* Unblock dynamic reconfiguration operations. */
 211 extern void acpidev_dr_unlock_all(void);
 212 
 213 extern ACPI_STATUS acpidev_dr_allocate_cpuid(ACPI_HANDLE hdl,
 214     processorid_t *idp);
 215 extern ACPI_STATUS acpidev_dr_free_cpuid(ACPI_HANDLE hdl);
 216 
 217 /*
 218  * Query NUMA relative information for the CPU device.
 219  * It returns APIC id, Proximity id and latency information of the CPU device.
 220  * Latency information is retrieved from the ACPI _SLI method or the ACPI SLIT
 221  * table.
 222  */
 223 extern int acpidev_dr_get_cpu_numa_info(cpu_t *cp, void **hdlpp,
 224     uint32_t *apicidp, uint32_t *pxmidp, uint32_t *slicntp, uchar_t **slipp);
 225 
 226 /*
 227  * Release resources allocated by acpidev_dr_get_cpu_numa_info().
 228  */
 229 extern void acpidev_dr_free_cpu_numa_info(void *hdlp);
 230 
 231 /*
 232  * Query NUMA relative information for a memory device.
 233  * It returns proximity id and latency information of the memory device.
 234  * Latency information is obtained from the ACPI _SLI method or the ACPI
 235  * SLIT table.
 236  */
 237 extern ACPI_STATUS acpidev_dr_get_mem_numa_info(ACPI_HANDLE hdl,
 238     struct memlist *ml, void **hdlpp, uint32_t *pxmidp,
 239     uint32_t *slicntp, uchar_t **slipp);
 240 
 241 /*
 242  * Release resources allocated by acpidev_dr_get_mem_numa_info().
 243  */
 244 extern void acpidev_dr_free_mem_numa_info(void *hdlp);
 245 
 246 #endif  /* _KERNEL */
 247 
 248 #ifdef __cplusplus
 249 }
 250 #endif
 251 
 252 #endif  /* _SYS_ACPIDEV_DR_H */