11772Sjl139090 /* 21772Sjl139090 * CDDL HEADER START 31772Sjl139090 * 41772Sjl139090 * The contents of this file are subject to the terms of the 51772Sjl139090 * Common Development and Distribution License (the "License"). 61772Sjl139090 * You may not use this file except in compliance with the License. 71772Sjl139090 * 81772Sjl139090 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91772Sjl139090 * or http://www.opensolaris.org/os/licensing. 101772Sjl139090 * See the License for the specific language governing permissions 111772Sjl139090 * and limitations under the License. 121772Sjl139090 * 131772Sjl139090 * When distributing Covered Code, include this CDDL HEADER in each 141772Sjl139090 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151772Sjl139090 * If applicable, add the following below this CDDL HEADER, with the 161772Sjl139090 * fields enclosed by brackets "[]" replaced with your own identifying 171772Sjl139090 * information: Portions Copyright [yyyy] [name of copyright owner] 181772Sjl139090 * 191772Sjl139090 * CDDL HEADER END 201772Sjl139090 */ 211772Sjl139090 /* 221772Sjl139090 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 231772Sjl139090 * Use is subject to license terms. 241772Sjl139090 */ 251772Sjl139090 261772Sjl139090 #pragma ident "%Z%%M% %I% %E% SMI" 271772Sjl139090 281772Sjl139090 #include <sys/cpuvar.h> 291772Sjl139090 #include <sys/systm.h> 301772Sjl139090 #include <sys/sysmacros.h> 311772Sjl139090 #include <sys/promif.h> 321772Sjl139090 #include <sys/platform_module.h> 331772Sjl139090 #include <sys/cmn_err.h> 341772Sjl139090 #include <sys/errno.h> 351772Sjl139090 #include <sys/machsystm.h> 361772Sjl139090 #include <sys/bootconf.h> 371772Sjl139090 #include <sys/nvpair.h> 381772Sjl139090 #include <sys/kobj.h> 391772Sjl139090 #include <sys/mem_cage.h> 401772Sjl139090 #include <sys/opl.h> 411772Sjl139090 #include <sys/scfd/scfostoescf.h> 421772Sjl139090 #include <sys/cpu_sgnblk_defs.h> 431772Sjl139090 #include <sys/utsname.h> 441772Sjl139090 #include <sys/ddi.h> 451772Sjl139090 #include <sys/sunndi.h> 461772Sjl139090 #include <sys/lgrp.h> 471772Sjl139090 #include <sys/memnode.h> 481772Sjl139090 #include <sys/sysmacros.h> 491772Sjl139090 #include <vm/vm_dep.h> 501772Sjl139090 511772Sjl139090 int (*opl_get_mem_unum)(int, uint64_t, char *, int, int *); 522214Sav145390 int (*opl_get_mem_sid)(char *unum, char *buf, int buflen, int *lenp); 532214Sav145390 int (*opl_get_mem_offset)(uint64_t paddr, uint64_t *offp); 542214Sav145390 int (*opl_get_mem_addr)(char *unum, char *sid, 552214Sav145390 uint64_t offset, uint64_t *paddr); 561772Sjl139090 571772Sjl139090 /* Memory for fcode claims. 16k times # maximum possible IO units */ 581772Sjl139090 #define EFCODE_SIZE (OPL_MAX_BOARDS * OPL_MAX_IO_UNITS_PER_BOARD * 0x4000) 591772Sjl139090 int efcode_size = EFCODE_SIZE; 601772Sjl139090 611772Sjl139090 #define OPL_MC_MEMBOARD_SHIFT 38 /* Boards on 256BG boundary */ 621772Sjl139090 631772Sjl139090 /* Set the maximum number of boards for DR */ 641772Sjl139090 int opl_boards = OPL_MAX_BOARDS; 651772Sjl139090 661772Sjl139090 void sgn_update_all_cpus(ushort_t, uchar_t, uchar_t); 671772Sjl139090 681772Sjl139090 extern int tsb_lgrp_affinity; 691772Sjl139090 701772Sjl139090 int opl_tsb_spares = (OPL_MAX_BOARDS) * (OPL_MAX_PCICH_UNITS_PER_BOARD) * 711772Sjl139090 (OPL_MAX_TSBS_PER_PCICH); 721772Sjl139090 731772Sjl139090 pgcnt_t opl_startup_cage_size = 0; 741772Sjl139090 752241Shuah static opl_model_info_t opl_models[] = { 76*3123Ssubhan { "FF1", OPL_MAX_BOARDS_FF1, FF1, STD_DISPATCH_TABLE }, 77*3123Ssubhan { "FF2", OPL_MAX_BOARDS_FF2, FF2, STD_DISPATCH_TABLE }, 78*3123Ssubhan { "DC1", OPL_MAX_BOARDS_DC1, DC1, STD_DISPATCH_TABLE }, 79*3123Ssubhan { "DC2", OPL_MAX_BOARDS_DC2, DC2, EXT_DISPATCH_TABLE }, 80*3123Ssubhan { "DC3", OPL_MAX_BOARDS_DC3, DC3, EXT_DISPATCH_TABLE }, 812241Shuah }; 822241Shuah static int opl_num_models = sizeof (opl_models)/sizeof (opl_model_info_t); 832241Shuah 84*3123Ssubhan /* 85*3123Ssubhan * opl_cur_model defaults to FF1. 86*3123Ssubhan */ 87*3123Ssubhan static opl_model_info_t *opl_cur_model = &opl_models[0]; 882241Shuah 891772Sjl139090 static struct memlist *opl_memlist_per_board(struct memlist *ml); 901772Sjl139090 911772Sjl139090 int 921772Sjl139090 set_platform_max_ncpus(void) 931772Sjl139090 { 941772Sjl139090 return (OPL_MAX_CPU_PER_BOARD * OPL_MAX_BOARDS); 951772Sjl139090 } 961772Sjl139090 971772Sjl139090 int 981772Sjl139090 set_platform_tsb_spares(void) 991772Sjl139090 { 1001772Sjl139090 return (MIN(opl_tsb_spares, MAX_UPA)); 1011772Sjl139090 } 1021772Sjl139090 1032241Shuah static void 1042241Shuah set_model_info() 1052241Shuah { 106*3123Ssubhan extern int ts_dispatch_extended; 1072241Shuah char name[MAXSYSNAME]; 1082241Shuah int i; 1092241Shuah 1102241Shuah /* 1112241Shuah * Get model name from the root node. 1122241Shuah * 1132241Shuah * We are using the prom device tree since, at this point, 1142241Shuah * the Solaris device tree is not yet setup. 1152241Shuah */ 1162241Shuah (void) prom_getprop(prom_rootnode(), "model", (caddr_t)name); 1172241Shuah 1182241Shuah for (i = 0; i < opl_num_models; i++) { 1192241Shuah if (strncmp(name, opl_models[i].model_name, MAXSYSNAME) == 0) { 1202241Shuah opl_cur_model = &opl_models[i]; 1212241Shuah break; 1222241Shuah } 1232241Shuah } 124*3123Ssubhan 1252241Shuah if (i == opl_num_models) 126*3123Ssubhan halt("No valid OPL model is found!"); 127*3123Ssubhan 128*3123Ssubhan if ((opl_cur_model->model_cmds & EXT_DISPATCH_TABLE) && 129*3123Ssubhan (ts_dispatch_extended == -1)) { 130*3123Ssubhan /* 131*3123Ssubhan * Based on a platform model, select a dispatch table. 132*3123Ssubhan * Only DC2 and DC3 systems uses the alternate/extended 133*3123Ssubhan * TS dispatch table. 134*3123Ssubhan * FF1, FF2 and DC1 systems used standard dispatch tables. 135*3123Ssubhan */ 136*3123Ssubhan ts_dispatch_extended = 1; 137*3123Ssubhan } 138*3123Ssubhan 1392241Shuah } 1402241Shuah 1412241Shuah static void 1422241Shuah set_max_mmu_ctxdoms() 1432241Shuah { 1442241Shuah extern uint_t max_mmu_ctxdoms; 1452241Shuah int max_boards; 1462241Shuah 1472241Shuah /* 1482241Shuah * From the model, get the maximum number of boards 1492241Shuah * supported and set the value accordingly. If the model 1502241Shuah * could not be determined or recognized, we assume the max value. 1512241Shuah */ 1522241Shuah if (opl_cur_model == NULL) 1532241Shuah max_boards = OPL_MAX_BOARDS; 1542241Shuah else 1552241Shuah max_boards = opl_cur_model->model_max_boards; 1562241Shuah 1572241Shuah /* 1582241Shuah * On OPL, cores and MMUs are one-to-one. 1592241Shuah */ 1602241Shuah max_mmu_ctxdoms = OPL_MAX_CORE_UNITS_PER_BOARD * max_boards; 1612241Shuah } 1622241Shuah 1631772Sjl139090 #pragma weak mmu_init_large_pages 1641772Sjl139090 1651772Sjl139090 void 1661772Sjl139090 set_platform_defaults(void) 1671772Sjl139090 { 1681772Sjl139090 extern char *tod_module_name; 1691772Sjl139090 extern void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int); 1701772Sjl139090 extern void mmu_init_large_pages(size_t); 1711772Sjl139090 1721772Sjl139090 /* Set the CPU signature function pointer */ 1731772Sjl139090 cpu_sgn_func = cpu_sgn_update; 1741772Sjl139090 1751772Sjl139090 /* Set appropriate tod module for OPL platform */ 1761772Sjl139090 ASSERT(tod_module_name == NULL); 1771772Sjl139090 tod_module_name = "todopl"; 1781772Sjl139090 1791772Sjl139090 if ((mmu_page_sizes == max_mmu_page_sizes) && 1802659Ssusans (mmu_ism_pagesize != DEFAULT_ISM_PAGESIZE)) { 1811772Sjl139090 if (&mmu_init_large_pages) 1821772Sjl139090 mmu_init_large_pages(mmu_ism_pagesize); 1831772Sjl139090 } 1841772Sjl139090 1851772Sjl139090 tsb_lgrp_affinity = 1; 1862241Shuah 1872241Shuah set_model_info(); 1882241Shuah set_max_mmu_ctxdoms(); 1891772Sjl139090 } 1901772Sjl139090 1911772Sjl139090 /* 1921772Sjl139090 * Convert logical a board number to a physical one. 1931772Sjl139090 */ 1941772Sjl139090 1951772Sjl139090 #define LSBPROP "board#" 1961772Sjl139090 #define PSBPROP "physical-board#" 1971772Sjl139090 1981772Sjl139090 int 1991772Sjl139090 opl_get_physical_board(int id) 2001772Sjl139090 { 2011772Sjl139090 dev_info_t *root_dip, *dip = NULL; 2021772Sjl139090 char *dname = NULL; 2031772Sjl139090 int circ; 2041772Sjl139090 2051772Sjl139090 pnode_t pnode; 2061772Sjl139090 char pname[MAXSYSNAME] = {0}; 2071772Sjl139090 2081772Sjl139090 int lsb_id; /* Logical System Board ID */ 2091772Sjl139090 int psb_id; /* Physical System Board ID */ 2101772Sjl139090 2111772Sjl139090 2121772Sjl139090 /* 2131772Sjl139090 * This function is called on early stage of bootup when the 2141772Sjl139090 * kernel device tree is not initialized yet, and also 2151772Sjl139090 * later on when the device tree is up. We want to try 2161772Sjl139090 * the fast track first. 2171772Sjl139090 */ 2181772Sjl139090 root_dip = ddi_root_node(); 2191772Sjl139090 if (root_dip) { 2201772Sjl139090 /* Get from devinfo node */ 2211772Sjl139090 ndi_devi_enter(root_dip, &circ); 2221772Sjl139090 for (dip = ddi_get_child(root_dip); dip; 2231772Sjl139090 dip = ddi_get_next_sibling(dip)) { 2241772Sjl139090 2251772Sjl139090 dname = ddi_node_name(dip); 2261772Sjl139090 if (strncmp(dname, "pseudo-mc", 9) != 0) 2271772Sjl139090 continue; 2281772Sjl139090 2291772Sjl139090 if ((lsb_id = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 2301772Sjl139090 DDI_PROP_DONTPASS, LSBPROP, -1)) == -1) 2311772Sjl139090 continue; 2321772Sjl139090 2331772Sjl139090 if (id == lsb_id) { 2341772Sjl139090 if ((psb_id = (int)ddi_getprop(DDI_DEV_T_ANY, 2351772Sjl139090 dip, DDI_PROP_DONTPASS, PSBPROP, -1)) 2361772Sjl139090 == -1) { 2371772Sjl139090 ndi_devi_exit(root_dip, circ); 2381772Sjl139090 return (-1); 2391772Sjl139090 } else { 2401772Sjl139090 ndi_devi_exit(root_dip, circ); 2411772Sjl139090 return (psb_id); 2421772Sjl139090 } 2431772Sjl139090 } 2441772Sjl139090 } 2451772Sjl139090 ndi_devi_exit(root_dip, circ); 2461772Sjl139090 } 2471772Sjl139090 2481772Sjl139090 /* 2491772Sjl139090 * We do not have the kernel device tree, or we did not 2501772Sjl139090 * find the node for some reason (let's say the kernel 2511772Sjl139090 * device tree was modified), let's try the OBP tree. 2521772Sjl139090 */ 2531772Sjl139090 pnode = prom_rootnode(); 2541772Sjl139090 for (pnode = prom_childnode(pnode); pnode; 2551772Sjl139090 pnode = prom_nextnode(pnode)) { 2561772Sjl139090 2571772Sjl139090 if ((prom_getprop(pnode, "name", (caddr_t)pname) == -1) || 2581772Sjl139090 (strncmp(pname, "pseudo-mc", 9) != 0)) 2591772Sjl139090 continue; 2601772Sjl139090 2611772Sjl139090 if (prom_getprop(pnode, LSBPROP, (caddr_t)&lsb_id) == -1) 2621772Sjl139090 continue; 2631772Sjl139090 2641772Sjl139090 if (id == lsb_id) { 2651772Sjl139090 if (prom_getprop(pnode, PSBPROP, 2661772Sjl139090 (caddr_t)&psb_id) == -1) { 2671772Sjl139090 return (-1); 2681772Sjl139090 } else { 2691772Sjl139090 return (psb_id); 2701772Sjl139090 } 2711772Sjl139090 } 2721772Sjl139090 } 2731772Sjl139090 2741772Sjl139090 return (-1); 2751772Sjl139090 } 2761772Sjl139090 2771772Sjl139090 /* 2781772Sjl139090 * For OPL it's possible that memory from two or more successive boards 2791772Sjl139090 * will be contiguous across the boards, and therefore represented as a 2801772Sjl139090 * single chunk. 2811772Sjl139090 * This function splits such chunks down the board boundaries. 2821772Sjl139090 */ 2831772Sjl139090 static struct memlist * 2841772Sjl139090 opl_memlist_per_board(struct memlist *ml) 2851772Sjl139090 { 2861772Sjl139090 uint64_t ssize, low, high, boundary; 2871772Sjl139090 struct memlist *head, *tail, *new; 2881772Sjl139090 2891772Sjl139090 ssize = (1ull << OPL_MC_MEMBOARD_SHIFT); 2901772Sjl139090 2911772Sjl139090 head = tail = NULL; 2921772Sjl139090 2931772Sjl139090 for (; ml; ml = ml->next) { 2941772Sjl139090 low = (uint64_t)ml->address; 2951772Sjl139090 high = low+(uint64_t)(ml->size); 2961772Sjl139090 while (low < high) { 2971772Sjl139090 boundary = roundup(low+1, ssize); 2981772Sjl139090 boundary = MIN(high, boundary); 2991772Sjl139090 new = kmem_zalloc(sizeof (struct memlist), KM_SLEEP); 3001772Sjl139090 new->address = low; 3011772Sjl139090 new->size = boundary - low; 3021772Sjl139090 if (head == NULL) 3031772Sjl139090 head = new; 3041772Sjl139090 if (tail) { 3051772Sjl139090 tail->next = new; 3061772Sjl139090 new->prev = tail; 3071772Sjl139090 } 3081772Sjl139090 tail = new; 3091772Sjl139090 low = boundary; 3101772Sjl139090 } 3111772Sjl139090 } 3121772Sjl139090 return (head); 3131772Sjl139090 } 3141772Sjl139090 3151772Sjl139090 void 3161772Sjl139090 set_platform_cage_params(void) 3171772Sjl139090 { 3181772Sjl139090 extern pgcnt_t total_pages; 3191772Sjl139090 extern struct memlist *phys_avail; 3201772Sjl139090 struct memlist *ml, *tml; 3211772Sjl139090 int ret; 3221772Sjl139090 3231772Sjl139090 if (kernel_cage_enable) { 3241772Sjl139090 pgcnt_t preferred_cage_size; 3251772Sjl139090 3261772Sjl139090 preferred_cage_size = 3271772Sjl139090 MAX(opl_startup_cage_size, total_pages / 256); 3281772Sjl139090 3291772Sjl139090 ml = opl_memlist_per_board(phys_avail); 3301772Sjl139090 3311772Sjl139090 kcage_range_lock(); 3321772Sjl139090 /* 3331772Sjl139090 * Note: we are assuming that post has load the 3341772Sjl139090 * whole show in to the high end of memory. Having 3351772Sjl139090 * taken this leap, we copy the whole of phys_avail 3361772Sjl139090 * the glist and arrange for the cage to grow 3371772Sjl139090 * downward (descending pfns). 3381772Sjl139090 */ 3391772Sjl139090 ret = kcage_range_init(ml, 1); 3401772Sjl139090 3411772Sjl139090 /* free the memlist */ 3421772Sjl139090 do { 3431772Sjl139090 tml = ml->next; 3441772Sjl139090 kmem_free(ml, sizeof (struct memlist)); 3451772Sjl139090 ml = tml; 3461772Sjl139090 } while (ml != NULL); 3471772Sjl139090 3481772Sjl139090 if (ret == 0) 3491772Sjl139090 kcage_init(preferred_cage_size); 3501772Sjl139090 kcage_range_unlock(); 3511772Sjl139090 } 3521772Sjl139090 3531772Sjl139090 if (kcage_on) 3541772Sjl139090 cmn_err(CE_NOTE, "!DR Kernel Cage is ENABLED"); 3551772Sjl139090 else 3561772Sjl139090 cmn_err(CE_NOTE, "!DR Kernel Cage is DISABLED"); 3571772Sjl139090 } 3581772Sjl139090 3591772Sjl139090 /*ARGSUSED*/ 3601772Sjl139090 int 3611772Sjl139090 plat_cpu_poweron(struct cpu *cp) 3621772Sjl139090 { 3631772Sjl139090 int (*opl_cpu_poweron)(struct cpu *) = NULL; 3641772Sjl139090 3651772Sjl139090 opl_cpu_poweron = 3661772Sjl139090 (int (*)(struct cpu *))kobj_getsymvalue("drmach_cpu_poweron", 0); 3671772Sjl139090 3681772Sjl139090 if (opl_cpu_poweron == NULL) 3691772Sjl139090 return (ENOTSUP); 3701772Sjl139090 else 3711772Sjl139090 return ((opl_cpu_poweron)(cp)); 3721772Sjl139090 3731772Sjl139090 } 3741772Sjl139090 3751772Sjl139090 /*ARGSUSED*/ 3761772Sjl139090 int 3771772Sjl139090 plat_cpu_poweroff(struct cpu *cp) 3781772Sjl139090 { 3791772Sjl139090 int (*opl_cpu_poweroff)(struct cpu *) = NULL; 3801772Sjl139090 3811772Sjl139090 opl_cpu_poweroff = 3821772Sjl139090 (int (*)(struct cpu *))kobj_getsymvalue("drmach_cpu_poweroff", 0); 3831772Sjl139090 3841772Sjl139090 if (opl_cpu_poweroff == NULL) 3851772Sjl139090 return (ENOTSUP); 3861772Sjl139090 else 3871772Sjl139090 return ((opl_cpu_poweroff)(cp)); 3881772Sjl139090 3891772Sjl139090 } 3901772Sjl139090 3911772Sjl139090 int 3921772Sjl139090 plat_max_boards(void) 3931772Sjl139090 { 3941772Sjl139090 return (OPL_MAX_BOARDS); 3951772Sjl139090 } 3961772Sjl139090 3971772Sjl139090 int 3981772Sjl139090 plat_max_cpu_units_per_board(void) 3991772Sjl139090 { 4001772Sjl139090 return (OPL_MAX_CPU_PER_BOARD); 4011772Sjl139090 } 4021772Sjl139090 4031772Sjl139090 int 4041772Sjl139090 plat_max_mem_units_per_board(void) 4051772Sjl139090 { 4061772Sjl139090 return (OPL_MAX_MEM_UNITS_PER_BOARD); 4071772Sjl139090 } 4081772Sjl139090 4091772Sjl139090 int 4101772Sjl139090 plat_max_io_units_per_board(void) 4111772Sjl139090 { 4121772Sjl139090 return (OPL_MAX_IO_UNITS_PER_BOARD); 4131772Sjl139090 } 4141772Sjl139090 4151772Sjl139090 int 4161772Sjl139090 plat_max_cmp_units_per_board(void) 4171772Sjl139090 { 4181772Sjl139090 return (OPL_MAX_CMP_UNITS_PER_BOARD); 4191772Sjl139090 } 4201772Sjl139090 4211772Sjl139090 int 4221772Sjl139090 plat_max_core_units_per_board(void) 4231772Sjl139090 { 4241772Sjl139090 return (OPL_MAX_CORE_UNITS_PER_BOARD); 4251772Sjl139090 } 4261772Sjl139090 4271772Sjl139090 int 4281772Sjl139090 plat_pfn_to_mem_node(pfn_t pfn) 4291772Sjl139090 { 4301772Sjl139090 return (pfn >> mem_node_pfn_shift); 4311772Sjl139090 } 4321772Sjl139090 4331772Sjl139090 /* ARGSUSED */ 4341772Sjl139090 void 4351772Sjl139090 plat_build_mem_nodes(u_longlong_t *list, size_t nelems) 4361772Sjl139090 { 4371772Sjl139090 size_t elem; 4381772Sjl139090 pfn_t basepfn; 4391772Sjl139090 pgcnt_t npgs; 4401772Sjl139090 uint64_t boundary, ssize; 4411772Sjl139090 uint64_t low, high; 4421772Sjl139090 4431772Sjl139090 /* 4441772Sjl139090 * OPL mem slices are always aligned on a 256GB boundary. 4451772Sjl139090 */ 4461772Sjl139090 mem_node_pfn_shift = OPL_MC_MEMBOARD_SHIFT - MMU_PAGESHIFT; 4471772Sjl139090 mem_node_physalign = 0; 4481772Sjl139090 4491772Sjl139090 /* 4501772Sjl139090 * Boot install lists are arranged <addr, len>, <addr, len>, ... 4511772Sjl139090 */ 4521772Sjl139090 ssize = (1ull << OPL_MC_MEMBOARD_SHIFT); 4531772Sjl139090 for (elem = 0; elem < nelems; elem += 2) { 4541772Sjl139090 low = (uint64_t)list[elem]; 4551772Sjl139090 high = low+(uint64_t)(list[elem+1]); 4561772Sjl139090 while (low < high) { 4571772Sjl139090 boundary = roundup(low+1, ssize); 4581772Sjl139090 boundary = MIN(high, boundary); 4591772Sjl139090 basepfn = btop(low); 4601772Sjl139090 npgs = btop(boundary - low); 4611772Sjl139090 mem_node_add_slice(basepfn, basepfn + npgs - 1); 4621772Sjl139090 low = boundary; 4631772Sjl139090 } 4641772Sjl139090 } 4651772Sjl139090 } 4661772Sjl139090 4671772Sjl139090 /* 4681772Sjl139090 * Find the CPU associated with a slice at boot-time. 4691772Sjl139090 */ 4701772Sjl139090 void 4711772Sjl139090 plat_fill_mc(pnode_t nodeid) 4721772Sjl139090 { 4731772Sjl139090 int board; 4741772Sjl139090 int memnode; 4751772Sjl139090 struct { 4761772Sjl139090 uint64_t addr; 4771772Sjl139090 uint64_t size; 4781772Sjl139090 } mem_range; 4791772Sjl139090 4801772Sjl139090 if (prom_getprop(nodeid, "board#", (caddr_t)&board) < 0) { 4811772Sjl139090 panic("Can not find board# property in mc node %x", nodeid); 4821772Sjl139090 } 4831772Sjl139090 if (prom_getprop(nodeid, "sb-mem-ranges", (caddr_t)&mem_range) < 0) { 4841772Sjl139090 panic("Can not find sb-mem-ranges property in mc node %x", 4851772Sjl139090 nodeid); 4861772Sjl139090 } 4871772Sjl139090 memnode = mem_range.addr >> OPL_MC_MEMBOARD_SHIFT; 4881772Sjl139090 plat_assign_lgrphand_to_mem_node(board, memnode); 4891772Sjl139090 } 4901772Sjl139090 4911772Sjl139090 /* 4921772Sjl139090 * Return the platform handle for the lgroup containing the given CPU 4931772Sjl139090 * 4941772Sjl139090 * For OPL, lgroup platform handle == board #. 4951772Sjl139090 */ 4961772Sjl139090 4971772Sjl139090 extern int mpo_disabled; 4981772Sjl139090 extern lgrp_handle_t lgrp_default_handle; 4991772Sjl139090 5001772Sjl139090 lgrp_handle_t 5011772Sjl139090 plat_lgrp_cpu_to_hand(processorid_t id) 5021772Sjl139090 { 5031772Sjl139090 lgrp_handle_t plathand; 5041772Sjl139090 5051772Sjl139090 /* 5061772Sjl139090 * Return the real platform handle for the CPU until 5071772Sjl139090 * such time as we know that MPO should be disabled. 5081772Sjl139090 * At that point, we set the "mpo_disabled" flag to true, 5091772Sjl139090 * and from that point on, return the default handle. 5101772Sjl139090 * 5111772Sjl139090 * By the time we know that MPO should be disabled, the 5121772Sjl139090 * first CPU will have already been added to a leaf 5131772Sjl139090 * lgroup, but that's ok. The common lgroup code will 5141772Sjl139090 * double check that the boot CPU is in the correct place, 5151772Sjl139090 * and in the case where mpo should be disabled, will move 5161772Sjl139090 * it to the root if necessary. 5171772Sjl139090 */ 5181772Sjl139090 if (mpo_disabled) { 5191772Sjl139090 /* If MPO is disabled, return the default (UMA) handle */ 5201772Sjl139090 plathand = lgrp_default_handle; 5211772Sjl139090 } else 5221772Sjl139090 plathand = (lgrp_handle_t)LSB_ID(id); 5231772Sjl139090 return (plathand); 5241772Sjl139090 } 5251772Sjl139090 5261772Sjl139090 /* 5271772Sjl139090 * Platform specific lgroup initialization 5281772Sjl139090 */ 5291772Sjl139090 void 5301772Sjl139090 plat_lgrp_init(void) 5311772Sjl139090 { 5321772Sjl139090 extern uint32_t lgrp_expand_proc_thresh; 5331772Sjl139090 extern uint32_t lgrp_expand_proc_diff; 5341772Sjl139090 5351772Sjl139090 /* 5361772Sjl139090 * Set tuneables for the OPL architecture 5371772Sjl139090 * 5381772Sjl139090 * lgrp_expand_proc_thresh is the minimum load on the lgroups 5391772Sjl139090 * this process is currently running on before considering 5401772Sjl139090 * expanding threads to another lgroup. 5411772Sjl139090 * 5421772Sjl139090 * lgrp_expand_proc_diff determines how much less the remote lgroup 5431772Sjl139090 * must be loaded before expanding to it. 5441772Sjl139090 * 5451772Sjl139090 * Since remote latencies can be costly, attempt to keep 3 threads 5461772Sjl139090 * within the same lgroup before expanding to the next lgroup. 5471772Sjl139090 */ 5481772Sjl139090 lgrp_expand_proc_thresh = LGRP_LOADAVG_THREAD_MAX * 3; 5491772Sjl139090 lgrp_expand_proc_diff = LGRP_LOADAVG_THREAD_MAX; 5501772Sjl139090 } 5511772Sjl139090 5521772Sjl139090 /* 5531772Sjl139090 * Platform notification of lgroup (re)configuration changes 5541772Sjl139090 */ 5551772Sjl139090 /*ARGSUSED*/ 5561772Sjl139090 void 5571772Sjl139090 plat_lgrp_config(lgrp_config_flag_t evt, uintptr_t arg) 5581772Sjl139090 { 5591772Sjl139090 update_membounds_t *umb; 5601772Sjl139090 lgrp_config_mem_rename_t lmr; 5611772Sjl139090 int sbd, tbd; 5621772Sjl139090 lgrp_handle_t hand, shand, thand; 5631772Sjl139090 int mnode, snode, tnode; 5641772Sjl139090 pfn_t start, end; 5651772Sjl139090 5661772Sjl139090 if (mpo_disabled) 5671772Sjl139090 return; 5681772Sjl139090 5691772Sjl139090 switch (evt) { 5701772Sjl139090 5711772Sjl139090 case LGRP_CONFIG_MEM_ADD: 5721772Sjl139090 /* 5731772Sjl139090 * Establish the lgroup handle to memnode translation. 5741772Sjl139090 */ 5751772Sjl139090 umb = (update_membounds_t *)arg; 5761772Sjl139090 5771772Sjl139090 hand = umb->u_board; 5781772Sjl139090 mnode = plat_pfn_to_mem_node(umb->u_base >> MMU_PAGESHIFT); 5791772Sjl139090 plat_assign_lgrphand_to_mem_node(hand, mnode); 5801772Sjl139090 5811772Sjl139090 break; 5821772Sjl139090 5831772Sjl139090 case LGRP_CONFIG_MEM_DEL: 5841772Sjl139090 /* 5851772Sjl139090 * Special handling for possible memory holes. 5861772Sjl139090 */ 5871772Sjl139090 umb = (update_membounds_t *)arg; 5881772Sjl139090 hand = umb->u_board; 5891772Sjl139090 if ((mnode = plat_lgrphand_to_mem_node(hand)) != -1) { 5901772Sjl139090 if (mem_node_config[mnode].exists) { 5911772Sjl139090 start = mem_node_config[mnode].physbase; 5921772Sjl139090 end = mem_node_config[mnode].physmax; 5931772Sjl139090 mem_node_pre_del_slice(start, end); 5941772Sjl139090 mem_node_post_del_slice(start, end, 0); 5951772Sjl139090 } 5961772Sjl139090 } 5971772Sjl139090 5981772Sjl139090 break; 5991772Sjl139090 6001772Sjl139090 case LGRP_CONFIG_MEM_RENAME: 6011772Sjl139090 /* 6021772Sjl139090 * During a DR copy-rename operation, all of the memory 6031772Sjl139090 * on one board is moved to another board -- but the 6041772Sjl139090 * addresses/pfns and memnodes don't change. This means 6051772Sjl139090 * the memory has changed locations without changing identity. 6061772Sjl139090 * 6071772Sjl139090 * Source is where we are copying from and target is where we 6081772Sjl139090 * are copying to. After source memnode is copied to target 6091772Sjl139090 * memnode, the physical addresses of the target memnode are 6101772Sjl139090 * renamed to match what the source memnode had. Then target 6111772Sjl139090 * memnode can be removed and source memnode can take its 6121772Sjl139090 * place. 6131772Sjl139090 * 6141772Sjl139090 * To do this, swap the lgroup handle to memnode mappings for 6151772Sjl139090 * the boards, so target lgroup will have source memnode and 6161772Sjl139090 * source lgroup will have empty target memnode which is where 6171772Sjl139090 * its memory will go (if any is added to it later). 6181772Sjl139090 * 6191772Sjl139090 * Then source memnode needs to be removed from its lgroup 6201772Sjl139090 * and added to the target lgroup where the memory was living 6211772Sjl139090 * but under a different name/memnode. The memory was in the 6221772Sjl139090 * target memnode and now lives in the source memnode with 6231772Sjl139090 * different physical addresses even though it is the same 6241772Sjl139090 * memory. 6251772Sjl139090 */ 6261772Sjl139090 sbd = arg & 0xffff; 6271772Sjl139090 tbd = (arg & 0xffff0000) >> 16; 6281772Sjl139090 shand = sbd; 6291772Sjl139090 thand = tbd; 6301772Sjl139090 snode = plat_lgrphand_to_mem_node(shand); 6311772Sjl139090 tnode = plat_lgrphand_to_mem_node(thand); 6321772Sjl139090 6331772Sjl139090 /* 6341772Sjl139090 * Special handling for possible memory holes. 6351772Sjl139090 */ 6361772Sjl139090 if (tnode != -1 && mem_node_config[tnode].exists) { 6371772Sjl139090 start = mem_node_config[mnode].physbase; 6381772Sjl139090 end = mem_node_config[mnode].physmax; 6391772Sjl139090 mem_node_pre_del_slice(start, end); 6401772Sjl139090 mem_node_post_del_slice(start, end, 0); 6411772Sjl139090 } 6421772Sjl139090 6431772Sjl139090 plat_assign_lgrphand_to_mem_node(thand, snode); 6441772Sjl139090 plat_assign_lgrphand_to_mem_node(shand, tnode); 6451772Sjl139090 6461772Sjl139090 lmr.lmem_rename_from = shand; 6471772Sjl139090 lmr.lmem_rename_to = thand; 6481772Sjl139090 6491772Sjl139090 /* 6501772Sjl139090 * Remove source memnode of copy rename from its lgroup 6511772Sjl139090 * and add it to its new target lgroup 6521772Sjl139090 */ 6531772Sjl139090 lgrp_config(LGRP_CONFIG_MEM_RENAME, (uintptr_t)snode, 6541772Sjl139090 (uintptr_t)&lmr); 6551772Sjl139090 6561772Sjl139090 break; 6571772Sjl139090 6581772Sjl139090 default: 6591772Sjl139090 break; 6601772Sjl139090 } 6611772Sjl139090 } 6621772Sjl139090 6631772Sjl139090 /* 6641772Sjl139090 * Return latency between "from" and "to" lgroups 6651772Sjl139090 * 6661772Sjl139090 * This latency number can only be used for relative comparison 6671772Sjl139090 * between lgroups on the running system, cannot be used across platforms, 6681772Sjl139090 * and may not reflect the actual latency. It is platform and implementation 6691772Sjl139090 * specific, so platform gets to decide its value. It would be nice if the 6701772Sjl139090 * number was at least proportional to make comparisons more meaningful though. 6711772Sjl139090 * NOTE: The numbers below are supposed to be load latencies for uncached 6721772Sjl139090 * memory divided by 10. 6731772Sjl139090 * 6741772Sjl139090 */ 6751772Sjl139090 int 6761772Sjl139090 plat_lgrp_latency(lgrp_handle_t from, lgrp_handle_t to) 6771772Sjl139090 { 6781772Sjl139090 /* 6791772Sjl139090 * Return min remote latency when there are more than two lgroups 6801772Sjl139090 * (root and child) and getting latency between two different lgroups 6811772Sjl139090 * or root is involved 6821772Sjl139090 */ 6831772Sjl139090 if (lgrp_optimizations() && (from != to || 6841772Sjl139090 from == LGRP_DEFAULT_HANDLE || to == LGRP_DEFAULT_HANDLE)) 6852491Shyw return (42); 6861772Sjl139090 else 6872491Shyw return (35); 6881772Sjl139090 } 6891772Sjl139090 6901772Sjl139090 /* 6911772Sjl139090 * Return platform handle for root lgroup 6921772Sjl139090 */ 6931772Sjl139090 lgrp_handle_t 6941772Sjl139090 plat_lgrp_root_hand(void) 6951772Sjl139090 { 6961772Sjl139090 if (mpo_disabled) 6971772Sjl139090 return (lgrp_default_handle); 6981772Sjl139090 6991772Sjl139090 return (LGRP_DEFAULT_HANDLE); 7001772Sjl139090 } 7011772Sjl139090 7021772Sjl139090 /*ARGSUSED*/ 7031772Sjl139090 void 7041772Sjl139090 plat_freelist_process(int mnode) 7051772Sjl139090 { 7061772Sjl139090 } 7071772Sjl139090 7081772Sjl139090 void 7091772Sjl139090 load_platform_drivers(void) 7101772Sjl139090 { 7111772Sjl139090 (void) i_ddi_attach_pseudo_node("dr"); 7121772Sjl139090 } 7131772Sjl139090 7141772Sjl139090 /* 7151772Sjl139090 * No platform drivers on this platform 7161772Sjl139090 */ 7171772Sjl139090 char *platform_module_list[] = { 7181772Sjl139090 (char *)0 7191772Sjl139090 }; 7201772Sjl139090 7211772Sjl139090 /*ARGSUSED*/ 7221772Sjl139090 void 7231772Sjl139090 plat_tod_fault(enum tod_fault_type tod_bad) 7241772Sjl139090 { 7251772Sjl139090 } 7261772Sjl139090 7271772Sjl139090 /*ARGSUSED*/ 7281772Sjl139090 void 7291772Sjl139090 cpu_sgn_update(ushort_t sgn, uchar_t state, uchar_t sub_state, int cpuid) 7301772Sjl139090 { 7311772Sjl139090 static void (*scf_panic_callback)(int); 7321772Sjl139090 static void (*scf_shutdown_callback)(int); 7331772Sjl139090 7341772Sjl139090 /* 7351772Sjl139090 * This is for notifing system panic/shutdown to SCF. 7361772Sjl139090 * In case of shutdown and panic, SCF call back 7371772Sjl139090 * function should be called. 7381772Sjl139090 * <SCF call back functions> 7391772Sjl139090 * scf_panic_callb() : panicsys()->panic_quiesce_hw() 7401772Sjl139090 * scf_shutdown_callb(): halt() or power_down() or reboot_machine() 7411772Sjl139090 * cpuid should be -1 and state should be SIGST_EXIT. 7421772Sjl139090 */ 7431772Sjl139090 if (state == SIGST_EXIT && cpuid == -1) { 7441772Sjl139090 7451772Sjl139090 /* 7461772Sjl139090 * find the symbol for the SCF panic callback routine in driver 7471772Sjl139090 */ 7481772Sjl139090 if (scf_panic_callback == NULL) 7491772Sjl139090 scf_panic_callback = (void (*)(int)) 7501772Sjl139090 modgetsymvalue("scf_panic_callb", 0); 7511772Sjl139090 if (scf_shutdown_callback == NULL) 7521772Sjl139090 scf_shutdown_callback = (void (*)(int)) 7531772Sjl139090 modgetsymvalue("scf_shutdown_callb", 0); 7541772Sjl139090 7551772Sjl139090 switch (sub_state) { 7561772Sjl139090 case SIGSUBST_PANIC: 7571772Sjl139090 if (scf_panic_callback == NULL) { 7581772Sjl139090 cmn_err(CE_NOTE, "!cpu_sgn_update: " 7591772Sjl139090 "scf_panic_callb not found\n"); 7601772Sjl139090 return; 7611772Sjl139090 } 7621772Sjl139090 scf_panic_callback(SIGSUBST_PANIC); 7631772Sjl139090 break; 7641772Sjl139090 7651772Sjl139090 case SIGSUBST_HALT: 7661772Sjl139090 if (scf_shutdown_callback == NULL) { 7671772Sjl139090 cmn_err(CE_NOTE, "!cpu_sgn_update: " 7681772Sjl139090 "scf_shutdown_callb not found\n"); 7691772Sjl139090 return; 7701772Sjl139090 } 7711772Sjl139090 scf_shutdown_callback(SIGSUBST_HALT); 7721772Sjl139090 break; 7731772Sjl139090 7741772Sjl139090 case SIGSUBST_ENVIRON: 7751772Sjl139090 if (scf_shutdown_callback == NULL) { 7761772Sjl139090 cmn_err(CE_NOTE, "!cpu_sgn_update: " 7771772Sjl139090 "scf_shutdown_callb not found\n"); 7781772Sjl139090 return; 7791772Sjl139090 } 7801772Sjl139090 scf_shutdown_callback(SIGSUBST_ENVIRON); 7811772Sjl139090 break; 7821772Sjl139090 7831772Sjl139090 case SIGSUBST_REBOOT: 7841772Sjl139090 if (scf_shutdown_callback == NULL) { 7851772Sjl139090 cmn_err(CE_NOTE, "!cpu_sgn_update: " 7861772Sjl139090 "scf_shutdown_callb not found\n"); 7871772Sjl139090 return; 7881772Sjl139090 } 7891772Sjl139090 scf_shutdown_callback(SIGSUBST_REBOOT); 7901772Sjl139090 break; 7911772Sjl139090 } 7921772Sjl139090 } 7931772Sjl139090 } 7941772Sjl139090 7951772Sjl139090 /*ARGSUSED*/ 7961772Sjl139090 int 7971772Sjl139090 plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id, 7981772Sjl139090 int flt_in_memory, ushort_t flt_status, 7991772Sjl139090 char *buf, int buflen, int *lenp) 8001772Sjl139090 { 8011772Sjl139090 /* 8021772Sjl139090 * check if it's a Memory error. 8031772Sjl139090 */ 8041772Sjl139090 if (flt_in_memory) { 8051772Sjl139090 if (opl_get_mem_unum != NULL) { 8061772Sjl139090 return (opl_get_mem_unum(synd_code, flt_addr, 8071772Sjl139090 buf, buflen, lenp)); 8081772Sjl139090 } else { 8091772Sjl139090 return (ENOTSUP); 8101772Sjl139090 } 8111772Sjl139090 } else { 8121772Sjl139090 return (ENOTSUP); 8131772Sjl139090 } 8141772Sjl139090 } 8151772Sjl139090 8161772Sjl139090 /*ARGSUSED*/ 8171772Sjl139090 int 8181772Sjl139090 plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp) 8191772Sjl139090 { 8202214Sav145390 int ret = 0; 8212214Sav145390 uint_t sb; 822*3123Ssubhan int plen; 8231772Sjl139090 8241772Sjl139090 sb = opl_get_physical_board(LSB_ID(cpuid)); 8251772Sjl139090 if (sb == -1) { 8261772Sjl139090 return (ENXIO); 8271772Sjl139090 } 8281772Sjl139090 829*3123Ssubhan ASSERT((opl_cur_model - opl_models) == (opl_cur_model->model_type)); 830*3123Ssubhan 831*3123Ssubhan switch (opl_cur_model->model_type) { 832*3123Ssubhan case FF1: 8332214Sav145390 plen = snprintf(buf, buflen, "/%s/CPUM%d", "MBU_A", 8342214Sav145390 CHIP_ID(cpuid) / 2); 8352214Sav145390 break; 8362214Sav145390 837*3123Ssubhan case FF2: 8382214Sav145390 plen = snprintf(buf, buflen, "/%s/CPUM%d", "MBU_B", 8392808Sav145390 (CHIP_ID(cpuid) / 2) + (sb * 2)); 8402214Sav145390 break; 8412214Sav145390 842*3123Ssubhan case DC1: 843*3123Ssubhan case DC2: 844*3123Ssubhan case DC3: 8452214Sav145390 plen = snprintf(buf, buflen, "/%s%02d/CPUM%d", "CMU", sb, 8462214Sav145390 CHIP_ID(cpuid)); 8472214Sav145390 break; 8482214Sav145390 8492214Sav145390 default: 8502214Sav145390 /* This should never happen */ 8512214Sav145390 return (ENODEV); 8522214Sav145390 } 8532214Sav145390 8542214Sav145390 if (plen >= buflen) { 8552214Sav145390 ret = ENOSPC; 8561772Sjl139090 } else { 8571772Sjl139090 if (lenp) 8581772Sjl139090 *lenp = strlen(buf); 8591772Sjl139090 } 8602214Sav145390 return (ret); 8611772Sjl139090 } 8621772Sjl139090 8631772Sjl139090 #define SCF_PUTINFO(f, s, p) \ 8641772Sjl139090 f(KEY_ESCF, 0x01, 0, s, p) 8651772Sjl139090 void 8661772Sjl139090 plat_nodename_set(void) 8671772Sjl139090 { 8681772Sjl139090 void *datap; 8691772Sjl139090 static int (*scf_service_function)(uint32_t, uint8_t, 8701772Sjl139090 uint32_t, uint32_t, void *); 8711772Sjl139090 int counter = 5; 8721772Sjl139090 8731772Sjl139090 /* 8741772Sjl139090 * find the symbol for the SCF put routine in driver 8751772Sjl139090 */ 8761772Sjl139090 if (scf_service_function == NULL) 8771772Sjl139090 scf_service_function = 8781772Sjl139090 (int (*)(uint32_t, uint8_t, uint32_t, uint32_t, void *)) 8791772Sjl139090 modgetsymvalue("scf_service_putinfo", 0); 8801772Sjl139090 8811772Sjl139090 /* 8821772Sjl139090 * If the symbol was found, call it. Otherwise, log a note (but not to 8831772Sjl139090 * the console). 8841772Sjl139090 */ 8851772Sjl139090 8861772Sjl139090 if (scf_service_function == NULL) { 8871772Sjl139090 cmn_err(CE_NOTE, 8881772Sjl139090 "!plat_nodename_set: scf_service_putinfo not found\n"); 8891772Sjl139090 return; 8901772Sjl139090 } 8911772Sjl139090 8921772Sjl139090 datap = 8931772Sjl139090 (struct utsname *)kmem_zalloc(sizeof (struct utsname), KM_SLEEP); 8941772Sjl139090 8951772Sjl139090 if (datap == NULL) { 8961772Sjl139090 return; 8971772Sjl139090 } 8981772Sjl139090 8991772Sjl139090 bcopy((struct utsname *)&utsname, 9001772Sjl139090 (struct utsname *)datap, sizeof (struct utsname)); 9011772Sjl139090 9021772Sjl139090 while ((SCF_PUTINFO(scf_service_function, 9031772Sjl139090 sizeof (struct utsname), datap) == EBUSY) && (counter-- > 0)) { 9041772Sjl139090 delay(10 * drv_usectohz(1000000)); 9051772Sjl139090 } 9061772Sjl139090 if (counter == 0) 9071772Sjl139090 cmn_err(CE_NOTE, 9081772Sjl139090 "!plat_nodename_set: " 9091772Sjl139090 "scf_service_putinfo not responding\n"); 9101772Sjl139090 9111772Sjl139090 kmem_free(datap, sizeof (struct utsname)); 9121772Sjl139090 } 9131772Sjl139090 9141772Sjl139090 caddr_t efcode_vaddr = NULL; 9151772Sjl139090 9161772Sjl139090 /* 9171772Sjl139090 * Preallocate enough memory for fcode claims. 9181772Sjl139090 */ 9191772Sjl139090 9201772Sjl139090 caddr_t 9211772Sjl139090 efcode_alloc(caddr_t alloc_base) 9221772Sjl139090 { 9231772Sjl139090 caddr_t efcode_alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, 9241772Sjl139090 MMU_PAGESIZE); 9251772Sjl139090 caddr_t vaddr; 9261772Sjl139090 9271772Sjl139090 /* 9281772Sjl139090 * allocate the physical memory for the Oberon fcode. 9291772Sjl139090 */ 9301772Sjl139090 if ((vaddr = (caddr_t)BOP_ALLOC(bootops, efcode_alloc_base, 9311772Sjl139090 efcode_size, MMU_PAGESIZE)) == NULL) 9321772Sjl139090 cmn_err(CE_PANIC, "Cannot allocate Efcode Memory"); 9331772Sjl139090 9341772Sjl139090 efcode_vaddr = vaddr; 9351772Sjl139090 9361772Sjl139090 return (efcode_alloc_base + efcode_size); 9371772Sjl139090 } 9381772Sjl139090 9391772Sjl139090 caddr_t 9401772Sjl139090 plat_startup_memlist(caddr_t alloc_base) 9411772Sjl139090 { 9421772Sjl139090 caddr_t tmp_alloc_base; 9431772Sjl139090 9441772Sjl139090 tmp_alloc_base = efcode_alloc(alloc_base); 9451772Sjl139090 tmp_alloc_base = 9461772Sjl139090 (caddr_t)roundup((uintptr_t)tmp_alloc_base, ecache_alignsize); 9471772Sjl139090 return (tmp_alloc_base); 9481772Sjl139090 } 9491772Sjl139090 9501772Sjl139090 void 9511772Sjl139090 startup_platform(void) 9521772Sjl139090 { 9531772Sjl139090 } 9542214Sav145390 9552241Shuah void 9562241Shuah plat_cpuid_to_mmu_ctx_info(processorid_t cpuid, mmu_ctx_info_t *info) 9572241Shuah { 9582241Shuah int impl; 9592241Shuah 9602241Shuah impl = cpunodes[cpuid].implementation; 9612241Shuah if (IS_OLYMPUS_C(impl)) { 9622457Smv143129 info->mmu_idx = MMU_ID(cpuid); 9632241Shuah info->mmu_nctxs = 8192; 9642241Shuah } else { 9652241Shuah cmn_err(CE_PANIC, "Unknown processor %d", impl); 9662241Shuah } 9672241Shuah } 9682241Shuah 9692214Sav145390 int 9702214Sav145390 plat_get_mem_sid(char *unum, char *buf, int buflen, int *lenp) 9712214Sav145390 { 9722214Sav145390 if (opl_get_mem_sid == NULL) { 9732214Sav145390 return (ENOTSUP); 9742214Sav145390 } 9752214Sav145390 return (opl_get_mem_sid(unum, buf, buflen, lenp)); 9762214Sav145390 } 9772214Sav145390 9782214Sav145390 int 9792214Sav145390 plat_get_mem_offset(uint64_t paddr, uint64_t *offp) 9802214Sav145390 { 9812214Sav145390 if (opl_get_mem_offset == NULL) { 9822214Sav145390 return (ENOTSUP); 9832214Sav145390 } 9842214Sav145390 return (opl_get_mem_offset(paddr, offp)); 9852214Sav145390 } 9862214Sav145390 9872214Sav145390 int 9882214Sav145390 plat_get_mem_addr(char *unum, char *sid, uint64_t offset, uint64_t *addrp) 9892214Sav145390 { 9902214Sav145390 if (opl_get_mem_addr == NULL) { 9912214Sav145390 return (ENOTSUP); 9922214Sav145390 } 9932214Sav145390 return (opl_get_mem_addr(unum, sid, offset, addrp)); 9942214Sav145390 } 995