XilinxProcessorIPLib/drivers/aiengine/examples/aie_sim_test/ext/top/xaiesim_elfload.c
uint32 XAieSim_LoadElfMem(XAieSim_Tile *TileInstPtr, uint8 *ElfPtr,
		uint8 LoadSym)
{
	Elf32_Ehdr *ElfHdr = ElfPtr;
	Elf32_Shdr *SectHdr;

	uint8 Count = 0U;
	uint8 ShNameIdx = 0U;

	uint32 Idx;
	uint8 *DataPtr;
	uint32 DmbOff;
	uint32 SectAddr;
	uint32 RemSize;
	uint32 DoneSize;
	uint64_t DmbAddr;
	uint64_t TgtTileAddr;

	XAieSim_print("**** ELF HEADER ****\n");
	XAieSim_print("e_type\t\t : %08x\ne_machine\t : %08x\ne_version\t : "
			"%08x\ne_entry\t\t : %08x\ne_phoff\t\t : %08x\n",
			ElfHdr->e_type, ElfHdr->e_machine, ElfHdr->e_version,
			ElfHdr->e_entry, ElfHdr->e_phoff);
	XAieSim_print("e_shoff\t\t : ""%08x\ne_flags\t\t : %08x\ne_ehsize\t"
			" : %08x\ne_phentsize\t : %08x\ne_phnum\t\t : %08x\n"
			"e_shentsize\t : %08x\ne_shnum\t\t : %08x\ne_shstrndx\t : "
			"%08x\n\n", ElfHdr->e_shoff, ElfHdr->e_flags,
			ElfHdr->e_ehsize, ElfHdr->e_phentsize, ElfHdr->e_phnum,
			ElfHdr->e_shentsize, ElfHdr->e_shnum, ElfHdr->e_shstrndx);

	SectHdr = ElfPtr + ElfHdr->e_shoff;

	/*
	 * Get the section names from the .shstrtab section. First find the
	 * index of this section among the section header entries
	 */
	while(Count < ElfHdr->e_shnum) {
		if(SectHdr[Count].sh_type == SHT_STRTAB) {
			ShNameIdx = Count;
			break;
		}
		Count++;
	}

	/* Now point to the .shstrtab section in the ELF file */
	DataPtr = ElfPtr + SectHdr[ShNameIdx].sh_offset;

	XAieSim_print("**** SECTION HEADERS ****\n");
	XAieSim_print("Idx\tsh_name\t\tsh_type\t\tsh_flags\tsh_addr\t\tsh_offset"
			"\tsh_size\t\tsh_link\t\tsh_addralign\tsection_name\n");
	Count = 0U;
	while(Count < ElfHdr->e_shnum) {
		XAieSim_print("%d\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t"
				"%08x\t%s\n", Count, SectHdr[Count].sh_name,
				SectHdr[Count].sh_type, SectHdr[Count].sh_flags,
				SectHdr[Count].sh_addr, SectHdr[Count].sh_offset,
				SectHdr[Count].sh_size, SectHdr[Count].sh_link,
				SectHdr[Count].sh_addralign,
				DataPtr + SectHdr[Count].sh_name);
		Count++;
	}

	Count = 0U;
	while(Count < ElfHdr->e_shnum) {
		/* Copy the program data sections to memory */
		if(SectHdr[Count].sh_type == SHT_PROGBITS &&
				SectHdr[Count].sh_flags) {

			XAieSim_WriteSectionMem(TileInstPtr,
					DataPtr + SectHdr[Count].sh_name,
					&SectHdr[Count],
					ElfPtr + SectHdr[Count].sh_offset);
		}

		/* Zero out the bss sections */
		if(SectHdr[Count].sh_type == SHT_NOBITS &&
				SectHdr[Count].sh_addr > 0x1FFFFU) {

			XAieSim_print("Zeroing out the %s sections\n",
					DataPtr + SectHdr[Count].sh_name);

			TgtTileAddr = XAieSim_GetTargetTileAddr(TileInstPtr,
					SectHdr[Count].sh_addr);
			SectAddr = SectHdr[Count].sh_addr;
			/*
			 * Use the section header size. The AIE compiler uses
			 * the section header for load size.
			 */
			RemSize = SectHdr[Count].sh_size;
			DoneSize = 0U;

			/* Use 32 bit loads to match sim output */
			for(Idx = 0U; Idx < RemSize; Idx += 4U){
				/* Mask address as per the Data memory offset*/
				DmbOff = (SectAddr &
						XAIESIM_ELF_TILEADDR_DMB_MASK) + Idx;

				if(DmbOff & 0x8000U) {
					/*
					 * 32 KB boundary cross. Data section
					 * moving to the memory bank of next
					 * cardinal direction. Change the target
					 * tile address
					 */
					SectHdr[Count].sh_addr += 0x8000U;
					TgtTileAddr =
						XAieSim_GetTargetTileAddr(TileInstPtr,
								(SectHdr[Count].sh_addr &
								 0x1FFFFU));
					SectAddr = 0x0U;
					Idx = 0U;
					DmbOff = 0U;
					RemSize -= DoneSize;
					DoneSize = 0U;
				}

				DmbAddr = TgtTileAddr +
					XAIESIM_ELF_TILECORE_DATMEM + DmbOff;
				XAieGbl_Write32(DmbAddr, 0U);
				DoneSize += 4U;
			}
		}
		Count++;
	}

	return XAIESIM_SUCCESS;
}
/*****************************************************************************/
/**
*
* This is the API to load the specified ELF to the target AIE Tile program
* memory followed by clearing of the BSS sections.
*
* @param	TileInstPtr - Pointer to the Tile instance structure.
* @param	ElfPtr: Path to the ELF memory
*
* @return	XAIESIM_SUCCESS on success, else XAIESIM_FAILURE.
*
* @note		None.
*
*******************************************************************************/
This is the API to load the specified ELF to the target AIE Tile program
memory followed by clearing of the BSS sections.
This is the API to load the specified ELF to the target AIE Tile program memory followed by clearing of the BSS sections .
uint32 XAieSim_LoadElfMem(XAieSim_Tile *TileInstPtr, uint8 *ElfPtr,
		uint8 LoadSym)
{
	Elf32_Ehdr *ElfHdr = ElfPtr;
	Elf32_Shdr *SectHdr;
	uint8 Count = 0U;
	uint8 ShNameIdx = 0U;
	uint32 Idx;
	uint8 *DataPtr;
	uint32 DmbOff;
	uint32 SectAddr;
	uint32 RemSize;
	uint32 DoneSize;
	uint64_t DmbAddr;
	uint64_t TgtTileAddr;
	XAieSim_print("**** ELF HEADER ****\n");
	XAieSim_print("e_type\t\t : %08x\ne_machine\t : %08x\ne_version\t : "
			"%08x\ne_entry\t\t : %08x\ne_phoff\t\t : %08x\n",
			ElfHdr->e_type, ElfHdr->e_machine, ElfHdr->e_version,
			ElfHdr->e_entry, ElfHdr->e_phoff);
	XAieSim_print("e_shoff\t\t : ""%08x\ne_flags\t\t : %08x\ne_ehsize\t"
			" : %08x\ne_phentsize\t : %08x\ne_phnum\t\t : %08x\n"
			"e_shentsize\t : %08x\ne_shnum\t\t : %08x\ne_shstrndx\t : "
			"%08x\n\n", ElfHdr->e_shoff, ElfHdr->e_flags,
			ElfHdr->e_ehsize, ElfHdr->e_phentsize, ElfHdr->e_phnum,
			ElfHdr->e_shentsize, ElfHdr->e_shnum, ElfHdr->e_shstrndx);
	SectHdr = ElfPtr + ElfHdr->e_shoff;
	while(Count < ElfHdr->e_shnum) {
		if(SectHdr[Count].sh_type == SHT_STRTAB) {
			ShNameIdx = Count;
			break;
		}
		Count++;
	}
	DataPtr = ElfPtr + SectHdr[ShNameIdx].sh_offset;
	XAieSim_print("**** SECTION HEADERS ****\n");
	XAieSim_print("Idx\tsh_name\t\tsh_type\t\tsh_flags\tsh_addr\t\tsh_offset"
			"\tsh_size\t\tsh_link\t\tsh_addralign\tsection_name\n");
	Count = 0U;
	while(Count < ElfHdr->e_shnum) {
		XAieSim_print("%d\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t"
				"%08x\t%s\n", Count, SectHdr[Count].sh_name,
				SectHdr[Count].sh_type, SectHdr[Count].sh_flags,
				SectHdr[Count].sh_addr, SectHdr[Count].sh_offset,
				SectHdr[Count].sh_size, SectHdr[Count].sh_link,
				SectHdr[Count].sh_addralign,
				DataPtr + SectHdr[Count].sh_name);
		Count++;
	}
	Count = 0U;
	while(Count < ElfHdr->e_shnum) {
		if(SectHdr[Count].sh_type == SHT_PROGBITS &&
				SectHdr[Count].sh_flags) {
			XAieSim_WriteSectionMem(TileInstPtr,
					DataPtr + SectHdr[Count].sh_name,
					&SectHdr[Count],
					ElfPtr + SectHdr[Count].sh_offset);
		}
		if(SectHdr[Count].sh_type == SHT_NOBITS &&
				SectHdr[Count].sh_addr > 0x1FFFFU) {
			XAieSim_print("Zeroing out the %s sections\n",
					DataPtr + SectHdr[Count].sh_name);
			TgtTileAddr = XAieSim_GetTargetTileAddr(TileInstPtr,
					SectHdr[Count].sh_addr);
			SectAddr = SectHdr[Count].sh_addr;
			RemSize = SectHdr[Count].sh_size;
			DoneSize = 0U;
			for(Idx = 0U; Idx < RemSize; Idx += 4U){
				DmbOff = (SectAddr &
						XAIESIM_ELF_TILEADDR_DMB_MASK) + Idx;
				if(DmbOff & 0x8000U) {
					SectHdr[Count].sh_addr += 0x8000U;
					TgtTileAddr =
						XAieSim_GetTargetTileAddr(TileInstPtr,
								(SectHdr[Count].sh_addr &
								 0x1FFFFU));
					SectAddr = 0x0U;
					Idx = 0U;
					DmbOff = 0U;
					RemSize -= DoneSize;
					DoneSize = 0U;
				}
				DmbAddr = TgtTileAddr +
					XAIESIM_ELF_TILECORE_DATMEM + DmbOff;
				XAieGbl_Write32(DmbAddr, 0U);
				DoneSize += 4U;
			}
		}
		Count++;
	}
	return XAIESIM_SUCCESS;
}
uint32 XAieSim_LoadElfMem ( XAieSim_Tile * TileInstPtr , uint8 * ElfPtr , uint8 LoadSym ) { Elf32_Ehdr * ElfHdr = ElfPtr ; Elf32_Shdr * SectHdr ; uint8 Count = 0U ; uint8 ShNameIdx = 0U ; uint32 Idx ; uint8 * DataPtr ; uint32 DmbOff ; uint32 SectAddr ; uint32 RemSize ; uint32 DoneSize ; uint64_t DmbAddr ; uint64_t TgtTileAddr ; XAieSim_print ( " \n " ) ; XAieSim_print ( " \t \t \n \t \n \t " " \n \t \t \n \t \t \n " , ElfHdr -> e_type , ElfHdr -> e_machine , ElfHdr -> e_version , ElfHdr -> e_entry , ElfHdr -> e_phoff ) ; XAieSim_print ( " \t \t " " \n \t \t \n \t " " \n \t \n \t \t \n " " \t \n \t \t \n \t " " \n \n " , ElfHdr -> e_shoff , ElfHdr -> e_flags , ElfHdr -> e_ehsize , ElfHdr -> e_phentsize , ElfHdr -> e_phnum , ElfHdr -> e_shentsize , ElfHdr -> e_shnum , ElfHdr -> e_shstrndx ) ; SectHdr = ElfPtr + ElfHdr -> e_shoff ; while ( Count < ElfHdr -> e_shnum ) { if ( SectHdr [ Count ] . sh_type == SHT_STRTAB ) { ShNameIdx = Count ; break ; } Count ++ ; } DataPtr = ElfPtr + SectHdr [ ShNameIdx ] . sh_offset ; XAieSim_print ( " \n " ) ; XAieSim_print ( " \t \t \t \t \t \t \t \t " " \t \t \t \t \t \t \n " ) ; Count = 0U ; while ( Count < ElfHdr -> e_shnum ) { XAieSim_print ( " \t \t \t \t \t \t \t \t " " \t \n " , Count , SectHdr [ Count ] . sh_name , SectHdr [ Count ] . sh_type , SectHdr [ Count ] . sh_flags , SectHdr [ Count ] . sh_addr , SectHdr [ Count ] . sh_offset , SectHdr [ Count ] . sh_size , SectHdr [ Count ] . sh_link , SectHdr [ Count ] . sh_addralign , DataPtr + SectHdr [ Count ] . sh_name ) ; Count ++ ; } Count = 0U ; while ( Count < ElfHdr -> e_shnum ) { if ( SectHdr [ Count ] . sh_type == SHT_PROGBITS && SectHdr [ Count ] . sh_flags ) { XAieSim_WriteSectionMem ( TileInstPtr , DataPtr + SectHdr [ Count ] . sh_name , & SectHdr [ Count ] , ElfPtr + SectHdr [ Count ] . sh_offset ) ; } if ( SectHdr [ Count ] . sh_type == SHT_NOBITS && SectHdr [ Count ] . sh_addr > 0x1FFFFU ) { XAieSim_print ( " \n " , DataPtr + SectHdr [ Count ] . sh_name ) ; TgtTileAddr = XAieSim_GetTargetTileAddr ( TileInstPtr , SectHdr [ Count ] . sh_addr ) ; SectAddr = SectHdr [ Count ] . sh_addr ; RemSize = SectHdr [ Count ] . sh_size ; DoneSize = 0U ; for ( Idx = 0U ; Idx < RemSize ; Idx += 4U ) { DmbOff = ( SectAddr & XAIESIM_ELF_TILEADDR_DMB_MASK ) + Idx ; if ( DmbOff & 0x8000U ) { SectHdr [ Count ] . sh_addr += 0x8000U ; TgtTileAddr = XAieSim_GetTargetTileAddr ( TileInstPtr , ( SectHdr [ Count ] . sh_addr & 0x1FFFFU ) ) ; SectAddr = 0x0U ; Idx = 0U ; DmbOff = 0U ; RemSize -= DoneSize ; DoneSize = 0U ; } DmbAddr = TgtTileAddr + XAIESIM_ELF_TILECORE_DATMEM + DmbOff ; XAieGbl_Write32 ( DmbAddr , 0U ) ; DoneSize += 4U ; } } Count ++ ; } return XAIESIM_SUCCESS ; }
This is the API to load the specified ELF to the target AIE Tile program
memory followed by clearing of the BSS sections.
This is the API to load the specified ELF to the target AIE Tile program memory followed by clearing of the BSS sections .
/*
	 * Get the section names from the .shstrtab section. First find the
	 * index of this section among the section header entries
	 */ /* Now point to the .shstrtab section in the ELF file */ /* Copy the program data sections to memory */ /* Zero out the bss sections */ /*
			 * Use the section header size. The AIE compiler uses
			 * the section header for load size.
			 */ /* Use 32 bit loads to match sim output */ /* Mask address as per the Data memory offset*/ /*
					 * 32 KB boundary cross. Data section
					 * moving to the memory bank of next
					 * cardinal direction. Change the target
					 * tile address
					 */