1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef _SPARC64_MDESC_H 3*4882a593Smuzhiyun #define _SPARC64_MDESC_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <linux/types.h> 6*4882a593Smuzhiyun #include <linux/cpumask.h> 7*4882a593Smuzhiyun #include <asm/prom.h> 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun struct mdesc_handle; 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun /* Machine description operations are to be surrounded by grab and 12*4882a593Smuzhiyun * release calls. The mdesc_handle returned from the grab is 13*4882a593Smuzhiyun * the first argument to all of the operational calls that work 14*4882a593Smuzhiyun * on mdescs. 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun struct mdesc_handle *mdesc_grab(void); 17*4882a593Smuzhiyun void mdesc_release(struct mdesc_handle *); 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #define MDESC_NODE_NULL (~(u64)0) 20*4882a593Smuzhiyun #define MDESC_MAX_STR_LEN 256 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun u64 mdesc_node_by_name(struct mdesc_handle *handle, 23*4882a593Smuzhiyun u64 from_node, const char *name); 24*4882a593Smuzhiyun #define mdesc_for_each_node_by_name(__hdl, __node, __name) \ 25*4882a593Smuzhiyun for (__node = mdesc_node_by_name(__hdl, MDESC_NODE_NULL, __name); \ 26*4882a593Smuzhiyun (__node) != MDESC_NODE_NULL; \ 27*4882a593Smuzhiyun __node = mdesc_node_by_name(__hdl, __node, __name)) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* Access to property values returned from mdesc_get_property() are 30*4882a593Smuzhiyun * only valid inside of a mdesc_grab()/mdesc_release() sequence. 31*4882a593Smuzhiyun * Once mdesc_release() is called, the memory backed up by these 32*4882a593Smuzhiyun * pointers may reference freed up memory. 33*4882a593Smuzhiyun * 34*4882a593Smuzhiyun * Therefore callers must make copies of any property values 35*4882a593Smuzhiyun * they need. 36*4882a593Smuzhiyun * 37*4882a593Smuzhiyun * These same rules apply to mdesc_node_name(). 38*4882a593Smuzhiyun */ 39*4882a593Smuzhiyun const void *mdesc_get_property(struct mdesc_handle *handle, 40*4882a593Smuzhiyun u64 node, const char *name, int *lenp); 41*4882a593Smuzhiyun const char *mdesc_node_name(struct mdesc_handle *hp, u64 node); 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* MD arc iteration, the standard sequence is: 44*4882a593Smuzhiyun * 45*4882a593Smuzhiyun * unsigned long arc; 46*4882a593Smuzhiyun * mdesc_for_each_arc(arc, handle, node, MDESC_ARC_TYPE_{FWD,BACK}) { 47*4882a593Smuzhiyun * unsigned long target = mdesc_arc_target(handle, arc); 48*4882a593Smuzhiyun * ... 49*4882a593Smuzhiyun * } 50*4882a593Smuzhiyun */ 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun #define MDESC_ARC_TYPE_FWD "fwd" 53*4882a593Smuzhiyun #define MDESC_ARC_TYPE_BACK "back" 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from, 56*4882a593Smuzhiyun const char *arc_type); 57*4882a593Smuzhiyun #define mdesc_for_each_arc(__arc, __hdl, __node, __type) \ 58*4882a593Smuzhiyun for (__arc = mdesc_next_arc(__hdl, __node, __type); \ 59*4882a593Smuzhiyun (__arc) != MDESC_NODE_NULL; \ 60*4882a593Smuzhiyun __arc = mdesc_next_arc(__hdl, __arc, __type)) 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc); 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun void mdesc_update(void); 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun struct mdesc_notifier_client { 67*4882a593Smuzhiyun void (*add)(struct mdesc_handle *handle, u64 node, 68*4882a593Smuzhiyun const char *node_name); 69*4882a593Smuzhiyun void (*remove)(struct mdesc_handle *handle, u64 node, 70*4882a593Smuzhiyun const char *node_name); 71*4882a593Smuzhiyun const char *node_name; 72*4882a593Smuzhiyun struct mdesc_notifier_client *next; 73*4882a593Smuzhiyun }; 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun void mdesc_register_notifier(struct mdesc_notifier_client *client); 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun union md_node_info { 78*4882a593Smuzhiyun struct vdev_port { 79*4882a593Smuzhiyun u64 id; /* id */ 80*4882a593Smuzhiyun u64 parent_cfg_hdl; /* parent config handle */ 81*4882a593Smuzhiyun const char *name; /* name (property) */ 82*4882a593Smuzhiyun } vdev_port; 83*4882a593Smuzhiyun struct ds_port { 84*4882a593Smuzhiyun u64 id; /* id */ 85*4882a593Smuzhiyun } ds_port; 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun u64 mdesc_get_node(struct mdesc_handle *hp, const char *node_name, 89*4882a593Smuzhiyun union md_node_info *node_info); 90*4882a593Smuzhiyun int mdesc_get_node_info(struct mdesc_handle *hp, u64 node, 91*4882a593Smuzhiyun const char *node_name, union md_node_info *node_info); 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun void mdesc_fill_in_cpu_data(cpumask_t *mask); 94*4882a593Smuzhiyun void mdesc_populate_present_mask(cpumask_t *mask); 95*4882a593Smuzhiyun void mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask); 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun void sun4v_mdesc_init(void); 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun #endif 100