10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51563Slq150181 * Common Development and Distribution License (the "License").
61563Slq150181 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
211563Slq150181
220Sstevel@tonic-gate /*
23*5584Sjimand * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * PROM interface
310Sstevel@tonic-gate */
320Sstevel@tonic-gate
330Sstevel@tonic-gate #include <sys/types.h>
340Sstevel@tonic-gate #include <unistd.h>
350Sstevel@tonic-gate #include <string.h>
360Sstevel@tonic-gate #include <stdlib.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate #define _KERNEL
390Sstevel@tonic-gate #define _BOOT
400Sstevel@tonic-gate #include <sys/promif.h>
410Sstevel@tonic-gate #undef _BOOT
420Sstevel@tonic-gate #undef _KERNEL
430Sstevel@tonic-gate
440Sstevel@tonic-gate #include <mdb/mdb_debug.h>
450Sstevel@tonic-gate #include <mdb/mdb_err.h>
460Sstevel@tonic-gate #include <kmdb/kmdb_promif_impl.h>
470Sstevel@tonic-gate #include <kmdb/kmdb_kdi.h>
480Sstevel@tonic-gate #include <mdb/mdb_string.h>
490Sstevel@tonic-gate #include <mdb/mdb.h>
500Sstevel@tonic-gate
51*5584Sjimand #ifndef sun4v
52*5584Sjimand int kmdb_prom_preserve_kctx = 0;
53*5584Sjimand #endif /* sun4v */
54*5584Sjimand
550Sstevel@tonic-gate ssize_t
kmdb_prom_obp_writer(caddr_t buf,size_t len)560Sstevel@tonic-gate kmdb_prom_obp_writer(caddr_t buf, size_t len)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate return (prom_write(prom_stdout_ihandle(), buf, len, 0, 0));
590Sstevel@tonic-gate }
600Sstevel@tonic-gate
610Sstevel@tonic-gate ihandle_t
kmdb_prom_get_handle(char * name)620Sstevel@tonic-gate kmdb_prom_get_handle(char *name)
630Sstevel@tonic-gate {
640Sstevel@tonic-gate if (strcmp(name, "stdin") == 0)
650Sstevel@tonic-gate return (prom_stdin_ihandle());
660Sstevel@tonic-gate else if (strcmp(name, "stdout") == 0 || strcmp(name, "stderr") == 0)
670Sstevel@tonic-gate return (prom_stdout_ihandle());
680Sstevel@tonic-gate else
690Sstevel@tonic-gate return (-1);
700Sstevel@tonic-gate }
710Sstevel@tonic-gate
720Sstevel@tonic-gate /*ARGSUSED*/
730Sstevel@tonic-gate char *
kmdb_prom_get_ddi_prop(kmdb_auxv_t * kav,char * propname)741563Slq150181 kmdb_prom_get_ddi_prop(kmdb_auxv_t *kav, char *propname)
750Sstevel@tonic-gate {
76789Sahrens pnode_t node;
770Sstevel@tonic-gate ssize_t len;
780Sstevel@tonic-gate char *val;
790Sstevel@tonic-gate
800Sstevel@tonic-gate if ((node = prom_finddevice("/options")) == NULL)
810Sstevel@tonic-gate return (NULL);
820Sstevel@tonic-gate
830Sstevel@tonic-gate if ((len = prom_getproplen(node, propname)) < 0)
840Sstevel@tonic-gate return (NULL);
850Sstevel@tonic-gate
860Sstevel@tonic-gate val = mdb_alloc(len + 1, UM_SLEEP);
870Sstevel@tonic-gate
880Sstevel@tonic-gate if (prom_bounded_getprop(node, propname, val, len) != len) {
890Sstevel@tonic-gate mdb_free(val, len);
900Sstevel@tonic-gate return (NULL);
910Sstevel@tonic-gate }
920Sstevel@tonic-gate val[len] = '\0';
930Sstevel@tonic-gate
940Sstevel@tonic-gate return (val);
950Sstevel@tonic-gate }
960Sstevel@tonic-gate
970Sstevel@tonic-gate void
kmdb_prom_free_ddi_prop(char * val)981563Slq150181 kmdb_prom_free_ddi_prop(char *val)
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate strfree(val);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate int
kmdb_prom_getprop(pnode_t node,char * name,caddr_t value)104789Sahrens kmdb_prom_getprop(pnode_t node, char *name, caddr_t value)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate return (prom_getprop(node, name, value));
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate typedef struct walk_cpu_data {
110789Sahrens int (*wcd_cb)(pnode_t, void *, void *);
1110Sstevel@tonic-gate void *wcd_arg;
1120Sstevel@tonic-gate } walk_cpu_data_t;
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate static int
walk_cpus_cb(pnode_t node,void * arg,void * result)115789Sahrens walk_cpus_cb(pnode_t node, void *arg, void *result)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate walk_cpu_data_t *wcd = arg;
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate /*
1201772Sjl139090 * Sun4v doesn't support port_id on guest.
1210Sstevel@tonic-gate */
1220Sstevel@tonic-gate #ifndef sun4v
1230Sstevel@tonic-gate int port_id;
1240Sstevel@tonic-gate #endif /* sun4v */
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate if (!prom_devicetype(node, OBP_CPU))
1270Sstevel@tonic-gate return (PROM_WALK_CONTINUE);
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate #ifndef sun4v
1300Sstevel@tonic-gate if ((prom_getprop(node, "portid", (caddr_t)&port_id) == -1) &&
1310Sstevel@tonic-gate (prom_getprop(node, "upa-portid", (caddr_t)&port_id) == -1) &&
1320Sstevel@tonic-gate (prom_getprop(node, "cpuid", (caddr_t)&port_id) == -1)) {
1330Sstevel@tonic-gate warn("cpu node %x has no identifying properties\n",
1340Sstevel@tonic-gate node);
1350Sstevel@tonic-gate return (PROM_WALK_CONTINUE);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate #endif /* sun4v */
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate if (wcd->wcd_cb(node, wcd->wcd_arg, result) != 0)
1400Sstevel@tonic-gate return (PROM_WALK_TERMINATE);
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate return (PROM_WALK_CONTINUE);
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate void
kmdb_prom_walk_cpus(int (* cb)(pnode_t,void *,void *),void * arg,void * result)146789Sahrens kmdb_prom_walk_cpus(int (*cb)(pnode_t, void *, void *), void *arg, void *result)
1470Sstevel@tonic-gate {
1480Sstevel@tonic-gate walk_cpu_data_t wcd;
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate wcd.wcd_cb = cb;
1510Sstevel@tonic-gate wcd.wcd_arg = arg;
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate prom_walk_devs(prom_rootnode(), walk_cpus_cb, &wcd, result);
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate void
kmdb_prom_enter_mon(void)1570Sstevel@tonic-gate kmdb_prom_enter_mon(void)
1580Sstevel@tonic-gate {
1590Sstevel@tonic-gate prom_enter_mon();
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate
1621772Sjl139090 #ifndef sun4v
1631772Sjl139090 pnode_t
kmdb_prom_getcpu_propnode(pnode_t node)1641772Sjl139090 kmdb_prom_getcpu_propnode(pnode_t node)
1651772Sjl139090 {
1661772Sjl139090 int val;
1671772Sjl139090 pnode_t pnode;
1681772Sjl139090 char name[OBP_MAXPROPNAME];
1691772Sjl139090
1701772Sjl139090
1711772Sjl139090 /*
1721772Sjl139090 * Check for the CMT case where cpu nodes are "strand" nodes
1731772Sjl139090 * In this case, the "cpu node" properties are contained in
1741772Sjl139090 * its parent "core" node.
1751772Sjl139090 */
1761772Sjl139090 if (prom_getprop(node, "portid", (caddr_t)&val) == -1 &&
1771772Sjl139090 prom_getprop(node, "upa-portid", (caddr_t)&val) == -1 &&
178*5584Sjimand prom_getprop((pnode = prom_parentnode(node)), "name", name) != -1 &&
1791772Sjl139090 strcmp(name, "core") == 0)
1801772Sjl139090 return (pnode);
1811772Sjl139090
1821772Sjl139090 return (node);
1831772Sjl139090 }
1841772Sjl139090 #endif /* sun4v */
1851772Sjl139090
1860Sstevel@tonic-gate void
kmdb_prom_exit_to_mon(void)1870Sstevel@tonic-gate kmdb_prom_exit_to_mon(void)
1880Sstevel@tonic-gate {
1890Sstevel@tonic-gate prom_exit_to_mon();
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate void
kmdb_prom_interpret(const char * str)1930Sstevel@tonic-gate kmdb_prom_interpret(const char *str)
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate prom_interpret((char *)str, 0, 0, 0, 0, 0);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate /*ARGSUSED*/
1990Sstevel@tonic-gate int
kmdb_prom_translate_virt(uintptr_t virt,physaddr_t * pap)2000Sstevel@tonic-gate kmdb_prom_translate_virt(uintptr_t virt, physaddr_t *pap)
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate extern int prom_translate_virt(caddr_t, int *, u_longlong_t *, int *);
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate int valid, mode;
2050Sstevel@tonic-gate uintptr_t vabase = virt & ~(mdb.m_pagesize - 1);
2060Sstevel@tonic-gate uintptr_t off = virt - vabase;
2070Sstevel@tonic-gate u_longlong_t pa;
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate mdb_dprintf(MDB_DBG_DPI, "using OBP for vtop of %p\n", (void *)virt);
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate if (prom_translate_virt((caddr_t)vabase, &valid, &pa, &mode) != 0)
2120Sstevel@tonic-gate return (set_errno(EMDB_NOMAP));
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate *pap = pa + off;
2150Sstevel@tonic-gate return (0);
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate /*ARGSUSED*/
2190Sstevel@tonic-gate int
kmdb_prom_stdout_is_framebuffer(kmdb_auxv_t * kav)2200Sstevel@tonic-gate kmdb_prom_stdout_is_framebuffer(kmdb_auxv_t *kav)
2210Sstevel@tonic-gate {
2220Sstevel@tonic-gate return (prom_stdout_is_framebuffer());
2230Sstevel@tonic-gate }
224*5584Sjimand
225*5584Sjimand #ifndef sun4v
226*5584Sjimand #define PROM_KCTX_PRESERVED_PROPNAME "context0-page-size-preserved"
227*5584Sjimand void
kmdb_prom_preserve_kctx_init(void)228*5584Sjimand kmdb_prom_preserve_kctx_init(void)
229*5584Sjimand {
230*5584Sjimand pnode_t pnode;
231*5584Sjimand int val;
232*5584Sjimand
233*5584Sjimand pnode = (pnode_t)prom_getphandle(prom_mmu_ihandle());
234*5584Sjimand if (prom_getprop(pnode, PROM_KCTX_PRESERVED_PROPNAME,
235*5584Sjimand (caddr_t)&val) == 0) {
236*5584Sjimand kmdb_prom_preserve_kctx = 1;
237*5584Sjimand }
238*5584Sjimand }
239*5584Sjimand #endif /* sun4v */
240