Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Regular Visitor
pullanlu
Posts: 25
Registered: ‎04-21-2012
0
Accepted Solution

ZC702: How to access custom PL logic from Linux Kernel Module

We added a custom PL logic to Zynq. The xparameters.h of Bare-Metal BSP shows the base address of custom logic is mapped at:

#define XPAR_APB_LOGIC_BASEADDR 0x72800000

#define XPAR_APB_LOGIC_HIGHADDR 0x7287FFFF

And I was able to poke registers at that address region.

 

Xilinx SDK does not generate Zynq BSP for Linux.

How do I find out where the custom logic is mapped to if running Linux?

Access to above region from Linux kernel module caused kernel panic message below:

 

Unable to handle kernel paging request at virtual address 72800000
pgd = d680c000
[72800000] *pgd=00000000
Internal error: Oops: 5 [#1] PREEMPT SMP
Modules linked in: sevdev(+)
CPU: 0    Not tainted  (3.0.0-01263-g16c45e2 #6)
PC is at sevdev_probe+0x1c0/0x200 [sevdev]
LR is at kobj_map+0xf4/0x104
pc : [<bf00120c>]    lr : [<c01b1400>]    psr: 60000013
sp : d78c1e00  ip : 00000001  fp : 00000000
r10: 00000001  r9 : bf001908  r8 : d7a34c34
r7 : bf001e78  r6 : 00000000  r5 : bf0019b8  r4 : d7a34c00
r3 : 00000000  r2 : 00000000  r1 : 72800000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 18c5387d  Table: 1680c04a  DAC: 00000015
Process modprobe (pid: 465, stack limit = 0xd78c02f0)
Stack: (0xd78c1e00 to 0xd78c2000)
1e00: bf0019f4 bf0019c0 bf0019c0 bf0019f4 bf001c6c bf001c6c 00000002 00000150
1e20: 00000150 c01b099c c01b0988 c01afae8 00000000 bf0019c0 bf0019f4 bf001c6c
1e40: 00000000 c01afc04 bf001c6c c01afba4 00000000 c01aed8c d784b5c0 d79d7758
1e60: bf001c6c d79d7120 c03e1cd8 c01af404 bf001580 bf001582 00000000 bf001c6c
1e80: 00000002 bf0019b8 bf001b08 00000002 00000150 c01b00e0 bf001e78 00000002
1ea0: bf0019b8 bf001b08 00000002 00000150 00000150 bf000ebc bf001580 bf001e78
1ec0: 00000005 0fc00000 bf001d38 bf001d80 00000001 bf000ca8 00000000 00000026
1ee0: 000005f0 c002c650 bf000ca8 00000000 00000001 bf001d38 bf001d38 bf001d80
1f00: 00000001 d7886c20 00000001 c0077ac0 bf001d44 00000000 c02d3064 000e070d
1f20: 000011bf d886c000 0000491f d886ea84 d886e8ff d8870384 d7a34c00 000020a0
1f40: 00002210 00000000 00000000 00000024 00000025 00000019 0000001d 00000014
1f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c0397a9c
1f80: d782e060 000fa0ca 00000000 00000000 00000080 c0031a84 d78c0000 00000000
1fa0: 000f2040 c0031900 000fa0ca 00000000 001060e8 0000491f 000e070d 00000000
1fc0: 000fa0ca 00000000 00000000 00000080 000fa0ca 000fa0d8 00000000 000f2040
1fe0: becbff70 becbf974 0002c420 402a6b54 60000010 001060e8 00000000 00000000
[<bf00120c>] (sevdev_probe+0x1c0/0x200 [sevdev]) from [<c01b099c>] (platform_drv
_probe+0x14/0x18)
[<c01b099c>] (platform_drv_probe+0x14/0x18) from [<c01afae8>] (driver_probe_devi
ce+0xc8/0x184)
[<c01afae8>] (driver_probe_device+0xc8/0x184) from [<c01afc04>] (__driver_attach
+0x60/0x84)
[<c01afc04>] (__driver_attach+0x60/0x84) from [<c01aed8c>] (bus_for_each_dev+0x4
8/0x74)
[<c01aed8c>] (bus_for_each_dev+0x48/0x74) from [<c01af404>] (bus_add_driver+0x98
/0x214)
[<c01af404>] (bus_add_driver+0x98/0x214) from [<c01b00e0>] (driver_register+0xa0
/0x124)
[<c01b00e0>] (driver_register+0xa0/0x124) from [<bf000ebc>] (sevdev_init+0x214/0
x244 [sevdev])
[<bf000ebc>] (sevdev_init+0x214/0x244 [sevdev]) from [<c002c650>] (do_one_initca
ll+0x94/0x164)
[<c002c650>] (do_one_initcall+0x94/0x164) from [<c0077ac0>] (sys_init_module+0x1
688/0x1850)
[<c0077ac0>] (sys_init_module+0x1688/0x1850) from [<c0031900>] (ret_fast_syscall
+0x0/0x30)
Code: eb46ade7 e3e00012 ea00000c e5941018 (e591e000)
---[ end trace e9d9a2adbd64c591 ]---
Segmentation fault

Expert Contributor
linnj
Posts: 1,038
Registered: ‎09-10-2008
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

The kernel is not doing anything by default to map logic into the PL. It is up to the user to add a driver specific to the PL design which coudl be done with a kernel module.

There has to be a mapping added to the MMU to go from that physical address to a virtual address (ioremap call). There are examples on how to get access via userspace using mmap also which is more of a prototype solution.

You can see http://wiki.xilinx.com/osl-user-mode-pseudo-driver which is the principal I'm referring to. You can also use devmem from the console to read/write the addresses, or use it from a bash script to peek and poke.

Thanks.
John Linn
Regular Visitor
pullanlu
Posts: 25
Registered: ‎04-21-2012
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

John,

 

I was trying to access the PL logic from a kernel module.

Do I have to map physical address to virtual address for kernel module too?

For example, can I access device registers in a kernel module as below:

/* Device's physical address */

#define XPAR_APB_LOGIC_BASEADDR 0x72800000
#define XPAR_APB_LOGIC_HIGHADDR 0x7287FFFF

 

uint32_t* regAddr = (uint32_t*)XPAR_APB_LOGIC_BASEADDR;

volatile uint32_t regData;

regData = (volatile uint32_t) *regAddr;

 

Thanks

 

Pullan

 

Expert Contributor
linnj
Posts: 1,038
Registered: ‎09-10-2008
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

No you can't do that in Linux. Sorry.
John Linn
Visitor
bdyke
Posts: 7
Registered: ‎08-12-2008
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

Hi Pullan,

I can't tell exactly what you are doing of course but as a helpful suggestion you may be able to write what is called a user space driver using he Linux mmap command to get what you need.  I've done this for several simple periperals and it works well.  A good reference is "Linux Device Drivers" by Alessandro Rubini and Jonathan Corbet.  I believe this is available as a free download on the web.  There are some limitations to what one can do with a user space driver but hopefully this helps you.

-Bob

Super Contributor
norman_wong
Posts: 143
Registered: ‎05-28-2012
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

The usual embedded Linux way is to use the "/dev/mem" to mmap() physical memory to user space virtual memory. This sort of thing is very dangerous on a PC but has become common practice on embedded platforms. Example source code is out there on the internet. Search for devmem2.c.

 

Regular Visitor
pullanlu
Posts: 25
Registered: ‎04-21-2012
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

Dear Bob and Norman,

 

Thanks for the tips. I got it working in my kernel driver. As John said, I need to call ioremap() to map device's physical address into kernel space.

 

Pullan

Visitor
adutta78
Posts: 8
Registered: ‎03-05-2008
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

Hi,

A follow-up question on this topic. The example pseudo driver is given for GPIO. Will the same approach work if I have a custom IP connected using the AXI interconnect. How do I know what are the offsets, if any for the control signals (like the GPIO_DIRECTION_OFFSET value in the example driver) for the AXI interconnect? Wasn't quite clear to me how the value of GPIO_DIRECTION_OFFSET was derived. Is it documented somewhere?
Regular Visitor
nbedbury
Posts: 38
Registered: ‎07-31-2012
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

Offsets are described in the documentation for the IP core you are using.  For the GPIO example, the AXI GPIO core has the DATA register at offset 0x0 and 3-STATE register (or DIRECTION register) at offset 0x4 for channel 1. 

 

For a custom core, you define the number of AXI-accessible registers and what each one does.  If you only need to read and write single samples to registers, then this pseudo driver approach will work with custom PL.  Generally, a full fledged driver is needed to support interrupts and more complex operations.

Regular Contributor
balister
Posts: 68
Registered: ‎05-07-2012
0

Re: ZC702: How to access custom PL logic from Linux Kernel Module

Just as a note, look up the devm_ioremap version of the call. It is better for new work.