/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_OPL_CFG_H #define _SYS_OPL_CFG_H #pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { #endif /* * Hardware Descriptor. */ #include #define OPL_PSB_MODE 0x0 #define OPL_XSB_MODE 0x1 #define OPL_LSBID_MASK 0x1f /* * CPU device portid: * * 1 0 0 0 0 0 0 0 0 0 0 * 0 9 8 7 6 5 4 3 2 1 0 * --------------------------------------- * | 1 | LSB ID | CHIP | CORE | CPU | * --------------------------------------- */ #define OPL_CPUID_TO_LSB(devid) ((devid >> 5) & OPL_LSBID_MASK) #define OPL_CPU_CHIP(devid) ((devid >> 3) & 0x3) #define OPL_CORE(devid) ((devid >> 1) & 0x3) #define OPL_CPU(devid) ((devid & 0x001)) #define OPL_PORTID(board, chip) ((1 << 10) | (board << 5) | (chip << 3)) #define OPL_CPUID(board, chip, core, cpu) \ \ ((board << 5) | (chip << 3) | (core << 1) | (cpu)) /* * Dummy address space for a chip. */ #define OPL_PROC_AS(board, chip) \ \ ((1ULL << 46) | ((uint64_t)board << 40) | (1ULL << 39) | \ (1ULL << 33) | ((uint64_t)chip << 4)) /* * pseudo-mc portid: * * 1 0 0 0 0 0 0 0 0 0 0 * 0 9 8 7 6 5 4 3 2 1 0 * ------------------------------------- * | 0 | 1 | LSB ID | 0 | * ------------------------------------- */ #define OPL_LSB_TO_PSEUDOMC_PORTID(board) ((1 << 9) | (board << 4)) /* * Dummy address space for a pseudo memory node */ #define OPL_MC_AS(board) \ \ ((1ULL << 46) | ((uint64_t)board << 40) | (1ULL << 39) | \ (1ULL << 33)) /* * Defines used by the Jupiter bus-specific library (lfc_jupiter.so). * This library gets loaded into the user-level fcode interpreter * and provides bus-specific methods that are used by the Oberon * and the CMU-channel fcode drivers. */ /* * * IO port id: * * 1 0 0 0 0 0 0 0 0 0 0 * 0 9 8 7 6 5 4 3 2 1 0 * --------------------------------------- * | 0 0 | LSB ID | IO CHAN | LEAF | * --------------------------------------- */ #define OPL_PORTID_MASK 0x7FF #define OPL_IO_PORTID_TO_LSB(portid) (((portid) >> 4) & OPL_LSBID_MASK) #define OPL_PORTID_TO_CHANNEL(portid) (((portid) >> 1) & 0x7) #define OPL_PORTID_TO_LEAF(portid) ((portid) & 0x1) #define OPL_IO_PORTID(lsb, ch, leaf) \ (((lsb & OPL_LSBID_MASK) << 4) | ((ch & 0x7) << 1) | (leaf & 0x1)) #define OPL_ADDR_TO_LSB(hi) (((hi) >> 8) & OPL_LSBID_MASK) #define OPL_ADDR_TO_CHANNEL(hi) (((hi) >> 5) & 0x7) #define OPL_ADDR_TO_LEAF(hi, lo) \ (!(((hi) >> 7) & 0x1) && (((lo) >> 20) == 0x7)) #define OPL_ADDR_HI(lsb, ch) \ ((1 << 14) | ((lsb & OPL_LSBID_MASK) << 8) | ((ch & 0x7) << 5)) #define OPL_CMU_CHANNEL 4 #define OPL_OBERON_CHANNEL(ch) ((ch >= 0) && (ch <= 3)) #define OPL_VALID_CHANNEL(ch) ((ch >= 0) && (ch <= 4)) #define OPL_VALID_LEAF(leaf) ((leaf == 0) || (leaf == 1)) #if defined(_KERNEL) /* * We store the pointers to the following device nodes in this structure: * "pseudo-mc" * "cmp" * "pci" * * These nodes represent the different branches we create in the device * tree for each board during probe. We store them so that when a board * is unprobed, we can easily locate the branches and destroy them. */ typedef struct { dev_info_t *cfg_pseudo_mc; dev_info_t *cfg_cpu_chips[HWD_CPU_CHIPS_PER_CMU]; dev_info_t *cfg_cmuch_leaf; fco_handle_t cfg_cmuch_handle; char *cfg_cmuch_probe_str; dev_info_t *cfg_pcich_leaf[HWD_PCI_CHANNELS_PER_SB] [HWD_LEAVES_PER_PCI_CHANNEL]; fco_handle_t cfg_pcich_handle[HWD_PCI_CHANNELS_PER_SB] [HWD_LEAVES_PER_PCI_CHANNEL]; char *cfg_pcich_probe_str[HWD_PCI_CHANNELS_PER_SB] [HWD_LEAVES_PER_PCI_CHANNEL]; void *cfg_hwd; } opl_board_cfg_t; /* * Prototypes for the callback functions used in the DDI functions * used to perform device tree operations. * * init functions are used to find device nodes that are created * by Solaris during boot. * * create functions are used to initialize device nodes during DR. */ typedef int (*opl_init_func_t)(dev_info_t *, char *, int); typedef int (*opl_create_func_t)(dev_info_t *, void *, uint_t); /* * The following probe structure carries all the information required * at various points during probe. This structure serves two purposes: * * 1. It allows us to streamline functions and have them accept just * a single argument. * * 2. It allows us to pass information to the DDI callbacks. DDI * callbacks are allowed only one argument. It also allows * us to return information from those callbacks. * * The probe structure carries a snapshot of the hardware descriptor * taken at the beginning of a probe. */ typedef struct { hwd_header_t *pr_hdr; hwd_sb_status_t *pr_sb_status; hwd_domain_info_t *pr_dinfo; hwd_sb_t *pr_sb; int pr_board; int pr_cpu_chip; int pr_core; int pr_cpu; int pr_channel; int pr_channel_status; int pr_leaf; int pr_leaf_status; opl_create_func_t pr_create; dev_info_t *pr_parent; dev_info_t *pr_node; int pr_hold; unsigned pr_cpu_impl; } opl_probe_t; #define OPL_STR_LEN 256 #define OPL_HI(value) ((uint32_t)((uint64_t)(value) >> 32)) #define OPL_LO(value) ((uint32_t)(value)) typedef struct { uint32_t addr_hi; uint32_t addr_lo; } opl_addr_t; typedef struct { uint32_t rg_addr_hi; uint32_t rg_addr_lo; uint32_t rg_size_hi; uint32_t rg_size_lo; } opl_range_t; typedef struct { int mc_bank; uint32_t mc_hi; uint32_t mc_lo; } opl_mc_addr_t; /* * Convenience macros for DDI property operations. The functions that * DDI provides for getting and updating properties are not symmetric * either in their names or in the number of arguments. These macros * hide the gory details and provide a symmetric way to get and * set properties. */ #define opl_prop_get_string(dip, name, bufp, lenp) \ ddi_getlongprop(DDI_DEV_T_ANY, dip, \ DDI_PROP_DONTPASS, name, (caddr_t)bufp, lenp) #define opl_prop_get_int(dip, name, value, defvalue) \ ( \ *(value) = ddi_getprop(DDI_DEV_T_ANY, dip, \ DDI_PROP_DONTPASS, name, defvalue), \ (*(value) == defvalue) ? DDI_PROP_NOT_FOUND : DDI_PROP_SUCCESS \ ) #define opl_prop_get_int_array(dip, name, data, nelems) \ ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, \ DDI_PROP_DONTPASS, name, (int **)&data, (uint_t *)&nelems) #define OPL_GET_PROP(type, dip, name, value, arg) \ opl_prop_get_##type(dip, name, value, arg) #define OPL_GET_PROP_ARRAY(type, dip, name, values, nvalues) \ opl_prop_get_##type##_array(dip, name, values, nvalues) #define OPL_FREE_PROP(data) \ ddi_prop_free((void *)data) #define OPL_UPDATE_PROP_ERR(ret, name) \ if (ret != DDI_PROP_SUCCESS) { \ cmn_err(CE_WARN, "%s (%d): %s update property error (%d)",\ __FILE__, __LINE__, name, ret); \ return (DDI_WALK_ERROR); \ } #define OPL_UPDATE_PROP(type, dip, name, value) \ ret = ndi_prop_update_##type(DDI_DEV_T_NONE, dip, name, value); \ OPL_UPDATE_PROP_ERR(ret, name) #define OPL_UPDATE_PROP_ARRAY(type, dip, name, values, nvalues) \ ret = ndi_prop_update_##type##_array(DDI_DEV_T_NONE, dip, \ name, values, nvalues); \ OPL_UPDATE_PROP_ERR(ret, name) /* * Node names for the different nodes supported in OPL. */ #define OPL_PSEUDO_MC_NODE "pseudo-mc" #define OPL_CPU_CHIP_NODE "cmp" #define OPL_CORE_NODE "core" #define OPL_CPU_NODE "cpu" #define OPL_PCI_LEAF_NODE "pci" typedef struct { char *fc_service; fc_ops_t *fc_op; } opl_fc_ops_t; /* * Functions used by drmach */ extern int opl_probe_sb(int, unsigned *); extern int opl_unprobe_sb(int); extern int opl_read_hwd(int, hwd_header_t **, hwd_sb_status_t **, hwd_domain_info_t **, hwd_sb_t **); extern void opl_hold_devtree(void); extern void opl_release_devtree(void); extern int oplcfg_pa_swap(int from, int to); extern int opl_init_cfg(); #endif /* _KERNEL */ #ifdef __cplusplus } #endif #endif /* _SYS_OPL_CFG_H */