使用Hifive1 RevB的PLIC中断处理

使用Hifive1 RevB的PLIC中断处理,c,assembly,riscv,C,Assembly,Riscv,我正在为SiFive HiFive1 RevB编写一个HAL。我对中断处理有问题。 代码如下: int main (void) { int rc; unsigned int gpio = 7; set_freq_320MHz(); uint32_t mstatus, mie; __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus)); mie = 0;

我正在为SiFive HiFive1 RevB编写一个HAL。我对中断处理有问题。 代码如下:

int main (void)
{
    int rc;
    unsigned int gpio = 7;

    set_freq_320MHz();

    uint32_t mstatus, mie;

    __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus));

    mie = 0;
    __asm__ volatile("csrw mie, %0" : : "r"(mie));
    __asm__ volatile("csrw mtvec, %I" : : "r"((unsigned long)&interrupt_service_routine));
    //plic_interrupt_enable:
    uint32_t mie;

    __asm__ volatile("csrr %0, mie" : "=r"(mie));

    mie |= MIE_MEIE;
    __asm__ volatile("csrw mie, %0" : : "r"(mie));
    PLIC_REG(PLIC_ENABLE_OFFSET) = 0;
    PLIC_REG(PLIC_ENABLE_OFFSET_2) = 0;
    mstatus = MSTATUS_MIE;
    __asm__ volatile("csrw mstatus, %0" : : "r"(mstatus));

    //gpio_interrupt_enable:
    irq_functions[IRQ_GPIO + gpio].irq_handler = isr;
    irq_functions[IRQ_GPIO + gpio].active = 1;
    irq_functions[IRQ_GPIO + gpio].priority = prio;

    if ((IRQ_GPIO + gpio) > PLIC_ENABLE_OFFSET_MAX)
    {
        PLIC_REG(PLIC_ENABLE_OFFSET_2) |= (1 << (31 -IRQ_GPIO + gpio));
    }
    else
    {
        PLIC_REG(PLIC_ENABLE_OFFSET) |= (1 << (IRQ_GPIO + gpio));
    }

    PLIC_REG(PLIC_PRIORITY_OFFSET + 4 * (IRQ_GPIO + gpio)) = prio;

    rc = gpio_init_input(gpio, GPIO_PUP_EN);

    for(int i = 0; i < 100000; i++)
        ;

    __asm__ volatile ("wfi");

    while (1)
    {
        
    }

    return 0;
}



void handler()
{
    printf("Interrupt taken");
    uint32_t in = GPIO_REG(GPIO_FALL_IP);

    GPIO_REG(GPIO_FALL_IP) = in;
}

void interrupt_service_routine()
{

uint32_t mscratch;

__asm__ volatile("csrrw a0, mscratch, a0\n\t"
                 "sw a1, 0(a0)\n\t"
                 "sw a2, 4(a0)\n\t"
                 "sw a3, 8(a0)\n\t"
                 "sw a4, 12(a0)\n\t");

__asm__ volatile("csrr %0, mcause" : "=r"(mscratch));
if (mscratch & MCAUSE_INT)
{
    if (mscratch & MCAUSE_MTI)
        ; /* Clic interrupt handling not yet coded */
    else if (mscratch & MCAUSE_MSI)
        ; /* Clic interrupt handling not yet coded */
    else if (mscratch & MCAUSE_MEI)
    {
        plic_interrupt_handler();
    }
}

__asm__ volatile("lw a4, 12(a0)\n\t"
                 "lw a3, 8(a0)\n\t"
                 "lw a2, 4(a0)\n\t"
                 "lw a1, 0(a0)\n\t"
                 "csrrw a0, mscratch, a0\n\t"
                 "mret");
}
void plic_interrupt_handler()
{

uint32_t pending, claim;
unsigned int int_number;

pending = PLIC_REG(PLIC_PENDING_OFFSET);
claim = PLIC_REG(PLIC_CLAIM_OFFSET);

int_number = sqrt(claim) - 1;

if (irq_functions[int_number].active)
{
    irq_functions[int_number].irq_handler();
}
} 
int main(无效)
{
int rc;
无符号整数gpio=7;
设置频率为320MHz();
uint32_t mstatus,mie;
__asm_uuuuuuuuuvolatile(“csrr%0,mstatus”:“=r”(mstatus));
mie=0;
__asm_uuu挥发性(“csrw mie,%0):“r”(mie));
__asm_uuuuuvolatile(“csrw mtvec,%I”::“r”((无符号长)和中断服务例程));
//plic_中断_启用:
uint32_t mie;
__asm_uuuuuuvolatile(“csrr%0,mie”:“=r”(mie));
mie |=mie|MEIE;
__asm_uuu挥发性(“csrw mie,%0):“r”(mie));
PLIC_REG(PLIC_ENABLE_OFFSET)=0;
PLIC_REG(PLIC_ENABLE_OFFSET_2)=0;
mstatus=mstatus_MIE;
__asm_uuuu挥发性(“csrw mstatus,%0):“r”(mstatus));
//gpio_中断_启用:
irq_函数[irq_GPIO+GPIO].irq_handler=isr;
irq_函数[irq_GPIO+GPIO]。活动=1;
irq_函数[irq_GPIO+GPIO]。优先级=优先级;
如果((IRQ\U GPIO+GPIO)>PLIC\U启用\U偏移量\U最大值)
{
PLIC_REG(PLIC_ENABLE_OFFSET_2)|=(1