cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
tdirksens
Adventurer
Adventurer
4,098 Views
Registered: ‎02-12-2017

Software Interrupts from MicroBlaze to an ARM Core of Zynq

Hi everyone,

 

I wanted to ask how to generate Software Interrupts from a MicroBlaze Core to an ARM Core of the Xilinx Zynq on a Zedboard?

For an Interrupt, have I to enable PL-to-PS-Interrupts in Vivado for example IRQ or nFIQ as usual for hardware interrupts? Or aren't they necessary for software interrupts?

 

I found out, that you can use following code to generate a software interrupt::

ScuGic_SoftwareIntr(<GIC Instance Ptr>, <SW Interrupt ID>, <CPU Mask>)

 

 and this should call the SVC (SWI Handler):

 

SVCHandler:                    /* SWI handler */
    stmdb    sp!,{r0-r3,r12,lr}        /* state save from compiled code */

    tst    r0, #0x20            /* check the T bit */
    ldrneh    r0, [lr,#-2]            /* Thumb mode */
    bicne    r0, r0, #0xff00            /* Thumb mode */
    ldreq    r0, [lr,#-4]            /* ARM mode */
    biceq    r0, r0, #0xff000000        /* ARM mode */

    bl    SWInterrupt            /* SWInterrupt: call C function here */

    ldmia    sp!,{r0-r3,r12,lr}        /* state restore from compiled code */

    movs    pc, lr        /*return to the next instruction after the SWI instruction */


 

This example I think is just for interrupting Core 0, Core 1 or both.. Not interrupting them via MicroBlaze.

 

It would be great, if there's any help.

Thank you in advance!

 

0 Kudos
13 Replies
madhu.mami60
Explorer
Explorer
4,090 Views
Registered: ‎06-19-2015

Hi @tdirksens,

 

Add a AXI_GPIO IP to your Microblaze. Connect the GPIO output to your Zynq Interrupt Pin. 

 

See attachment. 

 

Hope this idea works for you. Mark it as Accepted solution if it works...

 

Thanks

Madhu

madhu.mami60
Explorer
Explorer
4,079 Views
Registered: ‎06-19-2015

Then you can interrupt Zynq by making the GPIO Port high from microblaze... Program the Zynq to edge triggered interrupt.
tdirksens
Adventurer
Adventurer
4,057 Views
Registered: ‎02-12-2017

@madhu.mami60 thanks for the support, I know this way to interrupt Zynq, but the main thing I want to achieve is a system call on it.

 

As I see in the ARM reference for getting a system call, you have to trigger a Softwareinterrupts, so this exception would lead to the Supervisor Call Interrupt handler. That's what I want to trigger via MicroBlaze.

 

If this isn't possible via MicroBlaze, how can I interrupt the Core by itself via SWI so it get into the SVC Handler?
I also used the xscugic_example.c, but when I run the program and the SoftwareInterrupt occurs it goes to the IRQ Routine and not to the SVC Routine as provided in the attached table.

 

 

arm_exc.PNG
0 Kudos
ericv
Scholar
Scholar
4,032 Views
Registered: ‎04-13-2015

@tdirksens

 

The name itself "Software Interrupt" indicates it's an interrupt raised by software and not by hardware.

For hardware interrupts, going through the GIC, (interrupt controller) it is the IRQs that are triggered.

You can always enter the the software interrupt handler with the following in the IRQ handler:

1 - Save the registers (that's the stmdb)

2 - set in R0 the SWI number you need to use

3 - call the SWI handler (bl SWIinterrupt)

4 - restore the registers (that's the ldmia)

5 - exit with subs pc, lr, #4 (this is different from the way SWI exits)

 

Regards

 

tdirksens
Adventurer
Adventurer
4,002 Views
Registered: ‎02-12-2017

@ericv thanks a lot! 

 

so when I use the function "XScuGic_SoftwareIntr" it is generating a hardware interrupt which is going through GIC, but triggered by software? 

 

Just thought it would directly jump to the svc handler in the asm_vector table, because of the relations in the table SWI --> SVC Handler.

 

That's the IRQ Handler which can be found in the Board Supprt Package in Xilinx SDK:

IRQHandler:					/* IRQ vector handler */

	stmdb	sp!,{r0-r3,r12,lr}		/* state save from compiled code*/
#ifdef __ARM_NEON__
	vpush {d0-d7}
	vpush {d16-d31}
	vmrs r1, FPSCR
	push {r1}
	vmrs r1, FPEXC
	push {r1}
#endif

So I have to edit it  in this way you descirbed to got to the software interrupt handler. I will try this out.

What do you mean by Software Number? The Software Interrupt ID?

 

thanks!

0 Kudos
ericv
Scholar
Scholar
3,997 Views
Registered: ‎04-13-2015

@tdirksens

 

so when I use the function "XScuGic_SoftwareIntr" it is generating a hardware interrupt which is going through GIC, but triggered by software? 

Correct, this writes in a GIC register informing the GIC to raise the interrupt.

 

When you use the SVC instruction, you need to specify a number as the argument.

e.g. SVC #123

 

These initial instructions in your original past extract that number (SVC's argument) directly from the instruction.

    tst    r0, #0x20            /* check the T bit */
    ldrneh    r0, [lr,#-2]            /* Thumb mode */
    bicne    r0, r0, #0xff00            /* Thumb mode */
    ldreq    r0, [lr,#-4]            /* ARM mode */
    biceq    r0, r0, #0xff000000        /* ARM mode */

 

The SVC number is used as a way to inform the software interrupt handler what has been requested.

e.g. ARM RealView description for semi-hosting on the M series (Zynq's A9 is an A series):

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0205g/Bgbjhiea.html

 

Regards

tdirksens
Adventurer
Adventurer
3,958 Views
Registered: ‎02-12-2017

@ericv thanks a lot! I will try this out.

 

what about MicroBlaze. Is there a way how to trigger a software interrupt to interrupt Core 0 via MicroBlaze?

0 Kudos
tdirksens
Adventurer
Adventurer
3,921 Views
Registered: ‎02-12-2017

forget about microblaze...

but the thing is I can't get into the SVC Handler in the asm vector table.. that's annoying.. I didn't get it..

what I have done to jump directly to the SVC handler by generating a software interrupt, not via IRQ handler..

 

I can't put this into c-code :/

0 Kudos
ericv
Scholar
Scholar
3,879 Views
Registered: ‎04-13-2015

@tdirksens

 

Substituting the SVC handler in the exception table or the IRQ handler will not work.

The return address (LR register) is not the same (movs pc,lr vs subs pc,lr,#4).

Could you elaborate why you try to get the code to jump into the SVC handler immediately instead of jumping in the SVC core routine from the IRQ?

 

Regards

0 Kudos
tdirksens
Adventurer
Adventurer
2,693 Views
Registered: ‎02-12-2017

@ericv thank you very much for your time and support. I just want to understand, how to get in the SVC handler in  general on the Zynq 7000 SoC. As I said before I expected that triggering a Software Interrupt would jump to the SVC handler as it is described in the references. Now I see it jumps to the IRQ Routine okay, but in which cases then it would jump to SVC?

 

I tried to jump from IRQ to SVC, but I couln't get this working. I'm not so familiar with all these as you already see :D

It would be helpful if there are examples, but didn't find any :/

0 Kudos
ericv
Scholar
Scholar
2,688 Views
Registered: ‎04-13-2015

@tdirksens

 

The easiest way in "C" is to do the following (assuming you want to raise the number 123 SVC:

 

   asm("swi  #123");

 

From an old habit, you should try to not single step on this instruction.

If you want to single step, stop single stepping before it, put a break-point in your SVC handler then let it run.

 

Regards

 

 

0 Kudos
tdirksens
Adventurer
Adventurer
2,674 Views
Registered: ‎02-12-2017

@ericv ah okay, with

 asm("swi  #123");

I get to the svc with address 0x0000007B. (Dez 123 --> HEX 7B), but anyhow it does not jump to the SVC Handler?

0 Kudos
ericv
Scholar
Scholar
2,658 Views
Registered: ‎04-13-2015

@tdirksens

 

investigate what the SWI (now named SVC) instruction performs.

The processor branches (doing other stuff too) to one of the vector table entry and executes the instruction in there.

The vectors table instructions are always filled with the following pseudo-instructions:

     ldr    pc, =Address

Address is the address of what is called the SVC handler.

 

Regards

 

 

 

 

0 Kudos