sparc64: Abstract away the NMI PIC counter computation.
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
09d053c797
commit
73a6b0538c
@ -6,6 +6,7 @@ struct pcr_ops {
|
|||||||
void (*write_pcr)(unsigned long, u64);
|
void (*write_pcr)(unsigned long, u64);
|
||||||
u64 (*read_pic)(unsigned long);
|
u64 (*read_pic)(unsigned long);
|
||||||
void (*write_pic)(unsigned long, u64);
|
void (*write_pic)(unsigned long, u64);
|
||||||
|
u64 (*nmi_picl_value)(unsigned int nmi_hz);
|
||||||
};
|
};
|
||||||
extern const struct pcr_ops *pcr_ops;
|
extern const struct pcr_ops *pcr_ops;
|
||||||
|
|
||||||
@ -29,20 +30,6 @@ extern void schedule_deferred_pcr_work(void);
|
|||||||
#define PCR_N2_SL1_SHIFT 27
|
#define PCR_N2_SL1_SHIFT 27
|
||||||
#define PCR_N2_OV1 0x80000000
|
#define PCR_N2_OV1 0x80000000
|
||||||
|
|
||||||
extern unsigned int picl_shift;
|
|
||||||
|
|
||||||
/* In order to commonize as much of the implementation as
|
|
||||||
* possible, we use PICH as our counter. Mostly this is
|
|
||||||
* to accommodate Niagara-1 which can only count insn cycles
|
|
||||||
* in PICH.
|
|
||||||
*/
|
|
||||||
static inline u64 picl_value(unsigned int nmi_hz)
|
|
||||||
{
|
|
||||||
u32 delta = local_cpu_data().clock_tick / (nmi_hz << picl_shift);
|
|
||||||
|
|
||||||
return ((u64)((0 - delta) & 0xffffffff)) << 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern u64 pcr_enable;
|
extern u64 pcr_enable;
|
||||||
|
|
||||||
extern int pcr_arch_init(void);
|
extern int pcr_arch_init(void);
|
||||||
|
@ -125,7 +125,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
|||||||
__this_cpu_write(alert_counter, 0);
|
__this_cpu_write(alert_counter, 0);
|
||||||
}
|
}
|
||||||
if (__get_cpu_var(wd_enabled)) {
|
if (__get_cpu_var(wd_enabled)) {
|
||||||
pcr_ops->write_pic(0, picl_value(nmi_hz));
|
pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
|
||||||
pcr_ops->write_pcr(0, pcr_enable);
|
pcr_ops->write_pcr(0, pcr_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ void start_nmi_watchdog(void *unused)
|
|||||||
atomic_inc(&nmi_active);
|
atomic_inc(&nmi_active);
|
||||||
|
|
||||||
pcr_ops->write_pcr(0, PCR_PIC_PRIV);
|
pcr_ops->write_pcr(0, PCR_PIC_PRIV);
|
||||||
pcr_ops->write_pic(0, picl_value(nmi_hz));
|
pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
|
||||||
|
|
||||||
pcr_ops->write_pcr(0, pcr_enable);
|
pcr_ops->write_pcr(0, pcr_enable);
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ static void nmi_adjust_hz_one(void *unused)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
pcr_ops->write_pcr(0, PCR_PIC_PRIV);
|
pcr_ops->write_pcr(0, PCR_PIC_PRIV);
|
||||||
pcr_ops->write_pic(0, picl_value(nmi_hz));
|
pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
|
||||||
|
|
||||||
pcr_ops->write_pcr(0, pcr_enable);
|
pcr_ops->write_pcr(0, pcr_enable);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
(0xff << PCR_N2_MASK1_SHIFT))
|
(0xff << PCR_N2_MASK1_SHIFT))
|
||||||
|
|
||||||
u64 pcr_enable;
|
u64 pcr_enable;
|
||||||
unsigned int picl_shift;
|
|
||||||
|
|
||||||
/* Performance counter interrupts run unmasked at PIL level 15.
|
/* Performance counter interrupts run unmasked at PIL level 15.
|
||||||
* Therefore we can't do things like wakeups and other work
|
* Therefore we can't do things like wakeups and other work
|
||||||
@ -98,11 +97,19 @@ static void direct_pic_write(unsigned long reg_num, u64 val)
|
|||||||
"rd %%pic, %%g0" : : "r" (val));
|
"rd %%pic, %%g0" : : "r" (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 direct_picl_value(unsigned int nmi_hz)
|
||||||
|
{
|
||||||
|
u32 delta = local_cpu_data().clock_tick / nmi_hz;
|
||||||
|
|
||||||
|
return ((u64)((0 - delta) & 0xffffffff)) << 32;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pcr_ops direct_pcr_ops = {
|
static const struct pcr_ops direct_pcr_ops = {
|
||||||
.read_pcr = direct_pcr_read,
|
.read_pcr = direct_pcr_read,
|
||||||
.write_pcr = direct_pcr_write,
|
.write_pcr = direct_pcr_write,
|
||||||
.read_pic = direct_pic_read,
|
.read_pic = direct_pic_read,
|
||||||
.write_pic = direct_pic_write,
|
.write_pic = direct_pic_write,
|
||||||
|
.nmi_picl_value = direct_picl_value,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void n2_pcr_write(unsigned long reg_num, u64 val)
|
static void n2_pcr_write(unsigned long reg_num, u64 val)
|
||||||
@ -118,11 +125,19 @@ static void n2_pcr_write(unsigned long reg_num, u64 val)
|
|||||||
direct_pcr_write(reg_num, val);
|
direct_pcr_write(reg_num, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 n2_picl_value(unsigned int nmi_hz)
|
||||||
|
{
|
||||||
|
u32 delta = local_cpu_data().clock_tick / (nmi_hz << 2);
|
||||||
|
|
||||||
|
return ((u64)((0 - delta) & 0xffffffff)) << 32;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pcr_ops n2_pcr_ops = {
|
static const struct pcr_ops n2_pcr_ops = {
|
||||||
.read_pcr = direct_pcr_read,
|
.read_pcr = direct_pcr_read,
|
||||||
.write_pcr = n2_pcr_write,
|
.write_pcr = n2_pcr_write,
|
||||||
.read_pic = direct_pic_read,
|
.read_pic = direct_pic_read,
|
||||||
.write_pic = direct_pic_write,
|
.write_pic = direct_pic_write,
|
||||||
|
.nmi_picl_value = n2_picl_value,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long perf_hsvc_group;
|
static unsigned long perf_hsvc_group;
|
||||||
@ -180,7 +195,6 @@ int __init pcr_arch_init(void)
|
|||||||
case hypervisor:
|
case hypervisor:
|
||||||
pcr_ops = &n2_pcr_ops;
|
pcr_ops = &n2_pcr_ops;
|
||||||
pcr_enable = PCR_N2_ENABLE;
|
pcr_enable = PCR_N2_ENABLE;
|
||||||
picl_shift = 2;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cheetah:
|
case cheetah:
|
||||||
|
Loading…
Reference in New Issue
Block a user