Пример #1
0
static irqreturn_t px_pmu_isr(struct pt_regs * const regs,
                              unsigned int pid,
                              unsigned int tid,
                              unsigned int cpu,
                              unsigned long long ts)
{
	u32 pmnc_value;
	u32 flag_value;
	unsigned int i;
	unsigned int reg_id;
	bool buffer_full = false;

	char ** bt_buffer = &per_cpu(g_bt_buffer, cpu);
	PXD32_CSS_Call_Stack_V2 *css_data = (PXD32_CSS_Call_Stack_V2 *)*bt_buffer;

	/* disable the counters */
	pmnc_value = PJ4_Read_PMNC();
	pmnc_value &= ~0x1;
	PJ4_Write_PMNC(pmnc_value);

	/* clear the overflow flag */
	flag_value = PJ4_Read_FLAG();
	PJ4_Write_FLAG(0xffffffff);
	
	if (flag_value != 0)
		backtrace(regs, cpu, pid, tid, css_data);

	if ((flag_value & 0x80000000) && es[COUNTER_PJ4_PMU_CCNT].enabled)
	{
		reg_id = COUNTER_PJ4_PMU_CCNT;

		/* ccnt overflow */
		if (es[reg_id].calibration == false)
		{
			/* write css data in non-calibration mode */
			if (!buffer_full)
			{
				fill_css_data_head(css_data, pid, tid, reg_id, ts);
				buffer_full |= write_css_data(cpu, css_data);
			}
		}
		else
		{
			/* calculate the overflow count in calibration mode */
			es[reg_id].overflow++;
		}

		PJ4_WritePMUCounter(reg_id, es[reg_id].reset_value);
	}

	for (i=0; i<PJ4_PMN_NUM; i++)
	{
		if (flag_value & (0x1 << i))
		{
			switch (i)
			{
			case 0:	reg_id = COUNTER_PJ4_PMU_PMN0; break;
			case 1:	reg_id = COUNTER_PJ4_PMU_PMN1; break;
			case 2:	reg_id = COUNTER_PJ4_PMU_PMN2; break;
			case 3:	reg_id = COUNTER_PJ4_PMU_PMN3; break;
			default: break;
			}

			if (es[reg_id].calibration == false)
			{
				/* write css data in non-calibration mode */
				if (!buffer_full)
				{
					fill_css_data_head(css_data, pid, tid, reg_id, ts);
					buffer_full |= write_css_data(cpu, css_data);
				}
			}
			else
			{
				/* calculate the overflow count in calibration mode */
				es[reg_id].overflow++;
			}

			PJ4_WritePMUCounter(reg_id, es[reg_id].reset_value);
		}

	}

	if (!buffer_full)
	{
		/* enable the counters */
		pmnc_value |= 0x1;
		PJ4_Write_PMNC(pmnc_value);
	}

	return IRQ_HANDLED;
}
Пример #2
0
static irqreturn_t px_pmu_isr(unsigned int pid,
                              unsigned int tid,
                              unsigned int pc,
                              unsigned int timestamp)
{
	u32 pmnc_value;
	u32 flag_value;
	unsigned int i;
	bool buffer_full = false;

	PXD32_Hotspot_Sample sample_rec;

	/* disable the counters */
	pmnc_value = PJ4_Read_PMNC();
	pmnc_value &= ~0x1;
	PJ4_Write_PMNC(pmnc_value);

	/* clear the overflow flag */
	flag_value = PJ4_Read_FLAG();
	PJ4_Write_FLAG(0x8000000f);

	sample_rec.pc = pc;
	sample_rec.pid = pid;
	sample_rec.tid = tid;
	memcpy(sample_rec.timestamp, &timestamp, 3);

	if ((flag_value & 0x80000000) && es[COUNTER_PJ4_PMU_CCNT].enabled)
	{
		sample_rec.registerId = COUNTER_PJ4_PMU_CCNT;

		/* ccnt overflow */
		if (es[sample_rec.registerId].calibration == false)
		{
			/* write sample record in non-calibration mode */
			buffer_full |= write_sample(&sample_rec);
		}
		else
		{
			/* calculate the overflow count in calibration mode */
			es[sample_rec.registerId].overflow++;
		}

		PJ4_WritePMUCounter(sample_rec.registerId, es[sample_rec.registerId].reset_value); 
	}

	for (i=0; i<4; i++)
	{
		if (flag_value & (0x1 << i))
		{
			switch (i)
			{
			case 0:	sample_rec.registerId = COUNTER_PJ4_PMU_PMN0; break;
			case 1:	sample_rec.registerId = COUNTER_PJ4_PMU_PMN1; break;
			case 2:	sample_rec.registerId = COUNTER_PJ4_PMU_PMN2; break;
			case 3:	sample_rec.registerId = COUNTER_PJ4_PMU_PMN3; break;
			default: break;
			}

			if (es[sample_rec.registerId].calibration == false)
			{
				/* write sample record in non-calibration mode */
				buffer_full |= write_sample(&sample_rec);
			}
			else
			{
				/* calculate the overflow count in calibration mode */
				es[sample_rec.registerId].overflow++;
			}

			PJ4_WritePMUCounter(sample_rec.registerId, es[sample_rec.registerId].reset_value); 
		}

	}

	if (!buffer_full)
	{
		/* enable the counters */
		pmnc_value |= 0x1;
		PJ4_Write_PMNC(pmnc_value);
	}

	return IRQ_HANDLED;
}