xref: /onnv-gate/usr/src/cmd/mdb/sparc/kmdb/kmdb_promif_isadep.c (revision 5584:4b4402ef936b)
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