/dev/mem access, failed

Env: Jetson TX1 R24.2

I try to use /dev/mem to mmap (128k size), but some point of it goes wrong.
I can successful read offset 0x10, 0x5B50,
but get “Bus error” when i read offset 0x5B5C. (btw, yeah this is a eeprom tool for intel NIC)

can you give me some hint about how to get this access action works?

hello reifan,

there’s several reasons caused the “Bus error”, generally it would be you’re accessing the memory which hardware cannot physically address.
may i know more details about why you would like to check 0x5B5C?
thanks

hi Jerry,

i got eeprom tool from intel, try to use it to access their NIC on TX1.
By intel’s design, they mmap a 128k space with /dev/mem, then read/write it to control it.

i can see this tool could read from 0x10, 0x5B50 for their control step,
Then 0x5B5C, its for “Sync register for SW and FW” will failed.

I try another setting: mmap a 8k space, not 128k.

Then 0x5B5C could be read successfully.
This tool goes further but still got “Bus error” at another action, which is writing value to offset 0x14.

Hi reifan,

Is the issue specific to the intel NIC?

Hi vicky,

i’m not sure about that.

I’m confuse with why i failed at 0x5B5C this point with 128k length, but no error when i changed to 8k length.

code:
WordLocation = (off_t)( Dev->MemoryAddress); //Dev->MemoryAddress is 0x13000000, because that is pci device.
WordLocation &= ~(sysconf(_SC_PAGESIZE) - 1);

Mapped1Address = mmap(NULL, 4096*32, PROT_WRITE | PROT_READ, MAP_SHARED, FileDescriptor, (off_t)WordLocation);

Hi Jerry and Vicky,

here is a sample code, i run it on my Jetson TX1 (R24.2.1) to read value from pci device.
On my platform, 0x13000000 is pci device base address as default.
i try to read value from [Offset].
When [Offset] is:
0x1044: “Bus error”
0x1048: no error
0x5b50: no error
0x5b54: “Bus error”
0x5b5c: “Bus error”

i have try RTL8821 wifi nic and intel i210 nic, both has this issue.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

//PCI bus base address
#define MY_BASE_ADDR 0x13000000

//Try to read value from here
#define Offset	0x5b50

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main ()
{
	int	memfd;
	void *mapped_base, *mapped_offset_addr;
	off_t dev_base = MY_BASE_ADDR;
	unsigned long readback = 0;

	dev_base &= ~(sysconf(_SC_PAGESIZE) - 1);

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

	mapped_base = mmap( NULL, 4096*32, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, (off_t)dev_base);

	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);

	mapped_offset_addr = mapped_base + Offset;
	readback = *((volatile unsigned long *) (mapped_offset_addr));
	printf("The Value of 0x%x was %016lx\n", Offset, readback);

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

	close(memfd);
	return 0;
}

Please take a look at mmap manual (http://man7.org/linux/man-pages/man2/mmap.2.html) and the example inside to see if help.

I have no experience with your hardware, but I am curious if the error occurs upon mmap, or if instead the error occurs during read or write of the mmap space? I’m suspicious of whether the is a little endian conversion issue or some byte address alignment requirement.

Thanks for everyone’s suggestion, i solved this issue.

The intel eeprom tool define u32 as “unsigned long”, and when it try to read regs, it use “u32” thus data should be 32bits, datasheet saied.
But “unsigned long” is 64bits.

When i use the sample code, i did the similiar thing, so the same issue occurs.

Just use the correct type to access mem, it won’t be “Bus error”