Ejemplo n.º 1
0
extern VOID
CPUMON_Remove_Cpuhooks (
    void
)
{
#if defined(PERFMON_V1) || defined(PERFMON_V2_ALT)
    int status;

    SEP_PRINT_DEBUG("CPUMON_Remove_Cpuhooks: entered... pmv=0x%p \n", SYS_Read_PMV());

    /*
     * if Perfmon1 or Perfmon2_alt is set, we used the perfmon.c
     * interface to steal perfmon.c's interrupt handler for our use.
     * Now we must release it back.
     * Don't free_irq() because perfmon.c still wants to use it
     */
     status = CPUMON_REMOVE_INTERRUPT(&desc);
     if (status) {
         SEP_PRINT_WARNING("CPUMON_Remove_Cpuhooks: CPUMON_REMOVE_INTERRUPT returned: %d\n",status);
     }

#elif !defined(PERFMON_V2)
    SEP_PRINT_DEBUG("CPUMON_Remove_Cpuhooks: entered... pmv=0x%p \n", SYS_Read_PMV());
    if (xchg(&pebs_irqaction, 0)) {
        free_irq(ebs_irq, NULL);
    }
#endif

    SEP_PRINT_DEBUG("CPUMON_Remove_Cpuhooks: exit... pmv=0x%p \n", SYS_Read_PMV());

    return;
}
Ejemplo n.º 2
0
extern VOID
UTILITY_Set_PMV_Mask (
    VOID
)
{
    U64 pmv;

    pmv = SYS_Read_PMV();
    pmv |= PMV_MASK_BIT;
    SYS_Write_PMV(pmv);

    return;
}
Ejemplo n.º 3
0
extern VOID
UTILITY_Clear_PMV_Mask (
    VOID
)
{
    U64 pmv;

    pmv = SYS_Read_PMV();
    pmv &= ~PMV_MASK_BIT;
    SYS_Write_PMV(pmv);

    return;
}
Ejemplo n.º 4
0
/*!
 * @fn          int CPUMON_Install_Cpuhooks(VOID)
 * @brief       Assign the PMU interrupt to the driver
 *
 * @return      zero if successful, non-zero error value if something failed
 *
 * Install the driver ebs handler onto the PMU interrupt. If perfmon is
 * compiled in then we ask perfmon for the interrupt, otherwise we ask the
 * kernel...
 *
 * <I>Special Notes:</I>
 *
 * @Note This routine is for Itanium(R)-based systems only!
 *
 *      For IA32, the LBRs are not frozen when a PMU interrupt is taken.
 * Since the LBRs capture information on every branch, for the LBR
 * registers to be useful, we need to freeze them as quickly as
 * possible after the interrupt. This means hooking the IDT directly
 * to call a driver specific interrupt handler. That happens in the
 * vtxsys.S file via samp_get_set_idt_entry. The real routine being
 * called first upon PMU interrupt is t_ebs (in vtxsys.S) and that
 * routine calls PMI_Interrupt_Handler()...
 *
 */
extern void
CPUMON_Install_Cpuhooks (
    void
)
{
    int status = -1;

    SEP_PRINT_DEBUG("CPUMON_Install_Cpuhooks: entered... pmv 0x%p \n", SYS_Read_PMV());

#if defined(PERFMON_V1) || defined(PERFMON_V2_ALT)
    /*
     * if Perfmon1 or Perfmon2_alt is set, we can use the perfmon.c
     * interface to steal perfmon.c's interrupt handler for our use
     * perfmon.c has already done register_percpu_irq()
     */

     ebs_irq      = SEP_PERFMON_IRQ;
     desc.handler = &PMI_Interrupt_Handler;
     status       = CPUMON_INSTALL_INTERRUPT(&desc);
     if (status) {
         SEP_PRINT_ERROR("CPUMON_Install_Cpuhooks: CPUMON_INSTALL_INTERRUPT returned %d\n",status);
     }
#elif !defined(PERFMON_V2)
    if (pebs_irqaction) {
        return status;
    }

#ifdef SA_PERCPU_IRQ_SUPPORTED
    ebs_irq        = SEP_PERFMON_IRQ;
    pebs_irqaction = (struct irqaction *) 1;
    status         = request_irq(SEP_PERFMON_IRQ,
                                 PMI_Interrupt_Handler,
                                 SA_INTERRUPT | SA_PERCPU_IRQ,
                                 "SEP Sampling",
                                 NULL);

#else
    {
        pebs_irqaction = kmalloc(sizeof (struct irqaction), GFP_ATOMIC);
        if (pebs_irqaction) {
            memset(pebs_irqaction, 0, sizeof (struct irqaction));
            ebs_irq                 = SEP_PERFMON_IRQ;
            pebs_irqaction->handler = (void *)PMI_Interrupt_Handler;
            pebs_irqaction->flags   = SA_INTERRUPT;
            pebs_irqaction->name    = SEP_DRIVER_NAME;
            pebs_irqaction->dev_id  = NULL;

            register_percpu_irq(ebs_irq, pebs_irqaction);
            status = 0;
        }
        else {
            SEP_PRINT_WARNING("couldn't kmalloc pebs_irqaction (%d bytes)\n",
                              (int)sizeof(struct irqaction));
        }
    }
#endif
#endif
    SEP_PRINT("IRQ vector 0x%x will be used for handling PMU interrupts\n", SEP_PERFMON_IRQ);

    SEP_PRINT_DEBUG("CPUMON_Install_Cpuhooks: exit...... rc=0x%x pmv=0x%p \n",
                    status, SYS_Read_PMV());

    return;
}