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 <sys/acpi/acpi.h>
38#include <sys/acpica.h>
39#include <sys/acpidev.h>
40#include <sys/acpidev_rsc.h>
41
42#ifdef __cplusplus
43extern "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
67typedef 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. */
76extern int acpidev_dr_capable(void);
77
78extern uint32_t acpidev_dr_max_boards(void);
79extern uint32_t acpidev_dr_max_mem_units_per_board(void);
80extern uint32_t acpidev_dr_max_io_units_per_board(void);
81extern uint32_t acpidev_dr_max_cmp_units_per_board(void);
82extern uint32_t acpidev_dr_max_cpu_units_per_cmp(void);
83extern uint32_t acpidev_dr_max_segments_per_mem_device(void);
84extern uint32_t acpidev_dr_max_memlists_per_segment(void);
85extern ACPI_STATUS acpidev_dr_get_mem_alignment(ACPI_HANDLE hdl, uint64_t *ap);
86
87/* Initialize support of DR operations. */
88extern void acpidev_dr_init(void);
89
90/* Scan for DR capable boards and setup environment for DR operations. */
91extern void acpidev_dr_check(acpidev_walk_info_t *infop);
92
93/*
94 * Initialize DR interfaces to enable DR operations.
95 */
96extern ACPI_STATUS acpidev_dr_initialize(dev_info_t *pdip);
97
98/* Get ACPI handle of the DR capable board. */
99extern ACPI_STATUS acpidev_dr_get_board_handle(uint_t board,
100    ACPI_HANDLE *hdlp);
101
102/* Get board type of the DR capable board. */
103extern acpidev_board_type_t acpidev_dr_get_board_type(ACPI_HANDLE hdl);
104
105/* Get board number of the DR capable board. */
106extern ACPI_STATUS acpidev_dr_get_board_number(ACPI_HANDLE hdl,
107    uint32_t *bnump);
108
109/* Get board name of the DR capable board. */
110extern 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. */
114extern 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 */
121extern acpidev_class_id_t acpidev_dr_device_get_class(ACPI_HANDLE hdl);
122
123/* Get memory device index/id. */
124extern 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. */
128extern int acpidev_dr_device_is_board(ACPI_HANDLE hdl);
129
130/* Check whether the device is present or not. */
131extern int acpidev_dr_device_is_present(ACPI_HANDLE hdl);
132
133/* Check whether the device is powered-on or not. */
134extern int acpidev_dr_device_is_powered(ACPI_HANDLE hdl);
135
136/* Check whether the device is DR capable. */
137extern int acpidev_dr_device_hotplug_capable(ACPI_HANDLE hdl);
138
139/* Check whether the device has an eject device list. */
140extern 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 */
148extern 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 */
158extern 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(). */
162extern 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). */
166extern 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). */
170extern 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 */
178extern 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. */
182extern ACPI_STATUS acpidev_dr_device_check_status(ACPI_HANDLE hdl);
183
184/* Power on the device. */
185extern ACPI_STATUS acpidev_dr_device_poweron(ACPI_HANDLE hdl);
186
187/* Power off the device. */
188extern 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 */
197extern 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 */
205extern ACPI_STATUS acpidev_dr_device_remove(ACPI_HANDLE hdl);
206
207/* Block dynamic reconfiguration operations. */
208extern void acpidev_dr_lock_all(void);
209
210/* Unblock dynamic reconfiguration operations. */
211extern void acpidev_dr_unlock_all(void);
212
213extern ACPI_STATUS acpidev_dr_allocate_cpuid(ACPI_HANDLE hdl,
214    processorid_t *idp);
215extern 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 */
223extern 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 */
229extern 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 */
237extern 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 */
244extern 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 */
253