c - BCM2708 (RPi) Rasbpian FIQ not triggered -


i have written linux loadable kernel module attempts attach fiq service gpio edge transistions. pin in question on gpio0 (irq 49) attempt configure fiq follows:

#ifndef gpio_base #define gpio_base       0x7e200000 #endif #define gpio_len        0x60 #define gpio_gpeds0     0x10 #define gpio_gpeds1     0x11 #define gpio_gpren0     0x13 #define gpio_gpren1     0x14 #define gpio_gpfen0     0x16 #define gpio_gpfen1     0x17  #define air_base    0x7e00b200 #define air_len     0x28 #define air_ip2     2    // irq pending source 63:32 #define air_fiq     3    // fiq config register #define air_fiq_an  0x80l   //      fiq enable field mask #define air_fiq_src 0x7fl   //      fiq source field mask #define air_en2     5    // irq enable irq source 63:32 #define air_de2     8    // irq disable irq source 63:32  #define air_gpio0_irq   49  struct {     uint32_t wr_p;        } fiq_data_s;  extern unsigned char pulse_logger_fiq_handler, pulse_logger_fiq_handler_end;  static struct fiq_handler pulse_logger_fh = {     .name   = "pulse_logger_fiq_handler" };  static int __init pulse_logger_init(void) {     gpioreg = ioremap(gpio_base, gpio_len);     aircreg = ioremap(air_base, air_len);     fiq_data_s.wr_p  = (uint32_t)&wr_p;                         // log offset store system counter      printk(kern_info "enabling fiq...\n");      printk(kern_info "\tdisable gpio0 irq\n");     // disable irq tied fiq     disable_irq_nosync(air_gpio0_irq);      printk(kern_info "\tconfig gpio edge events\n");     writel(air_gpio0_msk, gpioreg + gpio_gpeds0);     gpren0 = readl((const volatile void *)(gpioreg + gpio_gpren0));     gpren0 |= air_gpio0_msk;     writel(gpren0, gpioreg + gpio_gpren0);     gpfen0 = readl((const volatile void *)(gpioreg + gpio_gpfen0));     gpfen0 |= air_gpio0_msk;     writel(gpfen0, gpioreg + gpio_gpfen0);      printk(kern_info "\tclaim fiq\n");     // reserve fiq     ret = claim_fiq(&pulse_logger_fh);     if (ret){         printk(kern_info "failed claim fiq (%d)!\n", ret);         goto fail1;     }      // copy fiq vector location     printk(kern_info "\tcopying handler\n");     set_fiq_handler(&pulse_logger_fiq_handler,             &pulse_logger_fiq_handler_end - &pulse_logger_fiq_handler);      // store symbol pointers in fiq registers     printk(kern_info "\tstoring registers\n");     memset(&regs,0, sizeof(regs));     regs.arm_r8  = (long)&fiq_data_s;     set_fiq_regs(&regs);      printk(kern_info "\tenable fiq\n");     // enable fiq     enable_fiq(air_gpio0_irq);     local_fiq_enable();      return 0; } 

i find fiq register has invalid entry of 0x54 force fiq register:

writel(0x80 | air_gpio0_irq, (volatile void *)(aircreg + air_fiq)); 

i have written fiq follows:

#define data_ack_offset     12  entry(pulse_logger_fiq_handler)         /* acknowledge interrupt */         /* write pin_ack event_status_offset register */         ldr r14, [r8, #data_ack_offset]     /* load address */         mov r12, #pin_ack         str r12, [r14, #0]          ldr r14, [r8, #0]   /* load address */         ldr r14, [r14, #0]  /* load value */         add r14, r14, #1         ldr r12, [r8, #0]   /* load address */         str r14, [r12, #0]          /* return fiq */         subs  pc, lr, #4 pulse_logger_fiq_handler_end: 

i toggle line 20 times (using gpio) @ end of run wr_p == 1.

if run code standard isr wr_p == 20, leaving me believe isr code valid, need understand why fiq appears firing once.

static irqreturn_t pulse_isr(int irq, void *data) {     uint32_t fiq_data_addr = (uint32_t)&fiq_data_s;     *((uint32_t*)*((uint32_t*)fiq_data_addr)) += 1;      __asm__ __volatile__ (         "mov r8,  %[fiqbase]    \n"          "ldr r14, [r8, #12]    \n\t"     /* load address */         "mov r12, #0x00000010    \n\t"         "str r12, [r14, #0]    \n\t"          "ldr r14, [r8, #0]    \n\t"/* load address */         "ldr r14, [r14, #0]                  \n\t"/* load value */         "add r14, r14, #1                    \n\t"         "ldr r12, [r8, #0]    \n\t"   /* load address */         "str r14, [r12, #0]                  \n\t"         :: [fiqbase] "r" (fiq_data_addr)         : "r8", "r12", "r14");     return irq_handled; } 

if dig in [local_]enable_fiq() doesn't touches hardware @ why think have write register but, don't see happening in other drivers have looked @ online i'm confused.

is there reason why triggering once (even if don't write fiq register)?

i figured out, r13-r14 not general purpose registers. these sp , lr.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337h/chdedegj.html

a rewrite use r8-r12 has working.


Comments

Popular posts from this blog

java - UnknownEntityTypeException: Unable to locate persister (Hibernate 5.0) -

python - ValueError: empty vocabulary; perhaps the documents only contain stop words -

ubuntu - collect2: fatal error: ld terminated with signal 9 [Killed] -