patch-2.4.20 linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
Next file: linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.h
Previous file: linux-2.4.20/arch/mips/sibyte/sb1250/Makefile
Back to the patch index
Back to the overall index
- Lines: 109
- Date:
Thu Nov 28 15:53:10 2002
- Orig file:
linux-2.4.19/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
- Orig date:
Fri Aug 2 17:39:43 2002
diff -urN linux-2.4.19/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
@@ -10,7 +10,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -50,20 +50,26 @@
* overflow.
*
* We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
- *
+ *
************************************************************************/
-/* Once per second on a 500 Mhz 1250 */
-#define TB_PERIOD 250000000ULL
+/* 100 samples per second on a 500 Mhz 1250 */
+#define TB_PERIOD 2500000ULL
static void arm_tb(void)
{
+ unsigned long long scdperfcnt;
unsigned long long next = (1ULL << 40) - TB_PERIOD;
/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
trigger start of trace. XXX vary sampling period */
out64(0, KSEG1 + A_SCD_PERF_CNT_1);
- out64(in64(KSEG1 + A_SCD_PERF_CNT_CFG) | // keep counters 0,2,3 as is
+ scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG);
+ /* Unfortunately, in Pass 2 we must clear all counters to knock down
+ a previous interrupt request. This means that bus profiling
+ requires ALL of the SCD perf counters. */
+ out64((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
M_SPC_CFG_ENABLE | // enable counting
+ M_SPC_CFG_CLEAR | // clear all counters
V_SPC_CFG_SRC1(1), // counter 1 counts cycles
KSEG1 + A_SCD_PERF_CNT_CFG);
out64(next, KSEG1 + A_SCD_PERF_CNT_1);
@@ -150,17 +156,17 @@
out64(0, KSEG1 + A_ADDR_TRAP_UP_1);
out64(0, KSEG1 + A_ADDR_TRAP_UP_2);
out64(0, KSEG1 + A_ADDR_TRAP_UP_3);
-
+
out64(0, KSEG1 + A_ADDR_TRAP_DOWN_0);
out64(0, KSEG1 + A_ADDR_TRAP_DOWN_1);
out64(0, KSEG1 + A_ADDR_TRAP_DOWN_2);
out64(0, KSEG1 + A_ADDR_TRAP_DOWN_3);
-
+
out64(0, KSEG1 + A_ADDR_TRAP_CFG_0);
out64(0, KSEG1 + A_ADDR_TRAP_CFG_1);
out64(0, KSEG1 + A_ADDR_TRAP_CFG_2);
out64(0, KSEG1 + A_ADDR_TRAP_CFG_3);
-
+
/* Initialize Trace Event 0-7 */
// when interrupt
out64(M_SCD_TREVT_INTERRUPT, KSEG1 + A_SCD_TRACE_EVENT_0);
@@ -171,7 +177,7 @@
out64(0, KSEG1 + A_SCD_TRACE_EVENT_5);
out64(0, KSEG1 + A_SCD_TRACE_EVENT_6);
out64(0, KSEG1 + A_SCD_TRACE_EVENT_7);
-
+
/* Initialize Trace Sequence 0-7 */
// Start on event 0 (interrupt)
out64(V_SCD_TRSEQ_FUNC_START|0x0fff,
@@ -252,7 +258,7 @@
static int sbprof_tb_release(struct inode *inode, struct file *filp)
{
int minor;
-
+
minor = MINOR(inode->i_rdev);
if (minor != 0 || sbp == NULL) {
return -ENODEV;
@@ -269,7 +275,7 @@
return 0;
}
-static ssize_t sbprof_tb_read(struct file *filp, char *buf,
+static ssize_t sbprof_tb_read(struct file *filp, char *buf,
size_t size, loff_t *offp)
{
int cur_sample, sample_off, cur_count, sample_left;
@@ -309,9 +315,9 @@
#define SBPROF_ZBSTOP _IOW('s', 1, int)
#define SBPROF_ZBFULL _IOW('s', 2, int)
-static int sbprof_tb_ioctl(struct inode *inode,
+static int sbprof_tb_ioctl(struct inode *inode,
struct file *filp,
- unsigned int command,
+ unsigned int command,
unsigned long arg)
{
int error = 0;
@@ -346,7 +352,7 @@
static devfs_handle_t devfs_handle;
-static int __init sbprof_tb_init(void)
+static int __init sbprof_tb_init(void)
{
if (devfs_register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)