HPET Timer implementation for multiple IRQ's

Latest response

Problem Statement:

We want to use 8 hpet timers/comparators for generating interrupts in parallel for different applications on RHEL 7.1(3.10.0-229 kernel) on Intel core-i7 processor with RT Patch Kernel build 3.10.75.

When we tried to open /dev/hpet in different user applications , maximum two applications are only allowing to open /dev/hpet device.

We checked dmesg log: we found below log.

hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0, 0, 0, 0, 0

hpet0: 8 comparators, 64-bit 14.318180 MHz counter

In the Hpet specification document software-developers-hpet-spec-1-0a.pdf (attached), they have mentioned as below in section 3.2.2

3.2.2 HPET Block Interrupt Routing
Except for the case where HPET are being used to replace 8254/RTC functionality, all HPET interrupts are disabled.
The OS is responsible for establishing interrupt routing/delivery metrics prior to utilizing any given comparator within a Timer Block.

As per the intel document "564464_HPET.pdf" (attached) currently our system is configured as per section 6.2.4.1 Mapping Option #1 (Legacy Replacement Option)

Due to this in Dmesg IRQs are assigned as 2,8, 0,0,0,0,0,0 in I/O APIC Mode and i have checked "LEG_RT_CNF" in linux/hpet.h directory it i set as value (0x02UL) This means LEG_RT_CNF is set. In Hpet.c present in the path "arch/x86/kernel/hpet.c"

The following function code present as below:

static void hpet_reserve_platform_timers(unsigned int id)
{
struct hpet __iomem *hpet = hpet_virt_address;
struct hpet_timer __iomem *timer = &hpet->hpet_timers[2];
unsigned int nrtimers, i;
struct hpet_data hd;
nrtimers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
memset(&hd, 0, sizeof(hd));
hd.hd_phys_address = hpet_address;
hd.hd_address = hpet;
hd.hd_nirqs = nrtimers;
hpet_reserve_timer(&hd, 0);

ifdef CONFIG_HPET_EMULATE_RTC

hpet_reserve_timer(&hd, 1);

endif

/*
 * NOTE that hd_irq[] reflects IOAPIC input pins (LEGACY_8254
 * is wrong for i8259!) not the output IRQ.  Many BIOS writers
 * don't bother configuring *any* comparator interrupts.
 */
hd.hd_irq[0] = HPET_LEGACY_8254;
hd.hd_irq[1] = HPET_LEGACY_RTC;

for (i = 2; i < nrtimers; timer++, i++) {
    hd.hd_irq[i] = (readl(&timer->hpet_config) &
        Tn_INT_ROUTE_CNF_MASK) >> Tn_INT_ROUTE_CNF_SHIFT;
}
hpet_reserve_msi_timers(&hd);
hpet_alloc(&hd);

}

In the above code the yellow highlighted ones are assigned for first 2 timers (IRQ 2,8) HPET_LEGACY_8254 macro defined in hpet.h as 2 and HPET_LEGACY_RTC macro defined in hpet.h as 8.

As per the document section 6.2.4.2 Mapping Option #2 (Standard Option):

I have updated LEG_RT_CNF values in hpet.h to 0x00UL. and i have assigned 3 IRQ's in hpet.c driver code as below.

static void hpet_reserve_platform_timers(unsigned int id)
{
struct hpet __iomem *hpet = hpet_virt_address;
struct hpet_timer __iomem *timer = &hpet->hpet_timers[2];
unsigned int nrtimers, i;
struct hpet_data hd;
nrtimers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
memset(&hd, 0, sizeof(hd));
hd.hd_phys_address = hpet_address;
hd.hd_address = hpet;
hd.hd_nirqs = nrtimers;
hpet_reserve_timer(&hd, 0);

ifdef CONFIG_HPET_EMULATE_RTC

hpet_reserve_timer(&hd, 1);

endif

/*
 * NOTE that hd_irq[] reflects IOAPIC input pins (LEGACY_8254
 * is wrong for i8259!) not the output IRQ.  Many BIOS writers
 * don't bother configuring *any* comparator interrupts.
 */
hd.hd_irq[0] = 20;          //Added manually
hd.hd_irq[1] = 21;             //Added manually
    hd.hd_irq[2] = 22;           //Added manually
for (i = 3; i < nrtimers; timer++, i++) {
    hd.hd_irq[i] = (readl(&timer->hpet_config) &
        Tn_INT_ROUTE_CNF_MASK) >> Tn_INT_ROUTE_CNF_SHIFT;
}
hpet_reserve_msi_timers(&hd);
hpet_alloc(&hd);

}

I have assigned IRQ0,1,2 to 20,21,22 aftre updation of this code i have build the kernel using commands "make, make modules, make modules_install, make install". After successful build i have rebooted. After rebooting dmesg log contains following output

" IRQ 20,21,22,0,0,0,0,0".

Please clarify the following questions: Kernal version 3.10.75 RT Patch

  1. How to use the Mapping Option #3 (Processor Message Option) to use remaining interrupts? To use this option, Tn_PROCMSG_EN_CNF,Tn_PROCMSG_INT_ADDR & Tn_PROCMSG_INT_VAL fileds are not present in Hpet Header files and c files.

  2. How to check whether all 8 timer interrupts enabled or Not??

  3. If interrupts are enabled, it will show in cat /proc/interrupts file or not?

  4. Can you please provide the procedure for configuring the 8 timer interrups as per the section 6.2.4.2 Mapping Option #3 (Processor Message Option) and sample code for user space applications?

  5. At current we are able to open /dev/hpet in maximum of two(2) user space applications for generating interrupts, But when we opened more than two(2) user space applications ".failed to open /dev/hpet" error and "HPET_IE_ON failed" errors are coming. So please provide the procedure to open /dev/hpet device to generate interrupts for 8 user space applications.

  6. Can you please tell us the meaning of "HPET_IE_ON failed" error. I have attached the user space application code,dmesg log, /proc/interrupts logs for your reference.

Source code of hpet.c can be found in this weblink :

https://elixir.bootlin.com/linux/v3.10.75/source/arch/x86/kernel/hpet.c

Please provide the support and do the needful.

Thanks & Regards

Attachments

Responses