[Milkymist-devel] Linux Porting Issues

Sébastien Bourdeauducq sebastien.bourdeauducq at lekernel.net
Mon Aug 17 06:14:13 PDT 2009


Hi,

Where is that value of vec coming from?

asm_do_IRQ is called from entry.S:

ENTRY(interrupt_handler)
	addi    sp, sp, -128
	sw      (sp+120), ra
	calli   _save_irq_frame
	rcsr    r1, IP

	addi    r2, sp, 4
#ifdef CONFIG_IPIPE
	calli		__ipipe_grab_irq
#else
	calli   asm_do_IRQ
#endif
	bi      _restore_irq_frame_and_return
	nop

Can you make sure you do not have CONFIG_IPIPE defined (it is not defined in 
the .config file you sent me)?
If it is not defined, then the value is coming straight from the IP CSR, and 
0x1a means that you have UART TX, UART RX and TIMER0 interrupts pending (see 
milkymist-core/software/include/hw/interrupts.h). This looks very normal, but 
the fact that you have all those three interrupts at the same time suggests 
that they are not acked properly; therefore the interrupt handler could be 
called in a endless loop and cause the system to crash.

Something you must be aware of about the IP CSR is that it shows *all* current 
pending interrupts, including the ones that are currently masked. So you may 
want to AND it with the IM (interrupt mask) CSR. See milkymist-
core/software/baselib/irq.S, milkymist-core/software/demo/isr.c and milkymist-
core/software/baselib/crt0.S.

Acking an interrupt in the Milkymist SoC is done in two steps:
1. first, the interrupt must be acked at the peripheral core level, so that 
the core releases its interrupt line. The procedure is specific to each 
peripheral - see sysctl and UART docs and how they are used in the Milkymist 
source code (the latest SVN revisions use interrupts heavily).
2. the interrupt is then acked at the Mico32 CPU level, by writing to the IP 
CSR (irq_ack function in Milkymist's irq.S).

Sébastien


On Saturday 15 August 2009 23.48.35 you wrote:
> in arch/lm32/kernel/irq.c
> the function:
> void asm_do_IRQ(unsigned long vec, struct pt_regs *regs)
> is called with param vec=0x1a.
> ...
> then it is assigned to irq value.
>
> irq=vec;
>
> pass it (0x1a) as an interrupt request to linux.
>
> actually in irq.c
>
>         /*
>          * Some hardware gives randomly wrong interrupts.  Rather
>          * than crashing, do something sensible.
>          */
>         if (irq >= NR_IRQS)
>                 desc = &bad_irq_desc;
>
> may be we can define NR_IRQS as 9?



More information about the Devel mailing list