Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd6c89f6 authored by Andy Fleming's avatar Andy Fleming Committed by Paul Mackerras
Browse files

[POWERPC] Fix oprofile support for e500 in arch/powerpc



Fixed a compile error in building the 85xx support with oprofile, and in
the process cleaned up some issues with the fsl_booke performance monitor
code.

* Reorganized FSL Book-E performance monitoring code so that the 7450
  wouldn't be built if the e500 was, and cleaned it up so it was more
  self-contained.

* Added a cpu_setup function for FSL Book-E.  The original
  cpu_setup function prototype had no arguments, assuming that
  the reg_setup function would copy the required information into
  variables which represented the registers.  This was silly for
  e500, since it has 1 register per counter (rather than 3 for
  all counters), so the code has been restructured to have
  cpu_setup take the current counter config array as an argument,
  with op_powerpc_setup() invoking op_powerpc_cpu_setup() through
  on_each_cpu(), and op_powerpc_cpu_setup() invoking the
  model-specific cpu_setup function with an argument.  The
  argument is ignored on all other platforms at present.

* Fixed a confusing line where a trinary operator only had two
  arguments

Signed-off-by: default avatarAndrew Fleming <afleming@freescale.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent e0da0dae
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -38,7 +38,6 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
obj-$(CONFIG_TAU)		+= tau_6xx.o
obj-$(CONFIG_TAU)		+= tau_6xx.o
obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
obj32-$(CONFIG_MODULES)		+= module_32.o
obj32-$(CONFIG_MODULES)		+= module_32.o
obj-$(CONFIG_E500)		+= perfmon_fsl_booke.o


ifeq ($(CONFIG_PPC_MERGE),y)
ifeq ($(CONFIG_PPC_MERGE),y)


+0 −221
Original line number Original line Diff line number Diff line
/* arch/powerpc/kernel/perfmon_fsl_booke.c
 * Freescale Book-E Performance Monitor code
 *
 * Author: Andy Fleming
 * Copyright (c) 2004 Freescale Semiconductor, Inc
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version
 *  2 of the License, or (at your option) any later version.
 */

#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/prctl.h>

#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/reg.h>
#include <asm/xmon.h>
#include <asm/pmc.h>

static inline u32 get_pmlca(int ctr);
static inline void set_pmlca(int ctr, u32 pmlca);

static inline u32 get_pmlca(int ctr)
{
	u32 pmlca;

	switch (ctr) {
		case 0:
			pmlca = mfpmr(PMRN_PMLCA0);
			break;
		case 1:
			pmlca = mfpmr(PMRN_PMLCA1);
			break;
		case 2:
			pmlca = mfpmr(PMRN_PMLCA2);
			break;
		case 3:
			pmlca = mfpmr(PMRN_PMLCA3);
			break;
		default:
			panic("Bad ctr number\n");
	}

	return pmlca;
}

static inline void set_pmlca(int ctr, u32 pmlca)
{
	switch (ctr) {
		case 0:
			mtpmr(PMRN_PMLCA0, pmlca);
			break;
		case 1:
			mtpmr(PMRN_PMLCA1, pmlca);
			break;
		case 2:
			mtpmr(PMRN_PMLCA2, pmlca);
			break;
		case 3:
			mtpmr(PMRN_PMLCA3, pmlca);
			break;
		default:
			panic("Bad ctr number\n");
	}
}

void init_pmc_stop(int ctr)
{
	u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
			PMLCA_FCM1 | PMLCA_FCM0);
	u32 pmlcb = 0;

	switch (ctr) {
		case 0:
			mtpmr(PMRN_PMLCA0, pmlca);
			mtpmr(PMRN_PMLCB0, pmlcb);
			break;
		case 1:
			mtpmr(PMRN_PMLCA1, pmlca);
			mtpmr(PMRN_PMLCB1, pmlcb);
			break;
		case 2:
			mtpmr(PMRN_PMLCA2, pmlca);
			mtpmr(PMRN_PMLCB2, pmlcb);
			break;
		case 3:
			mtpmr(PMRN_PMLCA3, pmlca);
			mtpmr(PMRN_PMLCB3, pmlcb);
			break;
		default:
			panic("Bad ctr number!\n");
	}
}

void set_pmc_event(int ctr, int event)
{
	u32 pmlca;

	pmlca = get_pmlca(ctr);

	pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
		((event << PMLCA_EVENT_SHIFT) &
		 PMLCA_EVENT_MASK);

	set_pmlca(ctr, pmlca);
}

void set_pmc_user_kernel(int ctr, int user, int kernel)
{
	u32 pmlca;

	pmlca = get_pmlca(ctr);

	if(user)
		pmlca &= ~PMLCA_FCU;
	else
		pmlca |= PMLCA_FCU;

	if(kernel)
		pmlca &= ~PMLCA_FCS;
	else
		pmlca |= PMLCA_FCS;

	set_pmlca(ctr, pmlca);
}

void set_pmc_marked(int ctr, int mark0, int mark1)
{
	u32 pmlca = get_pmlca(ctr);

	if(mark0)
		pmlca &= ~PMLCA_FCM0;
	else
		pmlca |= PMLCA_FCM0;

	if(mark1)
		pmlca &= ~PMLCA_FCM1;
	else
		pmlca |= PMLCA_FCM1;

	set_pmlca(ctr, pmlca);
}

void pmc_start_ctr(int ctr, int enable)
{
	u32 pmlca = get_pmlca(ctr);

	pmlca &= ~PMLCA_FC;

	if (enable)
		pmlca |= PMLCA_CE;
	else
		pmlca &= ~PMLCA_CE;

	set_pmlca(ctr, pmlca);
}

void pmc_start_ctrs(int enable)
{
	u32 pmgc0 = mfpmr(PMRN_PMGC0);

	pmgc0 &= ~PMGC0_FAC;
	pmgc0 |= PMGC0_FCECE;

	if (enable)
		pmgc0 |= PMGC0_PMIE;
	else
		pmgc0 &= ~PMGC0_PMIE;

	mtpmr(PMRN_PMGC0, pmgc0);
}

void pmc_stop_ctrs(void)
{
	u32 pmgc0 = mfpmr(PMRN_PMGC0);

	pmgc0 |= PMGC0_FAC;

	pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);

	mtpmr(PMRN_PMGC0, pmgc0);
}

void dump_pmcs(void)
{
	printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
	printk("pmc\t\tpmlca\t\tpmlcb\n");
	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
			mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
			mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
			mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
			mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
}

EXPORT_SYMBOL(init_pmc_stop);
EXPORT_SYMBOL(set_pmc_event);
EXPORT_SYMBOL(set_pmc_user_kernel);
EXPORT_SYMBOL(set_pmc_marked);
EXPORT_SYMBOL(pmc_start_ctr);
EXPORT_SYMBOL(pmc_start_ctrs);
EXPORT_SYMBOL(pmc_stop_ctrs);
EXPORT_SYMBOL(dump_pmcs);
+1 −1
Original line number Original line Diff line number Diff line
@@ -71,7 +71,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq)
	}
	}


	pmc_owner_caller = __builtin_return_address(0);
	pmc_owner_caller = __builtin_return_address(0);
	perf_irq = new_perf_irq ? : dummy_perf;
	perf_irq = new_perf_irq ? new_perf_irq : dummy_perf;


 out:
 out:
	spin_unlock(&pmc_owner_lock);
	spin_unlock(&pmc_owner_lock);
+1 −1
Original line number Original line Diff line number Diff line
@@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
oprofile-$(CONFIG_PPC32) += op_model_7450.o
oprofile-$(CONFIG_6xx) += op_model_7450.o
+8 −2
Original line number Original line Diff line number Diff line
@@ -34,6 +34,11 @@ static void op_handle_interrupt(struct pt_regs *regs)
	model->handle_interrupt(regs, ctr);
	model->handle_interrupt(regs, ctr);
}
}


static void op_powerpc_cpu_setup(void *dummy)
{
	model->cpu_setup(ctr);
}

static int op_powerpc_setup(void)
static int op_powerpc_setup(void)
{
{
	int err;
	int err;
@@ -47,7 +52,7 @@ static int op_powerpc_setup(void)
	model->reg_setup(ctr, &sys, model->num_counters);
	model->reg_setup(ctr, &sys, model->num_counters);


	/* Configure the registers on all cpus.  */
	/* Configure the registers on all cpus.  */
	on_each_cpu(model->cpu_setup, NULL, 0, 1);
	on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1);


	return 0;
	return 0;
}
}
@@ -142,7 +147,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
		case PPC_OPROFILE_POWER4:
		case PPC_OPROFILE_POWER4:
			model = &op_model_power4;
			model = &op_model_power4;
			break;
			break;
#else
#endif
#ifdef CONFIG_6xx
		case PPC_OPROFILE_G4:
		case PPC_OPROFILE_G4:
			model = &op_model_7450;
			model = &op_model_7450;
			break;
			break;
Loading