UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Scholar vanmierlo
Scholar
10,531 Views
Registered: ‎06-10-2008

Zynq Bus Error on mmap'ed io

Hi,

 

I'm trying to access a BRAM connected to the Zynq PS in linux using the  Linux User Mode Pseudo Driver but I always get:

Memory Unhandled fault: external abort on non-linefetch (0x018) at 0xb6f8dffc
Bus error

 

I have no idea what I'm doing wrong. Even when I use devmem to read a word I get this.

 

I've searched and found several others with similar problems but no solutions whatsoever.

 

Maarten

0 Kudos
11 Replies
Xilinx Employee
Xilinx Employee
10,528 Views
Registered: ‎08-02-2007

Re: Zynq Bus Error on mmap'ed io

Hi,

 

Can you confirm if you are trying to implement a Stream FIFO to pass data into PS, if yes,

 

Ensure that the FIFO is not empty by reading 0x1C first.  0x1C will be 1'b1 if the FIFO is receiving data.  

 
If the FIFO is empty, the devmem utility will generate a fault because there is no data to be received.
 
--HS
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------
0 Kudos
Highlighted
Scholar vanmierlo
Scholar
10,522 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

Hello HS,

 

I'm not implementing a Stream FIFO. I just added a BRAM-controller with one port which is connected to PORTA of a BRAM. PORTB of this BRAM is connected to PL.

 

It does not matter whether I read or write the Memory Mapped block. So even if I had a Stream FIFO I would expect it to fail when reading 0x1C.

 

I've first created a bare-metal application and that works as expected. But with linux I get the Bus Error.

 

Maarten

0 Kudos
Scholar norman_wong
Scholar
10,501 Views
Registered: ‎05-28-2012

Re: Zynq Bus Error on mmap'ed io

When is the PL loaded? If it's on boot, you can try accessing BRAM from the u-boot prompt. In your linux code, did you take care with the mmap and page boundaries?

0 Kudos
Scholar vanmierlo
Scholar
10,491 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

The PL is loaded by U-boot (over TFTP). So I can test from U-boot. But since my bare-metal application worked I expected U-boot to work as well. However, it doesn't. It resets the system.

 

U-Boot 2013.04-01183-gf12f87e-dirty (Jun 05 2013 - 14:20:22)

DRAM:  512 MiB
WARNING: Caches not enabled
MMC:   zynq_sdhci: 0
SF: Detected S25FL256S_64K with page size 64 KiB, total 32 MiB
In:    serial
Out:   serial
Err:   serial
Net:   Gem.e000b000
Hit any key to stop autoboot:  0
zynq-uboot> run tftp_bit
Loading bitstream from TFTP to PL...
Xilinx Device
Descriptor @ 0x1ffbc968
Family:         Zynq PL
Interface type: Device configuration interface (Zynq)
Device Size:    4045564 bytes
Cookie:         0x20 (32)
Device name:    7z020
No Device Function Table.
Gem.e000b000 Waiting for PHY auto negotiation to complete...... done
Using Gem.e000b000 device
TFTP from server 192.168.37.142; our IP address is 192.168.37.234
Filename 'system.bit'.
Load address: 0x1000000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         ################
         581.1 KiB/s
done
Bytes transferred = 4045667 (3dbb63 hex)
  design filename = "system_stub_routed.ncd;UserID=0xFFFFFFFF"
  part number = "7z020clg484"
  date = "2013/06/12"
  time = "13:40:57"
  bytes in bitstream = 4045564
zynq_load: Align buffer at 1000067 to 1000064(swap 1)
zynq-uboot> base 0x40000000
Base Address: 0x40000000
zynq-uboot> md.l 0 4
40000000:data abort

    MAYBE you should read doc/README.arm-unaligned-accesses

pc : [<1ff96638>]          lr : [<1ff96620>]
sp : 1fb55d80  ip : 1ffa7ff5     fp : 40000000
r10: 40000000  r9 : 00000004     r8 : 1fb55f40
r7 : 00000004  r6 : 00000000     r5 : 00000004  r4 : 00000004
r3 : 1fb55d94  r2 : 1ffa46c4     r1 : 00000802  r0 : 00000009
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

resetting ...

 

 

The main difference is that the bare-metal app uses

    Status = BramInit(BRAM_DEVICE_ID);

at the start. This function comes from xbram.[ch] in the generated BSP. So now I assume I need something similar in linux and u-boot. Can anyone help?

 

Maarten

0 Kudos
Scholar vanmierlo
Scholar
10,489 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

And this is the embedded linux application:

 

#define BRAM_BASE_ADDRESS     0x40000000

#define MAP_SIZE             0x1000
#define MAP_MASK             (MAP_SIZE - 1)

int main()
{
	int memfd;
	void *mapped_base, *mapped_dev_base;
	off_t dev_base = BRAM_BASE_ADDRESS;

	printf("Test application to send data to the JA connector.\n");

	memfd = open("/dev/mem", O_RDWR | O_SYNC);
	if (memfd == -1)
	{
		printf("Can't open /dev/mem.\n");
		exit(0);
	}
	printf("/dev/mem opened.\n");

	// Map one page of memory into user space such that the device is in that page,
	// but it may no be at the start of the page

	size_t len = getpagesize();
	mapped_base = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, dev_base & ~MAP_MASK);
	if (mapped_base == (void *) -1)
	{
		printf("Can't map the memory to user space.\n");
		exit(0);
	}
 	printf("Memory mapped at address %p.\n", mapped_base);

	// get the address of the device in user space which will be an offset from the base
	// that was mapped as memory is mapped at the start of a page

	mapped_dev_base = mapped_base + (dev_base & MAP_MASK);

	// clear the bram
	uint32_t* pBram = (uint32_t*)mapped_dev_base;
	uint32_t* pLen = &pBram[BRAM_LEN_OFFSET];
	memset(pBram, 0, MAP_SIZE);

	// unmap the memory before exiting

	if (munmap(mapped_base, MAP_SIZE) == -1)
	{
		printf("Can't unmap memory from user space.\n");
		exit(0);
	}

	close(memfd);
	return 0;
}

 It doesn't really matter if I replace memset with any other read or write instruction.

 

Maarten

0 Kudos
Scholar norman_wong
Scholar
10,475 Views
Registered: ‎05-28-2012

Re: Zynq Bus Error on mmap'ed io

I've had similar problems with the u-boot side. I had to modify the translation_table.s file in the FSBL. That table sets up the default MMU access to all memory. Even though u-boot does not use the MMU, that table still takes effect for some reason.

 

I haven't worked with the zc702 for a few years now. All this might have changed. I don't remember xbram.c/.h code. Maybe you might to merge that into the FSBL. Perhaps u-boot does low-level init now. If so, you can try to setup the table in u-boot. Never done it though. Can't say where to look.

 

As for the linux side, that's mystery. The kernel code will modify the MMU translation table when you mmap it. Something different there. Just one comment about your code. if you are using "size_t len = getpagesize();" then technically MAP_SIZE should be the same as len. Change MAP_SIZE and MAP_MASK to a variables. No need for hard-coded numbers.

0 Kudos
Scholar vanmierlo
Scholar
10,469 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

I don't need access from u-boot so I'm not going to modify that. I only tried it because you asked me to.

 

I assumed mmap needed the native pagesize and MAP_SIZE should equal my BRAM size. But for the moment that is not important as both are 4096.

 

I'm still very much stuck.

0 Kudos
Scholar vanmierlo
Scholar
10,452 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

For completeness, here's my Block Design. If someone sees something wrong or missing here, please tell me.

 

Zynq_Bram.png

 

Maarten

0 Kudos
Scholar vanmierlo
Scholar
10,446 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

Ok, I finally found it. It seems it is not allowed to use two different clocks on both sides of the BRAM. Now I changed them both to use FCLK_CLK0 and it finally works!

 

Maarten

0 Kudos
Scholar norman_wong
Scholar
4,303 Views
Registered: ‎05-28-2012

Re: Zynq Bus Error on mmap'ed io

Great news. Good to know. Maybe you've found the root cause of many of the access violation problems out there. Some code in your bare metal example must have been aligning the frequencies.

0 Kudos
Scholar vanmierlo
Scholar
4,298 Views
Registered: ‎06-10-2008

Re: Zynq Bus Error on mmap'ed io

I doubt it aligned frequencies, but it may have ignored exceptions by default.

0 Kudos