From owner-svn-src-vendor@FreeBSD.ORG Mon Jul 19 14:57:02 2010 Return-Path: Delivered-To: svn-src-vendor@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 16CB6106564A; Mon, 19 Jul 2010 14:57:02 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 04C258FC1D; Mon, 19 Jul 2010 14:57:02 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6JEv2ol098294; Mon, 19 Jul 2010 14:57:02 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6JEv1XS098292; Mon, 19 Jul 2010 14:57:01 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <201007191457.o6JEv1XS098292@svn.freebsd.org> From: Rui Paulo Date: Mon, 19 Jul 2010 14:57:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210236 - vendor/opensolaris/dist/cmd/plockstat X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Jul 2010 14:57:02 -0000 Author: rpaulo Date: Mon Jul 19 14:57:01 2010 New Revision: 210236 URL: http://svn.freebsd.org/changeset/base/210236 Log: Import plockstat from OpenSolaris r12768. Added: vendor/opensolaris/dist/cmd/plockstat/ vendor/opensolaris/dist/cmd/plockstat/plockstat.c (contents, props changed) Added: vendor/opensolaris/dist/cmd/plockstat/plockstat.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/opensolaris/dist/cmd/plockstat/plockstat.c Mon Jul 19 14:57:01 2010 (r210236) @@ -0,0 +1,996 @@ +/* + * 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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *g_pname; +static dtrace_hdl_t *g_dtp; +struct ps_prochandle *g_pr; + +#define E_SUCCESS 0 +#define E_ERROR 1 +#define E_USAGE 2 + +/* + * For hold times we use a global associative array since for mutexes, in + * user-land, it's not invalid to release a sychonization primitive that + * another thread acquired; rwlocks require a thread-local associative array + * since multiple thread can hold the same lock for reading. Note that we + * ignore recursive mutex acquisitions and releases as they don't truly + * affect lock contention. + */ +static const char *g_hold_init = +"plockstat$target:::rw-acquire\n" +"{\n" +" self->rwhold[arg0] = timestamp;\n" +"}\n" +"plockstat$target:::mutex-acquire\n" +"/arg1 == 0/\n" +"{\n" +" mtxhold[arg0] = timestamp;\n" +"}\n"; + +static const char *g_hold_histogram = +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0] && arg1 == 1/\n" +"{\n" +" @rw_w_hold[arg0, ustack()] =\n" +" quantize(timestamp - self->rwhold[arg0]);\n" +" self->rwhold[arg0] = 0;\n" +" rw_w_hold_found = 1;\n" +"}\n" +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0]/\n" +"{\n" +" @rw_r_hold[arg0, ustack()] =\n" +" quantize(timestamp - self->rwhold[arg0]);\n" +" self->rwhold[arg0] = 0;\n" +" rw_r_hold_found = 1;\n" +"}\n" +"plockstat$target:::mutex-release\n" +"/mtxhold[arg0] && arg1 == 0/\n" +"{\n" +" @mtx_hold[arg0, ustack()] = quantize(timestamp - mtxhold[arg0]);\n" +" mtxhold[arg0] = 0;\n" +" mtx_hold_found = 1;\n" +"}\n" +"\n" +"END\n" +"/mtx_hold_found/\n" +"{\n" +" trace(\"Mutex hold\");\n" +" printa(@mtx_hold);\n" +"}\n" +"END\n" +"/rw_r_hold_found/\n" +"{\n" +" trace(\"R/W reader hold\");\n" +" printa(@rw_r_hold);\n" +"}\n" +"END\n" +"/rw_w_hold_found/\n" +"{\n" +" trace(\"R/W writer hold\");\n" +" printa(@rw_w_hold);\n" +"}\n"; + +static const char *g_hold_times = +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0] && arg1 == 1/\n" +"{\n" +" @rw_w_hold[arg0, ustack(5)] = sum(timestamp - self->rwhold[arg0]);\n" +" @rw_w_hold_count[arg0, ustack(5)] = count();\n" +" self->rwhold[arg0] = 0;\n" +" rw_w_hold_found = 1;\n" +"}\n" +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0]/\n" +"{\n" +" @rw_r_hold[arg0, ustack(5)] = sum(timestamp - self->rwhold[arg0]);\n" +" @rw_r_hold_count[arg0, ustack(5)] = count();\n" +" self->rwhold[arg0] = 0;\n" +" rw_r_hold_found = 1;\n" +"}\n" +"plockstat$target:::mutex-release\n" +"/mtxhold[arg0] && arg1 == 0/\n" +"{\n" +" @mtx_hold[arg0, ustack(5)] = sum(timestamp - mtxhold[arg0]);\n" +" @mtx_hold_count[arg0, ustack(5)] = count();\n" +" mtxhold[arg0] = 0;\n" +" mtx_hold_found = 1;\n" +"}\n" +"\n" +"END\n" +"/mtx_hold_found/\n" +"{\n" +" trace(\"Mutex hold\");\n" +" printa(@mtx_hold, @mtx_hold_count);\n" +"}\n" +"END\n" +"/rw_r_hold_found/\n" +"{\n" +" trace(\"R/W reader hold\");\n" +" printa(@rw_r_hold, @rw_r_hold_count);\n" +"}\n" +"END\n" +"/rw_w_hold_found/\n" +"{\n" +" trace(\"R/W writer hold\");\n" +" printa(@rw_w_hold, @rw_w_hold_count);\n" +"}\n"; + + +/* + * For contention, we use thread-local associative arrays since we're tracing + * a single thread's activity in libc and multiple threads can be blocking or + * spinning on the same sychonization primitive. + */ +static const char *g_ctnd_init = +"plockstat$target:::rw-block\n" +"{\n" +" self->rwblock[arg0] = timestamp;\n" +"}\n" +"plockstat$target:::mutex-block\n" +"{\n" +" self->mtxblock[arg0] = timestamp;\n" +"}\n" +"plockstat$target:::mutex-spin\n" +"{\n" +" self->mtxspin[arg0] = timestamp;\n" +"}\n"; + +static const char *g_ctnd_histogram = +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg1 == 1 && arg2 != 0/\n" +"{\n" +" @rw_w_block[arg0, ustack()] =\n" +" quantize(timestamp - self->rwblock[arg0]);\n" +" self->rwblock[arg0] = 0;\n" +" rw_w_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg2 != 0/\n" +"{\n" +" @rw_r_block[arg0, ustack()] =\n" +" quantize(timestamp - self->rwblock[arg0]);\n" +" self->rwblock[arg0] = 0;\n" +" rw_r_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0]/\n" +"{\n" +" self->rwblock[arg0] = 0;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_spin[arg0, ustack()] =\n" +" quantize(timestamp - self->mtxspin[arg0]);\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0]/\n" +"{\n" +" @mtx_vain_spin[arg0, ustack()] =\n" +" quantize(timestamp - self->mtxspin[arg0]);\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_vain_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_block[arg0, ustack()] =\n" +" quantize(timestamp - self->mtxblock[arg0]);\n" +" self->mtxblock[arg0] = 0;\n" +" mtx_block_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0]/\n" +"{\n" +" self->mtxblock[arg0] = 0;\n" +"}\n" +"\n" +"END\n" +"/mtx_block_found/\n" +"{\n" +" trace(\"Mutex block\");\n" +" printa(@mtx_block);\n" +"}\n" +"END\n" +"/mtx_spin_found/\n" +"{\n" +" trace(\"Mutex spin\");\n" +" printa(@mtx_spin);\n" +"}\n" +"END\n" +"/mtx_vain_spin_found/\n" +"{\n" +" trace(\"Mutex unsuccessful spin\");\n" +" printa(@mtx_vain_spin);\n" +"}\n" +"END\n" +"/rw_r_block_found/\n" +"{\n" +" trace(\"R/W reader block\");\n" +" printa(@rw_r_block);\n" +"}\n" +"END\n" +"/rw_w_block_found/\n" +"{\n" +" trace(\"R/W writer block\");\n" +" printa(@rw_w_block);\n" +"}\n"; + + +static const char *g_ctnd_times = +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg1 == 1 && arg2 != 0/\n" +"{\n" +" @rw_w_block[arg0, ustack(5)] =\n" +" sum(timestamp - self->rwblock[arg0]);\n" +" @rw_w_block_count[arg0, ustack(5)] = count();\n" +" self->rwblock[arg0] = 0;\n" +" rw_w_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg2 != 0/\n" +"{\n" +" @rw_r_block[arg0, ustack(5)] =\n" +" sum(timestamp - self->rwblock[arg0]);\n" +" @rw_r_block_count[arg0, ustack(5)] = count();\n" +" self->rwblock[arg0] = 0;\n" +" rw_r_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0]/\n" +"{\n" +" self->rwblock[arg0] = 0;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_spin[arg0, ustack(5)] =\n" +" sum(timestamp - self->mtxspin[arg0]);\n" +" @mtx_spin_count[arg0, ustack(5)] = count();\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0]/\n" +"{\n" +" @mtx_vain_spin[arg0, ustack(5)] =\n" +" sum(timestamp - self->mtxspin[arg0]);\n" +" @mtx_vain_spin_count[arg0, ustack(5)] = count();\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_vain_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_block[arg0, ustack(5)] =\n" +" sum(timestamp - self->mtxblock[arg0]);\n" +" @mtx_block_count[arg0, ustack(5)] = count();\n" +" self->mtxblock[arg0] = 0;\n" +" mtx_block_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0]/\n" +"{\n" +" self->mtxblock[arg0] = 0;\n" +"}\n" +"\n" +"END\n" +"/mtx_block_found/\n" +"{\n" +" trace(\"Mutex block\");\n" +" printa(@mtx_block, @mtx_block_count);\n" +"}\n" +"END\n" +"/mtx_spin_found/\n" +"{\n" +" trace(\"Mutex spin\");\n" +" printa(@mtx_spin, @mtx_spin_count);\n" +"}\n" +"END\n" +"/mtx_vain_spin_found/\n" +"{\n" +" trace(\"Mutex unsuccessful spin\");\n" +" printa(@mtx_vain_spin, @mtx_vain_spin_count);\n" +"}\n" +"END\n" +"/rw_r_block_found/\n" +"{\n" +" trace(\"R/W reader block\");\n" +" printa(@rw_r_block, @rw_r_block_count);\n" +"}\n" +"END\n" +"/rw_w_block_found/\n" +"{\n" +" trace(\"R/W writer block\");\n" +" printa(@rw_w_block, @rw_w_block_count);\n" +"}\n"; + +static char g_prog[4096]; +static size_t g_proglen; +static int g_opt_V, g_opt_s; +static int g_intr; +static int g_exited; +static dtrace_optval_t g_nframes; +static ulong_t g_nent = ULONG_MAX; + +#define PLOCKSTAT_OPTSTR "n:ps:e:vx:ACHV" + +static void +usage(void) +{ + (void) fprintf(stderr, "Usage:\n" + "\t%s [-vACHV] [-n count] [-s depth] [-e secs] [-x opt[=val]]\n" + "\t command [arg...]\n" + "\t%s [-vACHV] [-n count] [-s depth] [-e secs] [-x opt[=val]]\n" + "\t -p pid\n", g_pname, g_pname); + + exit(E_USAGE); +} + +static void +verror(const char *fmt, va_list ap) +{ + int error = errno; + + (void) fprintf(stderr, "%s: ", g_pname); + (void) vfprintf(stderr, fmt, ap); + + if (fmt[strlen(fmt) - 1] != '\n') + (void) fprintf(stderr, ": %s\n", strerror(error)); +} + +/*PRINTFLIKE1*/ +static void +fatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); + + if (g_pr != NULL && g_dtp != NULL) + dtrace_proc_release(g_dtp, g_pr); + + exit(E_ERROR); +} + +/*PRINTFLIKE1*/ +static void +dfatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + (void) fprintf(stderr, "%s: ", g_pname); + if (fmt != NULL) + (void) vfprintf(stderr, fmt, ap); + + va_end(ap); + + if (fmt != NULL && fmt[strlen(fmt) - 1] != '\n') { + (void) fprintf(stderr, ": %s\n", + dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); + } else if (fmt == NULL) { + (void) fprintf(stderr, "%s\n", + dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); + } + + if (g_pr != NULL) { + dtrace_proc_continue(g_dtp, g_pr); + dtrace_proc_release(g_dtp, g_pr); + } + + exit(E_ERROR); +} + +/*PRINTFLIKE1*/ +static void +notice(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); +} + +static void +dprog_add(const char *prog) +{ + size_t len = strlen(prog); + bcopy(prog, g_prog + g_proglen, len + 1); + g_proglen += len; + assert(g_proglen < sizeof (g_prog)); +} + +static void +dprog_compile(void) +{ + dtrace_prog_t *prog; + dtrace_proginfo_t info; + + if (g_opt_V) { + (void) fprintf(stderr, "%s: vvvv D program vvvv\n", g_pname); + (void) fputs(g_prog, stderr); + (void) fprintf(stderr, "%s: ^^^^ D program ^^^^\n", g_pname); + } + + if ((prog = dtrace_program_strcompile(g_dtp, g_prog, + DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) + dfatal("failed to compile program"); + + if (dtrace_program_exec(g_dtp, prog, &info) == -1) + dfatal("failed to enable probes"); +} + +void +print_legend(void) +{ + (void) printf("%5s %8s %-28s %s\n", "Count", "nsec", "Lock", "Caller"); +} + +void +print_bar(void) +{ + (void) printf("---------------------------------------" + "----------------------------------------\n"); +} + +void +print_histogram_header(void) +{ + (void) printf("\n%10s ---- Time Distribution --- %5s %s\n", + "nsec", "count", "Stack"); +} + +/* + * Convert an address to a symbolic string or a numeric string. If nolocks + * is set, we return an error code if this symbol appears to be a mutex- or + * rwlock-related symbol in libc so the caller has a chance to find a more + * helpful symbol. + */ +static int +getsym(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, + int nolocks) +{ + char name[256]; + GElf_Sym sym; + prsyminfo_t info; + size_t len; + + if (P == NULL || Pxlookup_by_addr(P, addr, name, sizeof (name), + &sym, &info) != 0) { + (void) snprintf(buf, size, "%#lx", addr); + return (0); + } + if (info.prs_object == NULL) + info.prs_object = ""; + + if (info.prs_lmid != LM_ID_BASE) { + len = snprintf(buf, size, "LM%lu`", info.prs_lmid); + buf += len; + size -= len; + } + + len = snprintf(buf, size, "%s`%s", info.prs_object, info.prs_name); + buf += len; + size -= len; + + if (sym.st_value != addr) + len = snprintf(buf, size, "+%#lx", addr - sym.st_value); + + if (nolocks && strcmp("libc.so.1", info.prs_object) == 0 && + (strstr("mutex", info.prs_name) == 0 || + strstr("rw", info.prs_name) == 0)) + return (-1); + + return (0); +} + +/*ARGSUSED*/ +static int +process_aggregate(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg) +{ + const dtrace_recdesc_t *rec; + uintptr_t lock; + uint64_t *stack; + caddr_t data; + pid_t pid; + struct ps_prochandle *P; + char buf[256]; + int i, j; + uint64_t sum, count, avg; + + if ((*(uint_t *)arg)++ >= g_nent) + return (DTRACE_AGGWALK_NEXT); + + rec = aggsdata[0]->dtada_desc->dtagd_rec; + data = aggsdata[0]->dtada_data; + + /*LINTED - alignment*/ + lock = (uintptr_t)*(uint64_t *)(data + rec[1].dtrd_offset); + /*LINTED - alignment*/ + stack = (uint64_t *)(data + rec[2].dtrd_offset); + + if (!g_opt_s) { + /*LINTED - alignment*/ + sum = *(uint64_t *)(aggsdata[1]->dtada_data + + aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset); + /*LINTED - alignment*/ + count = *(uint64_t *)(aggsdata[2]->dtada_data + + aggsdata[2]->dtada_desc->dtagd_rec[3].dtrd_offset); + } else { + uint64_t *a; + + /*LINTED - alignment*/ + a = (uint64_t *)(aggsdata[1]->dtada_data + + aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset); + + print_bar(); + print_legend(); + + for (count = sum = 0, i = DTRACE_QUANTIZE_ZEROBUCKET, j = 0; + i < DTRACE_QUANTIZE_NBUCKETS; i++, j++) { + count += a[i]; + sum += a[i] << (j - 64); + } + } + + avg = sum / count; + (void) printf("%5llu %8llu ", (u_longlong_t)count, (u_longlong_t)avg); + + pid = stack[0]; + P = dtrace_proc_grab(g_dtp, pid, PGRAB_RDONLY); + + (void) getsym(P, lock, buf, sizeof (buf), 0); + (void) printf("%-28s ", buf); + + for (i = 2; i <= 5; i++) { + if (getsym(P, stack[i], buf, sizeof (buf), 1) == 0) + break; + } + (void) printf("%s\n", buf); + + if (g_opt_s) { + int stack_done = 0; + int quant_done = 0; + int first_bin, last_bin; + uint64_t bin_size, *a; + + /*LINTED - alignment*/ + a = (uint64_t *)(aggsdata[1]->dtada_data + + aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset); + + print_histogram_header(); + + for (first_bin = DTRACE_QUANTIZE_ZEROBUCKET; + a[first_bin] == 0; first_bin++) + continue; + for (last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 63; + a[last_bin] == 0; last_bin--) + continue; + + for (i = 0; !stack_done || !quant_done; i++) { + if (!stack_done) { + (void) getsym(P, stack[i + 2], buf, + sizeof (buf), 0); + } else { + buf[0] = '\0'; + } + + if (!quant_done) { + bin_size = a[first_bin]; + + (void) printf("%10llu |%-24.*s| %5llu %s\n", + 1ULL << + (first_bin - DTRACE_QUANTIZE_ZEROBUCKET), + (int)(24.0 * bin_size / count), + "@@@@@@@@@@@@@@@@@@@@@@@@@@", + (u_longlong_t)bin_size, buf); + } else { + (void) printf("%43s %s\n", "", buf); + } + + if (i + 1 >= g_nframes || stack[i + 3] == 0) + stack_done = 1; + + if (first_bin++ == last_bin) + quant_done = 1; + } + } + + dtrace_proc_release(g_dtp, P); + + return (DTRACE_AGGWALK_NEXT); +} + +/*ARGSUSED*/ +static void +prochandler(struct ps_prochandle *P, const char *msg, void *arg) +{ + const psinfo_t *prp = Ppsinfo(P); + int pid = Pstatus(P)->pr_pid; + char name[SIG2STR_MAX]; + + if (msg != NULL) { + notice("pid %d: %s\n", pid, msg); + return; + } + + switch (Pstate(P)) { + case PS_UNDEAD: + /* + * Ideally we would like to always report pr_wstat here, but it + * isn't possible given current /proc semantics. If we grabbed + * the process, Ppsinfo() will either fail or return a zeroed + * psinfo_t depending on how far the parent is in reaping it. + * When /proc provides a stable pr_wstat in the status file, + * this code can be improved by examining this new pr_wstat. + */ + if (prp != NULL && WIFSIGNALED(prp->pr_wstat)) { + notice("pid %d terminated by %s\n", pid, + proc_signame(WTERMSIG(prp->pr_wstat), + name, sizeof (name))); + } else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) { + notice("pid %d exited with status %d\n", + pid, WEXITSTATUS(prp->pr_wstat)); + } else { + notice("pid %d has exited\n", pid); + } + g_exited = 1; + break; + + case PS_LOST: + notice("pid %d exec'd a set-id or unobservable program\n", pid); + g_exited = 1; + break; + } +} + +/*ARGSUSED*/ +static int +chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg) +{ + dtrace_eprobedesc_t *epd = data->dtpda_edesc; + dtrace_aggvarid_t aggvars[2]; + const void *buf; + int i, nagv; + + /* + * A NULL rec indicates that we've processed the last record. + */ + if (rec == NULL) + return (DTRACE_CONSUME_NEXT); + + buf = data->dtpda_data - rec->dtrd_offset; + + switch (rec->dtrd_action) { + case DTRACEACT_DIFEXPR: + (void) printf("\n%s\n\n", (char *)buf + rec->dtrd_offset); + if (!g_opt_s) { + print_legend(); + print_bar(); + } + return (DTRACE_CONSUME_NEXT); + + case DTRACEACT_PRINTA: + for (nagv = 0, i = 0; i < epd->dtepd_nrecs - 1; i++) { + const dtrace_recdesc_t *nrec = &rec[i]; + + if (nrec->dtrd_uarg != rec->dtrd_uarg) + break; + + /*LINTED - alignment*/ + aggvars[nagv++] = *(dtrace_aggvarid_t *)((caddr_t)buf + + nrec->dtrd_offset); + } + + if (nagv == (g_opt_s ? 1 : 2)) { + uint_t nent = 0; + if (dtrace_aggregate_walk_joined(g_dtp, aggvars, nagv, + process_aggregate, &nent) != 0) + dfatal("failed to walk aggregate"); + } + + return (DTRACE_CONSUME_NEXT); + } + + return (DTRACE_CONSUME_THIS); +} + +/*ARGSUSED*/ +static void +intr(int signo) +{ + g_intr = 1; +} + +int +main(int argc, char **argv) +{ + ucred_t *ucp; + int err; + int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0; + char c, *p, *end; + struct sigaction act; + int done = 0; + + g_pname = basename(argv[0]); + argv[0] = g_pname; /* rewrite argv[0] for getopt errors */ + + /* + * Make sure we have the required dtrace_proc privilege. + */ + if ((ucp = ucred_get(getpid())) != NULL) { + const priv_set_t *psp; + if ((psp = ucred_getprivset(ucp, PRIV_EFFECTIVE)) != NULL && + !priv_ismember(psp, PRIV_DTRACE_PROC)) { + fatal("dtrace_proc privilege required\n"); + } + + ucred_free(ucp); + } + + while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) { + switch (c) { + case 'n': + errno = 0; + g_nent = strtoul(optarg, &end, 10); + if (*end != '\0' || errno != 0) { + (void) fprintf(stderr, "%s: invalid count " + "'%s'\n", g_pname, optarg); + usage(); + } + break; + + case 'p': + opt_p = 1; + break; + + case 'v': + opt_v = 1; + break; + + case 'A': + opt_C = opt_H = 1; + break; + + case 'C': + opt_C = 1; + break; + + case 'H': + opt_H = 1; + break; + + case 'V': + g_opt_V = 1; + break; + + default: + if (strchr(PLOCKSTAT_OPTSTR, c) == NULL) + usage(); + } + } + + /* + * We need a command or at least one pid. + */ + if (argc == optind) + usage(); + + if (opt_C == 0 && opt_H == 0) + opt_C = 1; + + if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) + fatal("failed to initialize dtrace: %s\n", + dtrace_errmsg(NULL, err)); + + /* + * The longest string we trace is 23 bytes long -- so 32 is plenty. + */ + if (dtrace_setopt(g_dtp, "strsize", "32") == -1) + dfatal("failed to set 'strsize'"); + + /* + * 1k should be more than enough for all trace() and printa() actions. + */ + if (dtrace_setopt(g_dtp, "bufsize", "1k") == -1) + dfatal("failed to set 'bufsize'"); + + /* + * The table we produce has the hottest locks at the top. + */ + if (dtrace_setopt(g_dtp, "aggsortrev", NULL) == -1) + dfatal("failed to set 'aggsortrev'"); + + /* + * These are two reasonable defaults which should suffice. + */ + if (dtrace_setopt(g_dtp, "aggsize", "256k") == -1) + dfatal("failed to set 'aggsize'"); + if (dtrace_setopt(g_dtp, "aggrate", "1sec") == -1) + dfatal("failed to set 'aggrate'"); + + /* + * Take a second pass through to look for options that set options now + * that we have an open dtrace handle. + */ + optind = 1; + while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) { + switch (c) { + case 's': + g_opt_s = 1; + if (dtrace_setopt(g_dtp, "ustackframes", optarg) == -1) + dfatal("failed to set 'ustackframes'"); + break; + + case 'x': + if ((p = strchr(optarg, '=')) != NULL) + *p++ = '\0'; + + if (dtrace_setopt(g_dtp, optarg, p) != 0) + dfatal("failed to set -x %s", optarg); + break; + + case 'e': + errno = 0; + (void) strtoul(optarg, &end, 10); + if (*optarg == '-' || *end != '\0' || errno != 0) { + (void) fprintf(stderr, "%s: invalid timeout " + "'%s'\n", g_pname, optarg); + usage(); + } + + /* + * Construct a DTrace enabling that will exit after + * the specified number of seconds. + */ + dprog_add("BEGIN\n{\n\tend = timestamp + "); + dprog_add(optarg); + dprog_add(" * 1000000000;\n}\n"); + dprog_add("tick-10hz\n/timestamp >= end/\n"); + dprog_add("{\n\texit(0);\n}\n"); + break; + } + } + + argc -= optind; + argv += optind; + + if (opt_H) { + dprog_add(g_hold_init); + if (g_opt_s == NULL) + dprog_add(g_hold_times); + else + dprog_add(g_hold_histogram); + } + + if (opt_C) { + dprog_add(g_ctnd_init); + if (g_opt_s == NULL) + dprog_add(g_ctnd_times); + else + dprog_add(g_ctnd_histogram); + } + + if (opt_p) { + ulong_t pid; + + if (argc > 1) { + (void) fprintf(stderr, "%s: only one pid is allowed\n", + g_pname); + usage(); + } + + errno = 0; + pid = strtoul(argv[0], &end, 10); + if (*end != '\0' || errno != 0 || (pid_t)pid != pid) { + (void) fprintf(stderr, "%s: invalid pid '%s'\n", + g_pname, argv[0]); + usage(); + } + + if ((g_pr = dtrace_proc_grab(g_dtp, (pid_t)pid, 0)) == NULL) + dfatal(NULL); + } else { + if ((g_pr = dtrace_proc_create(g_dtp, argv[0], argv)) == NULL) + dfatal(NULL); + } + + dprog_compile(); + + if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1) + dfatal("failed to establish proc handler"); + + (void) sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = intr; + (void) sigaction(SIGINT, &act, NULL); + (void) sigaction(SIGTERM, &act, NULL); + + if (dtrace_go(g_dtp) != 0) + dfatal("dtrace_go()"); + + if (dtrace_getopt(g_dtp, "ustackframes", &g_nframes) != 0) + dfatal("failed to get 'ustackframes'"); + + dtrace_proc_continue(g_dtp, g_pr); + + if (opt_v) + (void) printf("%s: tracing enabled for pid %d\n", g_pname, + (int)Pstatus(g_pr)->pr_pid); + + do { + if (!g_intr && !done) + dtrace_sleep(g_dtp); + + if (done || g_intr || g_exited) { + done = 1; + if (dtrace_stop(g_dtp) == -1) + dfatal("couldn't stop tracing"); + } + + switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) { + case DTRACE_WORKSTATUS_DONE: + done = 1; + break; + case DTRACE_WORKSTATUS_OKAY: + break; + default: + dfatal("processing aborted"); + } + + } while (!done); + + dtrace_close(g_dtp); + + return (0); +} From owner-svn-src-vendor@FreeBSD.ORG Tue Jul 20 07:11:20 2010 Return-Path: Delivered-To: svn-src-vendor@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 494521065673; Tue, 20 Jul 2010 07:11:20 +0000 (UTC) (envelope-from jmallett@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 35CC88FC1D; Tue, 20 Jul 2010 07:11:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6K7BKdl020892; Tue, 20 Jul 2010 07:11:20 GMT (envelope-from jmallett@svn.freebsd.org) Received: (from jmallett@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6K7BKB0020885; Tue, 20 Jul 2010 07:11:20 GMT (envelope-from jmallett@svn.freebsd.org) Message-Id: <201007200711.o6K7BKB0020885@svn.freebsd.org> From: Juli Mallett Date: Tue, 20 Jul 2010 07:11:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org X-SVN-Group: vendor-sys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210284 - in vendor-sys/octeon-sdk: . dist dist/cvmx-malloc X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Jul 2010 07:11:20 -0000 Author: jmallett Date: Tue Jul 20 07:11:19 2010 New Revision: 210284 URL: http://svn.freebsd.org/changeset/base/210284 Log: Initial import of Cavium Networks Octeon Simple Executive, SDK version 1.9.0. Added: vendor-sys/octeon-sdk/ vendor-sys/octeon-sdk/dist/ vendor-sys/octeon-sdk/dist/README.txt vendor-sys/octeon-sdk/dist/cvmip.h vendor-sys/octeon-sdk/dist/cvmx-abi.h vendor-sys/octeon-sdk/dist/cvmx-access-native.h vendor-sys/octeon-sdk/dist/cvmx-access.h vendor-sys/octeon-sdk/dist/cvmx-address.h vendor-sys/octeon-sdk/dist/cvmx-app-init-linux.c vendor-sys/octeon-sdk/dist/cvmx-app-init.c vendor-sys/octeon-sdk/dist/cvmx-app-init.h vendor-sys/octeon-sdk/dist/cvmx-asm.h vendor-sys/octeon-sdk/dist/cvmx-asx.h vendor-sys/octeon-sdk/dist/cvmx-atomic.h vendor-sys/octeon-sdk/dist/cvmx-bootloader.h vendor-sys/octeon-sdk/dist/cvmx-bootmem.c vendor-sys/octeon-sdk/dist/cvmx-bootmem.h vendor-sys/octeon-sdk/dist/cvmx-ciu.h vendor-sys/octeon-sdk/dist/cvmx-cmd-queue.c vendor-sys/octeon-sdk/dist/cvmx-cmd-queue.h vendor-sys/octeon-sdk/dist/cvmx-cn3010-evb-hs5.c vendor-sys/octeon-sdk/dist/cvmx-cn3010-evb-hs5.h vendor-sys/octeon-sdk/dist/cvmx-compactflash.c vendor-sys/octeon-sdk/dist/cvmx-compactflash.h vendor-sys/octeon-sdk/dist/cvmx-core.c vendor-sys/octeon-sdk/dist/cvmx-core.h vendor-sys/octeon-sdk/dist/cvmx-coremask.c vendor-sys/octeon-sdk/dist/cvmx-coremask.h vendor-sys/octeon-sdk/dist/cvmx-csr-addresses.h vendor-sys/octeon-sdk/dist/cvmx-csr-db-support.c vendor-sys/octeon-sdk/dist/cvmx-csr-db.c vendor-sys/octeon-sdk/dist/cvmx-csr-db.h vendor-sys/octeon-sdk/dist/cvmx-csr-enums.h vendor-sys/octeon-sdk/dist/cvmx-csr-typedefs.h vendor-sys/octeon-sdk/dist/cvmx-csr.h vendor-sys/octeon-sdk/dist/cvmx-cvmmem.h vendor-sys/octeon-sdk/dist/cvmx-dfa.c vendor-sys/octeon-sdk/dist/cvmx-dfa.h vendor-sys/octeon-sdk/dist/cvmx-dma-engine.c vendor-sys/octeon-sdk/dist/cvmx-dma-engine.h vendor-sys/octeon-sdk/dist/cvmx-ebt3000.c vendor-sys/octeon-sdk/dist/cvmx-ebt3000.h vendor-sys/octeon-sdk/dist/cvmx-fau.h vendor-sys/octeon-sdk/dist/cvmx-flash.c vendor-sys/octeon-sdk/dist/cvmx-flash.h vendor-sys/octeon-sdk/dist/cvmx-fpa.c vendor-sys/octeon-sdk/dist/cvmx-fpa.h vendor-sys/octeon-sdk/dist/cvmx-gmx.h vendor-sys/octeon-sdk/dist/cvmx-gpio.h vendor-sys/octeon-sdk/dist/cvmx-helper-board.c vendor-sys/octeon-sdk/dist/cvmx-helper-board.h vendor-sys/octeon-sdk/dist/cvmx-helper-check-defines.h vendor-sys/octeon-sdk/dist/cvmx-helper-errata.c vendor-sys/octeon-sdk/dist/cvmx-helper-errata.h vendor-sys/octeon-sdk/dist/cvmx-helper-fpa.c vendor-sys/octeon-sdk/dist/cvmx-helper-fpa.h vendor-sys/octeon-sdk/dist/cvmx-helper-loop.c vendor-sys/octeon-sdk/dist/cvmx-helper-loop.h vendor-sys/octeon-sdk/dist/cvmx-helper-npi.c vendor-sys/octeon-sdk/dist/cvmx-helper-npi.h vendor-sys/octeon-sdk/dist/cvmx-helper-rgmii.c vendor-sys/octeon-sdk/dist/cvmx-helper-rgmii.h vendor-sys/octeon-sdk/dist/cvmx-helper-sgmii.c vendor-sys/octeon-sdk/dist/cvmx-helper-sgmii.h vendor-sys/octeon-sdk/dist/cvmx-helper-spi.c vendor-sys/octeon-sdk/dist/cvmx-helper-spi.h vendor-sys/octeon-sdk/dist/cvmx-helper-util.c vendor-sys/octeon-sdk/dist/cvmx-helper-util.h vendor-sys/octeon-sdk/dist/cvmx-helper-xaui.c vendor-sys/octeon-sdk/dist/cvmx-helper-xaui.h vendor-sys/octeon-sdk/dist/cvmx-helper.c vendor-sys/octeon-sdk/dist/cvmx-helper.h vendor-sys/octeon-sdk/dist/cvmx-higig.h vendor-sys/octeon-sdk/dist/cvmx-interrupt-decodes.c vendor-sys/octeon-sdk/dist/cvmx-interrupt-handler.S vendor-sys/octeon-sdk/dist/cvmx-interrupt-rsl.c vendor-sys/octeon-sdk/dist/cvmx-interrupt.c vendor-sys/octeon-sdk/dist/cvmx-interrupt.h vendor-sys/octeon-sdk/dist/cvmx-iob.h vendor-sys/octeon-sdk/dist/cvmx-ipd.h vendor-sys/octeon-sdk/dist/cvmx-key.h vendor-sys/octeon-sdk/dist/cvmx-l2c.c vendor-sys/octeon-sdk/dist/cvmx-l2c.h vendor-sys/octeon-sdk/dist/cvmx-llm.c vendor-sys/octeon-sdk/dist/cvmx-llm.h vendor-sys/octeon-sdk/dist/cvmx-lmc.h vendor-sys/octeon-sdk/dist/cvmx-log-arc.S vendor-sys/octeon-sdk/dist/cvmx-log.c vendor-sys/octeon-sdk/dist/cvmx-log.h vendor-sys/octeon-sdk/dist/cvmx-malloc/ vendor-sys/octeon-sdk/dist/cvmx-malloc.h vendor-sys/octeon-sdk/dist/cvmx-malloc/README-malloc vendor-sys/octeon-sdk/dist/cvmx-malloc/arena.c vendor-sys/octeon-sdk/dist/cvmx-malloc/malloc.c vendor-sys/octeon-sdk/dist/cvmx-malloc/malloc.h vendor-sys/octeon-sdk/dist/cvmx-malloc/thread-m.h vendor-sys/octeon-sdk/dist/cvmx-mdio.h vendor-sys/octeon-sdk/dist/cvmx-mgmt-port.c vendor-sys/octeon-sdk/dist/cvmx-mgmt-port.h vendor-sys/octeon-sdk/dist/cvmx-mio.h vendor-sys/octeon-sdk/dist/cvmx-nand.c vendor-sys/octeon-sdk/dist/cvmx-nand.h vendor-sys/octeon-sdk/dist/cvmx-npi.h vendor-sys/octeon-sdk/dist/cvmx-packet.h vendor-sys/octeon-sdk/dist/cvmx-pci.h vendor-sys/octeon-sdk/dist/cvmx-pcie.c vendor-sys/octeon-sdk/dist/cvmx-pcie.h vendor-sys/octeon-sdk/dist/cvmx-pip.h vendor-sys/octeon-sdk/dist/cvmx-pko.c vendor-sys/octeon-sdk/dist/cvmx-pko.h vendor-sys/octeon-sdk/dist/cvmx-platform.h vendor-sys/octeon-sdk/dist/cvmx-pow.c vendor-sys/octeon-sdk/dist/cvmx-pow.h vendor-sys/octeon-sdk/dist/cvmx-raid.c vendor-sys/octeon-sdk/dist/cvmx-raid.h vendor-sys/octeon-sdk/dist/cvmx-resources.config vendor-sys/octeon-sdk/dist/cvmx-rng.h vendor-sys/octeon-sdk/dist/cvmx-rtc.h vendor-sys/octeon-sdk/dist/cvmx-rwlock.h vendor-sys/octeon-sdk/dist/cvmx-scratch.h vendor-sys/octeon-sdk/dist/cvmx-shared-linux-n32.ld vendor-sys/octeon-sdk/dist/cvmx-shared-linux-o32.ld vendor-sys/octeon-sdk/dist/cvmx-shared-linux.ld vendor-sys/octeon-sdk/dist/cvmx-spi.c vendor-sys/octeon-sdk/dist/cvmx-spi.h vendor-sys/octeon-sdk/dist/cvmx-spi4000.c vendor-sys/octeon-sdk/dist/cvmx-spinlock.h vendor-sys/octeon-sdk/dist/cvmx-swap.h vendor-sys/octeon-sdk/dist/cvmx-sysinfo.c vendor-sys/octeon-sdk/dist/cvmx-sysinfo.h vendor-sys/octeon-sdk/dist/cvmx-thunder.c vendor-sys/octeon-sdk/dist/cvmx-thunder.h vendor-sys/octeon-sdk/dist/cvmx-tim.c vendor-sys/octeon-sdk/dist/cvmx-tim.h vendor-sys/octeon-sdk/dist/cvmx-tra.c vendor-sys/octeon-sdk/dist/cvmx-tra.h vendor-sys/octeon-sdk/dist/cvmx-twsi-raw.c vendor-sys/octeon-sdk/dist/cvmx-twsi-raw.h vendor-sys/octeon-sdk/dist/cvmx-twsi.c vendor-sys/octeon-sdk/dist/cvmx-twsi.h vendor-sys/octeon-sdk/dist/cvmx-uart.h vendor-sys/octeon-sdk/dist/cvmx-usb.c vendor-sys/octeon-sdk/dist/cvmx-usb.h vendor-sys/octeon-sdk/dist/cvmx-utils.h vendor-sys/octeon-sdk/dist/cvmx-version.h vendor-sys/octeon-sdk/dist/cvmx-warn.c vendor-sys/octeon-sdk/dist/cvmx-warn.h vendor-sys/octeon-sdk/dist/cvmx-wqe.h vendor-sys/octeon-sdk/dist/cvmx-zip.c vendor-sys/octeon-sdk/dist/cvmx-zip.h vendor-sys/octeon-sdk/dist/cvmx-zone.c vendor-sys/octeon-sdk/dist/cvmx.h vendor-sys/octeon-sdk/dist/cvmx.mk vendor-sys/octeon-sdk/dist/executive-config.h.template vendor-sys/octeon-sdk/dist/octeon-feature.h vendor-sys/octeon-sdk/dist/octeon-model.c vendor-sys/octeon-sdk/dist/octeon-model.h vendor-sys/octeon-sdk/dist/octeon-pci-console.c vendor-sys/octeon-sdk/dist/octeon-pci-console.h vendor-sys/octeon-sdk/dist/perfzilla_screen.png (contents, props changed) Added: vendor-sys/octeon-sdk/dist/README.txt ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor-sys/octeon-sdk/dist/README.txt Tue Jul 20 07:11:19 2010 (r210284) @@ -0,0 +1,43 @@ +Readme for the Octeon Executive Library + + +The Octeon Executive Library provides runtime support and hardware +abstraction for the Octeon processor. The executive is composed of the +libcvmx.a library as well as header files that provide +functionality with inline functions. + + +Usage: + +The libcvmx.a library is built for every application as part of the +application build. (Please refer to the 'related pages' section of the +HTML documentation for more information on the build system.) +Applications using the executive should include the header files from +$OCTEON_ROOT/target/include and link against the library that is built in +the local obj directory. Each file using the executive +should include the following two header files in order: + +#include "cvmx-config.h" +#include "cvmx.h" + +The cvmx-config.h file contains configuration information for the +executive and is generated by the cvmx-config script from an +'executive-config.h' file. A sample version of this file is provided +in the executive directory as 'executive-config.h.template'. + +Copy this file to 'executive-config.h' into the 'config' subdirectory +of the application directory and customize as required by the application. +Applications that don't use any simple executive functionality can omit +the cvmx-config.h header file. Please refer to the examples for a +demonstration of where to put the executive-config.h file and for an +example of generated cvmx-config.h. + +For file specific information please see the documentation within the +source files or the HTML documentation provided in docs/html/index.html. +The HTML documentation is automatically generated by Doxygen from the +source files. + + + +========================================================================== +Please see the release notes for version specific information. Added: vendor-sys/octeon-sdk/dist/cvmip.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor-sys/octeon-sdk/dist/cvmip.h Tue Jul 20 07:11:19 2010 (r210284) @@ -0,0 +1,207 @@ +/***********************license start*************** + * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights + * reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of Cavium Networks nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" + * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS + * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH + * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY + * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT + * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES + * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR + * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET + * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT + * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. + * + * + * For any questions regarding licensing please contact marketing@caviumnetworks.com + * + ***********************license end**************************************/ + + + + + + +/** + * @file + * + * Cavium Networks Internet Protocol (IP) + * + * Definitions for the Internet Protocol (IP) support. + * + *
$Revision: 41586 $
+ * + */ + +#ifndef __CVMIP_H__ +#define __CVMIP_H__ + + +/* + * IP protocol values (1 byte) + * + */ +#define CVMIP_PROTO_ICMP 1 /* Internet Control Message Protocol */ +#define CVMIP_PROTO_TCP 6 /* Transmission Control Protocol */ +#define CVMIP_PROTO_UDP 17 /* User Datagram Protocol */ +#define CVMIP_PROTO_ESP 50 /* Encapsulated Security Payload */ +#define CVMIP_PROTO_AH 51 /* Authentication Header */ + + +/** + * network packet header definitions + * (originally from octane_hw.h) + * + */ + +/** + * UDP Packet header + */ +typedef struct { + union { + int32_t s32 ; + uint32_t u32 ; + struct { + uint16_t src_prt ; + uint16_t dst_prt ; + } s; + } prts; + uint16_t len ; + uint16_t chksum ; +} cvmip_udp_hdr_t; + +/** + * TCP Packet header + */ +typedef struct { + uint16_t src_prt ; + uint16_t dst_prt ; + uint32_t seq ; + uint32_t ack_seq ; + uint32_t hlen :4; + uint32_t rsvd :6; + uint32_t urg :1; + uint32_t ack :1; + uint32_t psh :1; + uint32_t rst :1; + uint32_t syn :1; + uint32_t fin :1; + uint16_t win_sz ; + uint16_t chksum ; + uint16_t urg_ptr ; + uint32_t junk ; +} cvmip_tcp_hdr_t; + +/** + * L4 Packet header + */ +typedef union { + cvmip_udp_hdr_t udphdr; + cvmip_tcp_hdr_t tcphdr; + struct { + union { + int32_t s32 ; + uint32_t u32 ; + struct { + uint16_t src_prt; + uint16_t dst_prt; + } s; + } prts; + uint16_t len ; + uint16_t chksum ; + char dat[48] ; // 48 for IPv6 with no extension hdrs, 64 for IPv4 without options + } udp; + struct { + uint16_t src_prt ; + uint16_t dst_prt ; + uint32_t seq ; + uint32_t ack_seq ; + uint32_t hlen :4; + uint32_t rsvd :6; + uint32_t urg :1; + uint32_t ack :1; + uint32_t psh :1; + uint32_t rst :1; + uint32_t syn :1; + uint32_t fin :1; + uint16_t win_sz ; + uint16_t chksum ; + uint16_t urg_ptr ; + char dat[36] ; // 36 for IPv6 with no extension hdrs, 52 for IPv6 without options + } tcp; +} cvmip_l4_info_t; + +/** + * Special struct to add a pad to IPv4 header + */ +typedef struct { + uint32_t pad; + + uint32_t version : 4; + uint32_t hl : 4; + uint8_t tos ; + uint16_t len ; + + uint16_t id ; + uint32_t mbz : 1; + uint32_t df : 1; + uint32_t mf : 1; + uint32_t off :13; + + uint8_t ttl ; + uint8_t protocol; + uint16_t chksum ; + + union { + uint64_t u64; + struct { + uint32_t src; + uint32_t dst; + } s; + } src_dst; +} cvmip_ipv4_hdr_t; + +/** + * IPv6 Packet header + */ +typedef struct { + + uint32_t version : 4; + uint32_t v6class : 8; + uint32_t flow :20; + + uint16_t len ; // includes extension headers plus payload (add 40 to be equiv to v4 len field) + uint8_t next_hdr; // equivalent to the v4 protocol field + uint8_t hop_lim ; // equivalent to the v4 TTL field + + union { + uint64_t u64[4]; + struct { + uint64_t src[2]; + uint64_t dst[2]; + } s; + } src_dst; + +} cvmip_ipv6_hdr_t; + + +#endif /* __CVMIP_H__ */ Added: vendor-sys/octeon-sdk/dist/cvmx-abi.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor-sys/octeon-sdk/dist/cvmx-abi.h Tue Jul 20 07:11:19 2010 (r210284) @@ -0,0 +1,92 @@ +/***********************license start*************** + * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights + * reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of Cavium Networks nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" + * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS + * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH + * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY + * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT + * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES + * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR + * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET + * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT + * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. + * + * + * For any questions regarding licensing please contact marketing@caviumnetworks.com + * + ***********************license end**************************************/ + + + + + + +/** + * @file + * + * This file defines macros for use in determining the current calling ABI. + * + *
$Revision: 41586 $
+*/ + +#ifndef __CVMX_ABI_H__ +#define __CVMX_ABI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Check for N32 ABI, defined for 32-bit Simple Exec applications + and Linux N32 ABI.*/ +#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) +#define CVMX_ABI_N32 +/* Check for N64 ABI, defined for 64-bit Linux toolchain. */ +#elif (defined _ABI64 && _MIPS_SIM == _ABI64) +#define CVMX_ABI_N64 +/* Check for O32 ABI, defined for Linux 032 ABI, not supported yet. */ +#elif (defined _ABIO32 && _MIPS_SIM == _ABIO32) +#define CVMX_ABI_O32 +/* Check for EABI ABI, defined for 64-bit Simple Exec applications. */ +#else +#define CVMX_ABI_EABI +#endif + +#ifndef __BYTE_ORDER + #if defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN) + #define __BYTE_ORDER __BIG_ENDIAN + #elif !defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) + #define __BYTE_ORDER __LITTLE_ENDIAN + #define __BIG_ENDIAN 4321 + #elif !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN) + #define __BIG_ENDIAN 4321 + #define __BYTE_ORDER __BIG_ENDIAN + #else + #error Unable to determine Endian mode + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CVMX_ABI_H__ */ Added: vendor-sys/octeon-sdk/dist/cvmx-access-native.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor-sys/octeon-sdk/dist/cvmx-access-native.h Tue Jul 20 07:11:19 2010 (r210284) @@ -0,0 +1,667 @@ +/***********************license start*************** + * Copyright (c) 2003-2009 Cavium Networks (support@cavium.com). All rights + * reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of Cavium Networks nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" + * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS + * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH + * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY + * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT + * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES + * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR + * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET + * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT + * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. + * + * + * For any questions regarding licensing please contact marketing@caviumnetworks.com + * + ***********************license end**************************************/ + +/** + * @file + * Functions for accessing memory and CSRs on Octeon when we are compiling + * natively. + * + *
$Revision: 38306 $
+*/ +#ifndef __CVMX_ACCESS_NATIVE_H__ +#define __CVMX_ACCESS_NATIVE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Returns the Octeon processor ID. + * + * @return Octeon processor ID from COP0 + */ +static inline uint32_t cvmx_get_proc_id(void) +{ +#ifdef CVMX_BUILD_FOR_LINUX_USER + extern uint32_t cvmx_app_init_processor_id; + return cvmx_app_init_processor_id; +#else + uint32_t id; + asm ("mfc0 %0, $15,0" : "=r" (id)); + return id; +#endif +} + +/** + * Convert a memory pointer (void*) into a hardware compatable + * memory address (uint64_t). Octeon hardware widgets don't + * understand logical addresses. + * + * @param ptr C style memory pointer + * @return Hardware physical address + */ +static inline uint64_t cvmx_ptr_to_phys(void *ptr) +{ + if (CVMX_ENABLE_PARAMETER_CHECKING) + cvmx_warn_if(ptr==NULL, "cvmx_ptr_to_phys() passed a NULL pointer\n"); + +#ifdef CVMX_BUILD_FOR_UBOOT + /* U-boot is a special case, as it is running in error level, which disables the TLB completely. + ** U-boot may use kseg0 addresses, or may directly use physical addresses already */ + return(CAST64(ptr) & 0x7FFFFFFF); +#endif + +#ifdef __linux__ + if (sizeof(void*) == 8) + { + /* We're running in 64 bit mode. Normally this means that we can use + 40 bits of address space (the hardware limit). Unfortunately there + is one case were we need to limit this to 30 bits, sign extended + 32 bit. Although these are 64 bits wide, only 30 bits can be used */ + if ((CAST64(ptr) >> 62) == 3) + return CAST64(ptr) & cvmx_build_mask(30); + else + return CAST64(ptr) & cvmx_build_mask(40); + } + else + { +#ifdef __KERNEL__ + return (long)(ptr) & 0x1fffffff; +#else + extern uint64_t linux_mem32_offset; + if (cvmx_likely(ptr)) + return CAST64(ptr) - linux_mem32_offset; + else + return 0; +#endif + } +#elif defined(_WRS_KERNEL) + return (long)(ptr) & 0x7fffffff; +#elif defined(VXWORKS_USER_MAPPINGS) + /* This mapping mode is used in vxWorks 5.5 to support 2GB of ram. The + 2nd 256MB is mapped at 0x10000000 and the rest of memory is 1:1 */ + uint64_t address = (long)ptr; + if (address & 0x80000000) + return address & 0x1fffffff; /* KSEG pointers directly map the lower 256MB and bootbus */ + else if ((address >= 0x10000000) && (address < 0x20000000)) + return address + 0x400000000ull; /* 256MB-512MB is a virtual mapping for the 2nd 256MB */ + else + return address; /* Looks to be a 1:1 mapped userspace pointer */ +#else +#if CVMX_USE_1_TO_1_TLB_MAPPINGS + /* We are assumung we're running the Simple Executive standalone. In this + mode the TLB is setup to perform 1:1 mapping and 32 bit sign extended + addresses are never used. Since we know all this, save the masking + cycles and do nothing */ + return CAST64(ptr); +#else + + if (sizeof(void*) == 8) + { + /* We're running in 64 bit mode. Normally this means that we can use + 40 bits of address space (the hardware limit). Unfortunately there + is one case were we need to limit this to 30 bits, sign extended + 32 bit. Although these are 64 bits wide, only 30 bits can be used */ + if ((CAST64(ptr) >> 62) == 3) + return CAST64(ptr) & cvmx_build_mask(30); + else + return CAST64(ptr) & cvmx_build_mask(40); + } + else + return (long)(ptr) & 0x7fffffff; + +#endif +#endif +} + + +/** + * Convert a hardware physical address (uint64_t) into a + * memory pointer (void *). + * + * @param physical_address + * Hardware physical address to memory + * @return Pointer to memory + */ +static inline void *cvmx_phys_to_ptr(uint64_t physical_address) +{ + if (CVMX_ENABLE_PARAMETER_CHECKING) + cvmx_warn_if(physical_address==0, "cvmx_phys_to_ptr() passed a zero address\n"); + +#ifdef CVMX_BUILD_FOR_UBOOT + /* U-boot is a special case, as it is running in error level, which disables the TLB completely. + ** U-boot may use kseg0 addresses, or may directly use physical addresses already */ + if (physical_address >= 0x80000000) + return NULL; + else + return CASTPTR(void, (physical_address & 0x7FFFFFFF)); +#endif + +#ifdef __linux__ + if (sizeof(void*) == 8) + { + /* Just set the top bit, avoiding any TLB uglyness */ + return CASTPTR(void, CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, physical_address)); + } + else + { +#ifdef __KERNEL__ + return CASTPTR(void, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, physical_address)); +#else + extern uint64_t linux_mem32_offset; + if (cvmx_likely(physical_address)) + return CASTPTR(void, physical_address + linux_mem32_offset); + else + return NULL; +#endif + } +#elif defined(_WRS_KERNEL) + return CASTPTR(void, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, physical_address)); +#elif defined(VXWORKS_USER_MAPPINGS) + /* This mapping mode is used in vxWorks 5.5 to support 2GB of ram. The + 2nd 256MB is mapped at 0x10000000 and the rest of memory is 1:1 */ + if ((physical_address >= 0x10000000) && (physical_address < 0x20000000)) + return CASTPTR(void, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, physical_address)); + else if ((physical_address >= 0x410000000ull) && (physical_address < 0x420000000ull)) + return CASTPTR(void, physical_address - 0x400000000ull); + else + return CASTPTR(void, physical_address); +#else + +#if CVMX_USE_1_TO_1_TLB_MAPPINGS + /* We are assumung we're running the Simple Executive standalone. In this + mode the TLB is setup to perform 1:1 mapping and 32 bit sign extended + addresses are never used. Since we know all this, save bit insert + cycles and do nothing */ + return CASTPTR(void, physical_address); +#else + /* Set the XKPHYS/KSEG0 bit as appropriate based on ABI */ + if (sizeof(void*) == 8) + return CASTPTR(void, CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, physical_address)); + else + return CASTPTR(void, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, physical_address)); + +#endif + +#endif +} + + +/* The following #if controls the definition of the macro + CVMX_BUILD_WRITE64. This macro is used to build a store operation to + a full 64bit address. With a 64bit ABI, this can be done with a simple + pointer access. 32bit ABIs require more complicated assembly */ +#if defined(CVMX_ABI_N64) || defined(CVMX_ABI_EABI) + +/* We have a full 64bit ABI. Writing to a 64bit address can be done with + a simple volatile pointer */ +#define CVMX_BUILD_WRITE64(TYPE, ST) \ +static inline void cvmx_write64_##TYPE(uint64_t addr, TYPE##_t val) \ +{ \ + *CASTPTR(volatile TYPE##_t, addr) = val; \ +} + +#elif defined(CVMX_ABI_N32) + +/* The N32 ABI passes all 64bit quantities in a single register, so it is + possible to use the arguments directly. We have to use inline assembly + for the actual store since a pointer would truncate the address */ +#define CVMX_BUILD_WRITE64(TYPE, ST) \ +static inline void cvmx_write64_##TYPE(uint64_t addr, TYPE##_t val) \ +{ \ + asm volatile (ST " %[v], 0(%[c])" ::[v] "r" (val), [c] "r" (addr)); \ +} + +#elif defined(CVMX_ABI_O32) + +#ifdef __KERNEL__ +#define CVMX_BUILD_WRITE64(TYPE, LT) extern void cvmx_write64_##TYPE(uint64_t csr_addr, TYPE##_t val); +#else + +/* Ok, now the ugly stuff starts. O32 splits 64bit quantities into two + separate registers. Assembly must be used to put them back together + before they're used. What should be a simple store becomes a + convoluted mess of shifts and ors */ +#define CVMX_BUILD_WRITE64(TYPE, ST) \ +static inline void cvmx_write64_##TYPE(uint64_t csr_addr, TYPE##_t val) \ +{ \ + if (sizeof(TYPE##_t) == 8) \ + { \ + uint32_t csr_addrh = csr_addr>>32; \ + uint32_t csr_addrl = csr_addr; \ + uint32_t valh = (uint64_t)val>>32; \ + uint32_t vall = val; \ + uint32_t tmp1; \ + uint32_t tmp2; \ + uint32_t tmp3; \ + \ + asm volatile ( \ + ".set push\n" \ + ".set mips64\n" \ + "dsll %[tmp1], %[valh], 32\n" \ + "dsll %[tmp2], %[csrh], 32\n" \ + "dsll %[tmp3], %[vall], 32\n" \ + "dsrl %[tmp3], %[tmp3], 32\n" \ + "or %[tmp1], %[tmp1], %[tmp3]\n" \ + "dsll %[tmp3], %[csrl], 32\n" \ + "dsrl %[tmp3], %[tmp3], 32\n" \ + "or %[tmp2], %[tmp2], %[tmp3]\n" \ + ST " %[tmp1], 0(%[tmp2])\n" \ + ".set pop\n" \ + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3)\ + : [valh] "r" (valh), [vall] "r" (vall), \ + [csrh] "r" (csr_addrh), [csrl] "r" (csr_addrl) \ + ); \ + } \ + else \ + { \ + uint32_t csr_addrh = csr_addr>>32; \ + uint32_t csr_addrl = csr_addr; \ + uint32_t tmp1; \ + uint32_t tmp2; \ + \ + asm volatile ( \ + ".set push\n" \ + ".set mips64\n" \ + "dsll %[tmp1], %[csrh], 32\n" \ + "dsll %[tmp2], %[csrl], 32\n" \ + "dsrl %[tmp2], %[tmp2], 32\n" \ + "or %[tmp1], %[tmp1], %[tmp2]\n" \ + ST " %[val], 0(%[tmp1])\n" \ + ".set pop\n" \ + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2) \ + : [val] "r" (val), [csrh] "r" (csr_addrh), \ + [csrl] "r" (csr_addrl) \ + ); \ + } \ +} + +#endif + +#else + +/* cvmx-abi.h didn't recognize the ABI. Force the compile to fail. */ +#error: Unsupported ABI + +#endif + +/* The following #if controls the definition of the macro + CVMX_BUILD_READ64. This macro is used to build a load operation from + a full 64bit address. With a 64bit ABI, this can be done with a simple + pointer access. 32bit ABIs require more complicated assembly */ +#if defined(CVMX_ABI_N64) || defined(CVMX_ABI_EABI) + +/* We have a full 64bit ABI. Writing to a 64bit address can be done with + a simple volatile pointer */ +#define CVMX_BUILD_READ64(TYPE, LT) \ +static inline TYPE##_t cvmx_read64_##TYPE(uint64_t addr) \ +{ \ + return *CASTPTR(volatile TYPE##_t, addr); \ +} + +#elif defined(CVMX_ABI_N32) + +/* The N32 ABI passes all 64bit quantities in a single register, so it is + possible to use the arguments directly. We have to use inline assembly + for the actual store since a pointer would truncate the address */ +#define CVMX_BUILD_READ64(TYPE, LT) \ +static inline TYPE##_t cvmx_read64_##TYPE(uint64_t addr) \ +{ \ + TYPE##_t val; \ + asm volatile (LT " %[v], 0(%[c])": [v] "=r" (val) : [c] "r" (addr));\ + return val; \ +} + +#elif defined(CVMX_ABI_O32) + +#ifdef __KERNEL__ +#define CVMX_BUILD_READ64(TYPE, LT) extern TYPE##_t cvmx_read64_##TYPE(uint64_t csr_addr); +#else + +/* Ok, now the ugly stuff starts. O32 splits 64bit quantities into two + separate registers. Assembly must be used to put them back together + before they're used. What should be a simple load becomes a + convoluted mess of shifts and ors */ +#define CVMX_BUILD_READ64(TYPE, LT) \ +static inline TYPE##_t cvmx_read64_##TYPE(uint64_t csr_addr) \ +{ \ + if (sizeof(TYPE##_t) == 8) \ + { \ + uint32_t csr_addrh = csr_addr>>32; \ + uint32_t csr_addrl = csr_addr; \ + uint32_t valh; \ + uint32_t vall; \ + \ + asm volatile ( \ + ".set push\n" \ + ".set mips64\n" \ + "dsll %[valh], %[csrh], 32\n" \ + "dsll %[vall], %[csrl], 32\n" \ + "dsrl %[vall], %[vall], 32\n" \ + "or %[valh], %[valh], %[vall]\n" \ + LT " %[vall], 0(%[valh])\n" \ + "dsrl %[valh], %[vall], 32\n" \ + "sll %[vall], 0\n" \ + "sll %[valh], 0\n" \ + ".set pop\n" \ + : [valh] "=&r" (valh), [vall] "=&r" (vall) \ + : [csrh] "r" (csr_addrh), [csrl] "r" (csr_addrl) \ + ); \ + return ((uint64_t)valh<<32) | vall; \ + } \ + else \ + { \ + uint32_t csr_addrh = csr_addr>>32; \ + uint32_t csr_addrl = csr_addr; \ + TYPE##_t val; \ + uint32_t tmp; \ + \ + asm volatile ( \ + ".set push\n" \ + ".set mips64\n" \ + "dsll %[val], %[csrh], 32\n" \ + "dsll %[tmp], %[csrl], 32\n" \ + "dsrl %[tmp], %[tmp], 32\n" \ + "or %[val], %[val], %[tmp]\n" \ + LT " %[val], 0(%[val])\n" \ + ".set pop\n" \ + : [val] "=&r" (val), [tmp] "=&r" (tmp) \ + : [csrh] "r" (csr_addrh), [csrl] "r" (csr_addrl) \ + ); \ + return val; \ + } \ +} + +#endif /* __KERNEL__ */ + +#else + +/* cvmx-abi.h didn't recognize the ABI. Force the compile to fail. */ +#error: Unsupported ABI + +#endif + +/* The following defines 8 functions for writing to a 64bit address. Each + takes two arguments, the address and the value to write. + cvmx_write64_int64 cvmx_write64_uint64 + cvmx_write64_int32 cvmx_write64_uint32 + cvmx_write64_int16 cvmx_write64_uint16 + cvmx_write64_int8 cvmx_write64_uint8 */ +CVMX_BUILD_WRITE64(int64, "sd"); +CVMX_BUILD_WRITE64(int32, "sw"); +CVMX_BUILD_WRITE64(int16, "sh"); +CVMX_BUILD_WRITE64(int8, "sb"); +CVMX_BUILD_WRITE64(uint64, "sd"); +CVMX_BUILD_WRITE64(uint32, "sw"); +CVMX_BUILD_WRITE64(uint16, "sh"); +CVMX_BUILD_WRITE64(uint8, "sb"); + +/* The following defines 8 functions for reading from a 64bit address. Each + takes the address as the only argument + cvmx_read64_int64 cvmx_read64_uint64 + cvmx_read64_int32 cvmx_read64_uint32 + cvmx_read64_int16 cvmx_read64_uint16 + cvmx_read64_int8 cvmx_read64_uint8 */ +CVMX_BUILD_READ64(int64, "ld"); +CVMX_BUILD_READ64(int32, "lw"); +CVMX_BUILD_READ64(int16, "lh"); +CVMX_BUILD_READ64(int8, "lb"); +CVMX_BUILD_READ64(uint64, "ld"); +CVMX_BUILD_READ64(uint32, "lw"); +CVMX_BUILD_READ64(uint16, "lhu"); +CVMX_BUILD_READ64(uint8, "lbu"); + +static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val) +{ + cvmx_write64_uint64(csr_addr, val); + + /* Perform an immediate read after every write to an RSL register to force + the write to complete. It doesn't matter what RSL read we do, so we + choose CVMX_MIO_BOOT_BIST_STAT because it is fast and harmless */ + if ((csr_addr >> 40) == (0x800118)) + cvmx_read64_uint64(CVMX_MIO_BOOT_BIST_STAT); +} + +static inline void cvmx_write_io(uint64_t io_addr, uint64_t val) +{ + cvmx_write64_uint64(io_addr, val); +} + +static inline uint64_t cvmx_read_csr(uint64_t csr_addr) +{ + return cvmx_read64_uint64(csr_addr); +} + +static inline void cvmx_send_single(uint64_t data) +{ + const uint64_t CVMX_IOBDMA_SENDSINGLE = 0xffffffffffffa200ull; + cvmx_write64_uint64(CVMX_IOBDMA_SENDSINGLE, data); +} + +static inline void cvmx_read_csr_async(uint64_t scraddr, uint64_t csr_addr) +{ + union + { + uint64_t u64; + struct { + uint64_t scraddr : 8; + uint64_t len : 8; + uint64_t addr :48; + } s; + } addr; + addr.u64 = csr_addr; + addr.s.scraddr = scraddr >> 3; + addr.s.len = 1; + cvmx_send_single(addr.u64); +} + + +/** + * Number of the Core on which the program is currently running. + * + * @return Number of cores + */ +static inline unsigned int cvmx_get_core_num(void) +{ + unsigned int core_num; + CVMX_RDHWRNV(core_num, 0); + return core_num; +} + + +/** + * Returns the number of bits set in the provided value. + * Simple wrapper for POP instruction. + * + * @param val 32 bit value to count set bits in + * + * @return Number of bits set + */ +static inline uint32_t cvmx_pop(uint32_t val) +{ + uint32_t pop; + CVMX_POP(pop, val); + return pop; +} + + +/** + * Returns the number of bits set in the provided value. + * Simple wrapper for DPOP instruction. + * + * @param val 64 bit value to count set bits in + * + * @return Number of bits set + */ +static inline int cvmx_dpop(uint64_t val) +{ + int pop; + CVMX_DPOP(pop, val); + return pop; +} + + +/** + * Provide current cycle counter as a return value + * + * @return current cycle counter + */ +static inline uint64_t cvmx_get_cycle(void) +{ +#if defined(CVMX_ABI_O32) + uint32_t tmp_low, tmp_hi; + + asm volatile ( + " .set push \n" + " .set mips64r2 \n" + " .set noreorder \n" + " rdhwr %[tmpl], $31 \n" + " dsrl %[tmph], %[tmpl], 32 \n" + " sll %[tmpl], 0 \n" + " sll %[tmph], 0 \n" + " .set pop \n" + : [tmpl] "=&r" (tmp_low), [tmph] "=&r" (tmp_hi) : ); + + return(((uint64_t)tmp_hi << 32) + tmp_low); +#else + uint64_t cycle; + CVMX_RDHWR(cycle, 31); + return(cycle); +#endif +} + + +/** + * Reads a chip global cycle counter. This counts CPU cycles since + * chip reset. The counter is 64 bit. + * This register does not exist on CN38XX pass 1 silicion + * + * @return Global chip cycle count since chip reset. + */ +static inline uint64_t cvmx_get_cycle_global(void) +{ + if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)) + return 0; + else + return cvmx_read64_uint64(CVMX_IPD_CLK_COUNT); +} + + +/** + * Wait for the specified number of cycle + * + * @param cycles + */ +static inline void cvmx_wait(uint64_t cycles) +{ + uint64_t done = cvmx_get_cycle() + cycles; + + while (cvmx_get_cycle() < done) + { + /* Spin */ + } +} + + +/** + * Wait for the specified number of micro seconds + * + * @param usec micro seconds to wait + */ +static inline void cvmx_wait_usec(uint64_t usec) +{ + uint64_t done = cvmx_get_cycle() + usec * cvmx_sysinfo_get()->cpu_clock_hz / 1000000; + while (cvmx_get_cycle() < done) + { + /* Spin */ + } +} + + +/** + * Perform a soft reset of Octeon + * + * @return + */ +static inline void cvmx_reset_octeon(void) +{ + cvmx_ciu_soft_rst_t ciu_soft_rst; + ciu_soft_rst.u64 = 0; + ciu_soft_rst.s.soft_rst = 1; + cvmx_write_csr(CVMX_CIU_SOFT_RST, ciu_soft_rst.u64); +} + + +/** + * Read a byte of fuse data + * @param byte_addr address to read + * + * @return fuse value: 0 or 1 + */ +static inline uint8_t cvmx_fuse_read_byte(int byte_addr) +{ + cvmx_mio_fus_rcmd_t read_cmd; + + read_cmd.u64 = 0; + read_cmd.s.addr = byte_addr; + read_cmd.s.pend = 1; + cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); + while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) && read_cmd.s.pend) + ; + return(read_cmd.s.dat); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-vendor@FreeBSD.ORG Tue Jul 20 07:12:44 2010 Return-Path: Delivered-To: svn-src-vendor@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6885F1065676; Tue, 20 Jul 2010 07:12:44 +0000 (UTC) (envelope-from jmallett@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3E4F88FC12; Tue, 20 Jul 2010 07:12:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6K7Cibr021254; Tue, 20 Jul 2010 07:12:44 GMT (envelope-from jmallett@svn.freebsd.org) Received: (from jmallett@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6K7CipP021253; Tue, 20 Jul 2010 07:12:44 GMT (envelope-from jmallett@svn.freebsd.org) Message-Id: <201007200712.o6K7CipP021253@svn.freebsd.org> From: Juli Mallett Date: Tue, 20 Jul 2010 07:12:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org X-SVN-Group: vendor-sys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210285 - vendor-sys/octeon-sdk/1.9.0 X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Jul 2010 07:12:44 -0000 Author: jmallett Date: Tue Jul 20 07:12:43 2010 New Revision: 210285 URL: http://svn.freebsd.org/changeset/base/210285 Log: Tag version 1.9.0 of Octeon SDK files. Added: vendor-sys/octeon-sdk/1.9.0/ - copied from r210284, vendor-sys/octeon-sdk/dist/ From owner-svn-src-vendor@FreeBSD.ORG Tue Jul 20 19:06:18 2010 Return-Path: Delivered-To: svn-src-vendor@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4ACDB1065670; Tue, 20 Jul 2010 19:06:18 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 20D618FC1B; Tue, 20 Jul 2010 19:06:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6KJ6I0Q082534; Tue, 20 Jul 2010 19:06:18 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6KJ6I55082533; Tue, 20 Jul 2010 19:06:18 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201007201906.o6KJ6I55082533@svn.freebsd.org> From: Ed Schouten Date: Tue, 20 Jul 2010 19:06:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210307 - vendor/llvm/llvm-r108428 X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Jul 2010 19:06:18 -0000 Author: ed Date: Tue Jul 20 19:06:17 2010 New Revision: 210307 URL: http://svn.freebsd.org/changeset/base/210307 Log: Add missing LLVM tag. Added: vendor/llvm/llvm-r108428/ - copied from r210306, vendor/llvm/dist/ From owner-svn-src-vendor@FreeBSD.ORG Tue Jul 20 19:06:38 2010 Return-Path: Delivered-To: svn-src-vendor@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 34B791065673; Tue, 20 Jul 2010 19:06:38 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0ABB78FC1C; Tue, 20 Jul 2010 19:06:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6KJ6bWF082640; Tue, 20 Jul 2010 19:06:37 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6KJ6bTP082639; Tue, 20 Jul 2010 19:06:37 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201007201906.o6KJ6bTP082639@svn.freebsd.org> From: Ed Schouten Date: Tue, 20 Jul 2010 19:06:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210308 - vendor/clang/clang-r108428 X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Jul 2010 19:06:38 -0000 Author: ed Date: Tue Jul 20 19:06:37 2010 New Revision: 210308 URL: http://svn.freebsd.org/changeset/base/210308 Log: Add missing Clang tag. Added: vendor/clang/clang-r108428/ - copied from r210307, vendor/clang/dist/