This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GPMC-CS1 (GPMC-FPGA) access leds to "Precise External Abort on non-linefetch (0x1018) .." & "Bus Error ".

a/ We have XILINX FPGA connected to GPMC chip_select 1 and trying to do basic read / write in Asynchronous mode.
   

a/ We are getting the error of :-
    1/ "..Precise External Abort on non-linefetch (0x1018) at 0x4006c000.."

    2/ " ..Bus Error"

    We are using an sample code in which we are mapping the GPMC chip select area using mmap

    (this is from one of TI Google groups)
 

d/  w.r.t DM816x EVM , if you could let me know :-

    a/  At what address range of GPMC (chip select 1) we can map FPGA (8/16 bit asynchronous mode).

    b/  Since by NAND driver ( CS_0) already does the GPMC pin muxing , i am assuming no additional

        GPMC pin muxing for GPMC would be required.


e/ Please do share if you have any sample /scratch code tested for similar asynchronous mode of GPMC from Linux.

Below is the code 

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


#define GPMC_BASE 	0x50000000
#define REGLEN 		0x10000000
#define GPMC_REVISION   0x0
#define GPMC_CONFIG1_1  (0X50000090)
#define GPMC_CONFIG2_1  (0X50000094)
#define GPMC_CONFIG3_1  (0X50000098)
#define GPMC_CONFIG4_1  (0X5000009C)
#define GPMC_CONFIG5_1  (0X500000A0)
#define GPMC_CONFIG6_1  (0X500000A4)
#define GPMC_CONFIG7_1  (0X500000A8)

#define GPMC_CHIPSELECTCONFIGDISPLACEMENT (0x30 / 4)

#define GPMC_CONFIG1 (0x60 / 4)
#define GPMC_CONFIG2 (0x64 / 4)
#define GPMC_CONFIG3 (0x68 / 4)
#define GPMC_CONFIG4 (0x6c / 4)
#define GPMC_CONFIG5 (0x70 / 4)
#define GPMC_CONFIG6 (0x74 / 4)
#define GPMC_CONFIG7 (0x78 / 4)


static volatile uint32_t* registers  = NULL;
static volatile uint8_t*  extbus     = NULL;
static unsigned int       valid      = 0;
static int 	          devmemfd   = -1;
static unsigned int       size       = 0x100;
static unsigned int       revision_id = 0;

//map memory of length "len" at offset "offset"
static void* util_mapmemoryblock(off_t offset, size_t len)
{
	devmemfd = open("/dev/mem", O_RDWR | O_SYNC);
	void* registers = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, 
				devmemfd, offset);
	if (registers == MAP_FAILED) {
		printf("\n[GPMC]: Failed in getting Memory acess \n");
	}else{
		printf("\n[GPMC]: Sucess in getting Memory acess \n");
	}
	return registers;
}

static void util_unmapmemoryblock(void* block, size_t len)
{
	printf("\n[GPMC]: Releasing the amemory acess \n");
	munmap((void*) block, len);
	if (devmemfd != -1) {
		printf("\n[GPMC]: Closing the interface file \n");
		close(devmemfd);
	}
}


static void gpmc_mapregisters()
{
	registers = (uint32_t*) util_mapmemoryblock(GPMC_BASE, REGLEN);
}

static void gpmc_unmapregisters()
{
	util_unmapmemoryblock((void*) registers, REGLEN);

}

static void gpmc_setup(void)
{
	
	printf("\n[GPMC]: Getting Memory acess for GPMC configuration register \n");
	gpmc_mapregisters();

	if (registers != MAP_FAILED) {
		valid =1;		
		int chipselect = 1;
		int displacement = GPMC_CHIPSELECTCONFIGDISPLACEMENT * chipselect;

		printf("\n[GPMC]: Initial revision_id is %X \n",revision_id);
		revision_id = *(registers + GPMC_REVISION);
		printf("\n[GPMC]: Updated revision_id is %X \n",revision_id);


		printf("\n[GPMC]: Disable before playing with the registers \n");
		*(registers + displacement + GPMC_CONFIG7) = 0x00000000;


		printf("\n[GPMC]: No burst, async, 8-bit, non multiplexed \n");
		*(registers + displacement + GPMC_CONFIG1) = 0x00000000; 


		printf("\n[GPMC]: Assert CS on fclk 0, deassert CS on fclk 3 \n");
		*(registers + displacement + GPMC_CONFIG2) = 0x00000300; 


		printf("\n[GPMC]: Unused ADV/ALE \n");
		*(registers + displacement + GPMC_CONFIG3) = 0x00000000; 


		printf("\n[GPMC]: Assert OE on fclk 1, deassert OE on fclk 3 \n");
		*(registers + displacement + GPMC_CONFIG4) = 0x00000301; 


		printf("\n[GPMC]: Data valid on fclk 2, cycle time 3 fclks \n");
		*(registers + displacement + GPMC_CONFIG5) = 0x00020003; 


		printf("\n[GPMC]: No back to back cycle restrictions \n");
		*(registers + displacement + GPMC_CONFIG6) = 0x00000000; 


		printf("\n[GPMC]: CS1: Set base address 0x02000000, 16MB region, and enable CS \n");
		*(registers + displacement + GPMC_CONFIG7) = 0x00000f42;  


   		printf("\n[GPMC]: Releasing Memory acess for GPMC configuration register \n");
		gpmc_unmapregisters();
	}
}



void bus_init()
{
	// Configure the GPMC 
	gpmc_setup();
	
	if(valid == 1 ){
		//Configure the Chip Select for 256 Bytes
		printf("\n[GPMC]: Getting Memory acess for FPGA \n");
		extbus = (uint8_t*) util_mapmemoryblock(0x01000000, size);
	}else {
		printf("\n[GPMC]: Configuration access was invalid  \n");
	}
}

void bus_writebyte(uint8_t address, uint8_t data)
{
	*(unsigned char *)(extbus + address) = data;
}

uint32_t  bus_readbyte(uint8_t address)
{
	return *(unsigned char *)(extbus + address);
}

void bus_shutdown()
{
	printf("\n[GPMC]: Releasing Memory acess for FPGA  & doing shutdown\n");
	util_unmapmemoryblock((void*) extbus, size);
}


int main() 
{

	int i = 0;
	printf("\n[GPMC]: Calling the Init Function now _VER_2.1\n");
	bus_init();

	if (extbus == NULL){
		printf("\n[GPMC]: The FPGA memory is not yet mapped \n");
		goto exit_code;
	}else{
		printf("\n[GPMC]: The FPGA memory is mapped @ %p \n",extbus);
	}

	printf("\n[GPMC]: ===========================================\n\n");
	for (i; i < 10; i++) {
		printf("\n[GPMC]: Read byte at address %x: %X\n", i, bus_readbyte(i));
	}
	printf("\n[GPMC]: ===========================================\n\n");


	bus_shutdown();

	printf("\n[GPMC]: Code terminates \n");
	return(0);

exit_code : 
	printf("\n[GPMC]: Code terminates \n");
	return(0);
	
}



/* 
And the OUTPUT LOG is 
root@dm816x-evm:~#
root@dm816x-evm:~#
root@dm816x-evm:~# ./gpmc_test

[GPMC]: Calling the Init Function now _VER_2.1

[GPMC]: Getting Memory acess for GPMC configuration register

[GPMC]: Sucess in getting Memory acess

[GPMC]: Initial revision_id is 0

[GPMC]: Updated revision_id is 60

[GPMC]: Disable before playing with theUnhandled fault: Precise External Abort on non-linefetch (0x1018) at 0x4006c000
 registers

[GPMC]: No burst, async, 8-bit, non multiplexed

[GPMC]: Assert CS on fclk 0, deassert CS on fclk 3

[GPMC]: Unused ADV/ALE

[GPMC]: Assert OE on fclk 1, deassert OE on fclk 3

[GPMC]: Data valid on fclk 2, cycle time 3 fclks

[GPMC]: No back to back cycle restrictions

[GPMC]: CS1: Set base address 0x02000000, 16MB region, and enable CS

[GPMC]: Releasing Memory acess for GPMC configuration register

[GPMC]: Releasing the amemory acess

[GPMC]: Closing the interface file

[GPMC]: Getting Memory acess for FPGA

[GPMC]: Sucess in getting Memory acess

[GPMC]: The FPGA memory is mapped @ 0x4006c000

[GPMC]: ===========================================

Bus error
root@dm816x-evm:~#
root@dm816x-evm:~#
root@dm816x-evm:~#
root@dm816x-evm:~#
root@dm816x-evm:~#
*/ 

Thanks 

Ashish.

  • Ashish,

    Ashish Mishra1 said:

    a/ We are getting the error of :-
        1/ "..Precise External Abort on non-linefetch (0x1018) at 0x4006c000.."

        2/ " ..Bus Error"

    By some reason you are trying to access Reserved memory, see DM816x datasheet, section 3.10 Memory Map Summary

    GPMC memory mapped accessible memory is from 0x01000000 to 0x1FFFFFFF, while memory from 0x40000000 to 0x402FFFFF is reserved.

    If you are using EZSDK, please try with the latest linux kernel:

    Refer also to the below e2e thread:

    BR
    Pavel



     

  • Dear Pavel ,

    We have used the standard EZSDK for our custom board bring up using DVM816x as our reference. 

    The only pending is the GPMC , hence could you please let us know if the mentioned repositories could be used for DVM816x EVM .

    or

    If you help us with particular patch to address this .

    Thank You,

    Ashish Kumar Mishra  

  • Ashish Mishra1 said:
    could you please let us know if the mentioned repositories could be used for DVM816x EVM

    Yes, the master branch I provided you in my previous post can/should be used with DM816x EVM and DM816x custom board. Just build it with ti8168_evm_defconfig

    BR
    Pavel