144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish #include <npi.h> 2944961713Sgirish #include <sys/nxge/nxge_impl.h> 3044961713Sgirish 3144961713Sgirish nxge_os_mutex_t npidebuglock; 3244961713Sgirish int npi_debug_init = 0; 3344961713Sgirish uint64_t npi_debug_level = 0; 3444961713Sgirish 35678453a8Sspeer extern void npi_trace_dump(rtrace_t *, int); 36678453a8Sspeer 3744961713Sgirish void 3844961713Sgirish npi_debug_msg(npi_handle_function_t function, uint64_t level, char *fmt, ...) 3944961713Sgirish { 4044961713Sgirish char msg_buffer[1024]; 4144961713Sgirish char prefix_buffer[32]; 4244961713Sgirish int cmn_level = CE_CONT; 4344961713Sgirish va_list ap; 4444961713Sgirish 4544961713Sgirish if ((level & npi_debug_level) || 46*52ccf843Smisaki (level & NPI_REG_CTL) || 47*52ccf843Smisaki (level & NPI_ERR_CTL)) { 4844961713Sgirish 4944961713Sgirish if (npi_debug_init == 0) { 5044961713Sgirish MUTEX_INIT(&npidebuglock, NULL, MUTEX_DRIVER, NULL); 5144961713Sgirish npi_debug_init = 1; 5244961713Sgirish } 5344961713Sgirish 5444961713Sgirish MUTEX_ENTER(&npidebuglock); 5544961713Sgirish 5644961713Sgirish if (level & NPI_ERR_CTL) { 5744961713Sgirish cmn_level = CE_WARN; 5844961713Sgirish } 5944961713Sgirish 6044961713Sgirish va_start(ap, fmt); 6144961713Sgirish (void) vsprintf(msg_buffer, fmt, ap); 6244961713Sgirish va_end(ap); 6344961713Sgirish 6444961713Sgirish (void) sprintf(prefix_buffer, "%s%d(%d):", "npi", 65*52ccf843Smisaki function.instance, function.function); 6644961713Sgirish 6744961713Sgirish MUTEX_EXIT(&npidebuglock); 6844961713Sgirish cmn_err(cmn_level, "!%s %s\n", prefix_buffer, msg_buffer); 6944961713Sgirish } 7044961713Sgirish } 7144961713Sgirish 7244961713Sgirish void 7344961713Sgirish npi_rtrace_buf_init(rtrace_t *rt) 7444961713Sgirish { 7544961713Sgirish int i; 7644961713Sgirish 7744961713Sgirish rt->next_idx = 0; 7844961713Sgirish rt->last_idx = MAX_RTRACE_ENTRIES - 1; 7944961713Sgirish rt->wrapped = B_FALSE; 8044961713Sgirish for (i = 0; i < MAX_RTRACE_ENTRIES; i++) { 8144961713Sgirish rt->buf[i].ctl_addr = TRACE_CTL_INVALID; 8244961713Sgirish rt->buf[i].val_l32 = 0; 8344961713Sgirish rt->buf[i].val_h32 = 0; 8444961713Sgirish } 8544961713Sgirish } 8644961713Sgirish 8744961713Sgirish void 8844961713Sgirish npi_rtrace_update(npi_handle_t handle, boolean_t wr, rtrace_t *rt, 89678453a8Sspeer uint32_t addr, uint64_t val) 9044961713Sgirish { 9144961713Sgirish int idx; 9244961713Sgirish idx = rt->next_idx; 9344961713Sgirish if (wr == B_TRUE) 9444961713Sgirish rt->buf[idx].ctl_addr = (addr & TRACE_ADDR_MASK) 95*52ccf843Smisaki | TRACE_CTL_WR; 9644961713Sgirish else 9744961713Sgirish rt->buf[idx].ctl_addr = (addr & TRACE_ADDR_MASK); 9844961713Sgirish rt->buf[idx].ctl_addr |= (((handle.function.function 99*52ccf843Smisaki << TRACE_FUNC_SHIFT) & TRACE_FUNC_MASK) | 100*52ccf843Smisaki ((handle.function.instance 101*52ccf843Smisaki << TRACE_INST_SHIFT) & TRACE_INST_MASK)); 10244961713Sgirish rt->buf[idx].val_l32 = val & 0xFFFFFFFF; 10344961713Sgirish rt->buf[idx].val_h32 = (val >> 32) & 0xFFFFFFFF; 10444961713Sgirish rt->next_idx++; 10544961713Sgirish if (rt->next_idx > rt->last_idx) { 10644961713Sgirish rt->next_idx = 0; 10744961713Sgirish rt->wrapped = B_TRUE; 10844961713Sgirish } 10944961713Sgirish } 110678453a8Sspeer 111678453a8Sspeer void 112678453a8Sspeer npi_trace_update(npi_handle_t handle, boolean_t wr, rtrace_t *rt, 113678453a8Sspeer const char *name, uint32_t addr, uint64_t val) 114678453a8Sspeer { 115678453a8Sspeer int idx; 116678453a8Sspeer idx = rt->next_idx; 117678453a8Sspeer if (wr == B_TRUE) 118678453a8Sspeer rt->buf[idx].ctl_addr = (addr & TRACE_ADDR_MASK) 119*52ccf843Smisaki | TRACE_CTL_WR; 120678453a8Sspeer else 121678453a8Sspeer rt->buf[idx].ctl_addr = (addr & TRACE_ADDR_MASK); 122678453a8Sspeer /* 123678453a8Sspeer * Control Address field format 124678453a8Sspeer * 125678453a8Sspeer * Bit 0 - 23: Address 126678453a8Sspeer * Bit 24 - 25: Function Number 127678453a8Sspeer * Bit 26 - 29: Instance Number 128678453a8Sspeer * Bit 30: Read/Write Direction bit 129678453a8Sspeer * Bit 31: Invalid bit 130678453a8Sspeer */ 131678453a8Sspeer rt->buf[idx].ctl_addr |= (((handle.function.function 132*52ccf843Smisaki << TRACE_FUNC_SHIFT) & TRACE_FUNC_MASK) | 133*52ccf843Smisaki ((handle.function.instance 134*52ccf843Smisaki << TRACE_INST_SHIFT) & TRACE_INST_MASK)); 135678453a8Sspeer rt->buf[idx].val_l32 = val & 0xFFFFFFFF; 136678453a8Sspeer rt->buf[idx].val_h32 = (val >> 32) & 0xFFFFFFFF; 137678453a8Sspeer (void) strncpy(rt->buf[idx].name, name, 15); 138678453a8Sspeer rt->next_idx++; 139678453a8Sspeer if (rt->next_idx > rt->last_idx) { 140678453a8Sspeer rt->next_idx = 0; 141678453a8Sspeer rt->wrapped = B_TRUE; 142678453a8Sspeer } 143678453a8Sspeer } 144678453a8Sspeer 145678453a8Sspeer #if defined(NPI_DEBUG) 146678453a8Sspeer void 147678453a8Sspeer npi_trace_dump( 148678453a8Sspeer rtrace_t *rt, 149678453a8Sspeer int count) 150678453a8Sspeer { 151678453a8Sspeer rt_buf_t *trace; 152678453a8Sspeer int cursor, i; 153678453a8Sspeer 154678453a8Sspeer if (count == 0 || count > MAX_RTRACE_ENTRIES) 155678453a8Sspeer count = 32; 156678453a8Sspeer 157678453a8Sspeer /* 158678453a8Sspeer * Starting with the last recorded entry, 159678453a8Sspeer * dump the <count> most recent records. 160678453a8Sspeer */ 161678453a8Sspeer cursor = rt->next_idx; 162678453a8Sspeer cursor = (cursor == 0) ? rt->last_idx : cursor - 1; 163678453a8Sspeer 164678453a8Sspeer for (i = 0; i < count; i++) { 165678453a8Sspeer trace = &rt->buf[cursor]; 166678453a8Sspeer if (trace->ctl_addr == 0) 167678453a8Sspeer break; 168678453a8Sspeer cmn_err(CE_NOTE, "%16s @ 0x%08x: 0x%08x.%08x: %c", 169678453a8Sspeer trace->name, trace->ctl_addr, 170678453a8Sspeer trace->val_h32, trace->val_l32, 171678453a8Sspeer trace->ctl_addr & TRACE_CTL_WR ? 'W' : 'R'); 172678453a8Sspeer cursor = (cursor == 0) ? rt->last_idx : cursor - 1; 173678453a8Sspeer } 174678453a8Sspeer } 175678453a8Sspeer #endif 176