/* Transfer the section to the L1 memory */
int
module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
			  char *secstrings, struct module *mod)
{
	/*
	 * XXX: sechdrs are vmalloced in kernel/module.c
	 * and would be vfreed just after module is loaded,
	 * so we hack to keep the only information we needed
	 * in mod->arch to correctly free L1 I/D sram later.
	 * NOTE: this breaks the semantic of mod->arch structure.
	 */
	Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
	void *dest;

	for (s = sechdrs; s < sechdrs_end; ++s) {
		const char *shname = secstrings + s->sh_name;

		if (s->sh_size == 0)
			continue;

		if (!strcmp(".l1.text", shname) ||
		    (!strcmp(".text", shname) &&
		     (hdr->e_flags & EF_BFIN_CODE_IN_L1))) {

			dest = l1_inst_sram_alloc(s->sh_size);
			mod->arch.text_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 inst memory allocation failed\n");
				return -1;
			}
			dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l1.data", shname) ||
		           (!strcmp(".data", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {

			dest = l1_data_sram_alloc(s->sh_size);
			mod->arch.data_a_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l1.bss", shname) ||
		           (!strcmp(".bss", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {

			dest = l1_data_sram_zalloc(s->sh_size);
			mod->arch.bss_a_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}

		} else if (!strcmp(".l1.data.B", shname)) {

			dest = l1_data_B_sram_alloc(s->sh_size);
			mod->arch.data_b_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l1.bss.B", shname)) {

			dest = l1_data_B_sram_alloc(s->sh_size);
			mod->arch.bss_b_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}
			memset(dest, 0, s->sh_size);

		} else if (!strcmp(".l2.text", shname) ||
		           (!strcmp(".text", shname) &&
		            (hdr->e_flags & EF_BFIN_CODE_IN_L2))) {

			dest = l2_sram_alloc(s->sh_size);
			mod->arch.text_l2 = dest;
			if (dest == NULL) {
				pr_err("L2 SRAM allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l2.data", shname) ||
		           (!strcmp(".data", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {

			dest = l2_sram_alloc(s->sh_size);
			mod->arch.data_l2 = dest;
			if (dest == NULL) {
				pr_err("L2 SRAM allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l2.bss", shname) ||
		           (!strcmp(".bss", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {

			dest = l2_sram_zalloc(s->sh_size);
			mod->arch.bss_l2 = dest;
			if (dest == NULL) {
				pr_err("L2 SRAM allocation failed\n");
				return -1;
			}

		} else
			continue;

		s->sh_flags &= ~SHF_ALLOC;
		s->sh_addr = (unsigned long)dest;
	}

	return 0;
}
int
module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
			  char *secstrings, struct module *mod)
{
	/*
                                                 
                                                    
                                                     
                                                     
                                                          
  */
	Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
	void *dest;

	for (s = sechdrs; s < sechdrs_end; ++s) {
		const char *shname = secstrings + s->sh_name;

		if (s->sh_size == 0)
			continue;

		if (!strcmp(".l1.text", shname) ||
		    (!strcmp(".text", shname) &&
		     (hdr->e_flags & EF_BFIN_CODE_IN_L1))) {

			dest = l1_inst_sram_alloc(s->sh_size);
			mod->arch.text_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 inst memory allocation failed\n");
				return -1;
			}
			dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l1.data", shname) ||
		           (!strcmp(".data", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {

			dest = l1_data_sram_alloc(s->sh_size);
			mod->arch.data_a_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l1.bss", shname) ||
		           (!strcmp(".bss", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {

			dest = l1_data_sram_zalloc(s->sh_size);
			mod->arch.bss_a_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}

		} else if (!strcmp(".l1.data.B", shname)) {

			dest = l1_data_B_sram_alloc(s->sh_size);
			mod->arch.data_b_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l1.bss.B", shname)) {

			dest = l1_data_B_sram_alloc(s->sh_size);
			mod->arch.bss_b_l1 = dest;
			if (dest == NULL) {
				pr_err("L1 data memory allocation failed\n");
				return -1;
			}
			memset(dest, 0, s->sh_size);

		} else if (!strcmp(".l2.text", shname) ||
		           (!strcmp(".text", shname) &&
		            (hdr->e_flags & EF_BFIN_CODE_IN_L2))) {

			dest = l2_sram_alloc(s->sh_size);
			mod->arch.text_l2 = dest;
			if (dest == NULL) {
				pr_err("L2 SRAM allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l2.data", shname) ||
		           (!strcmp(".data", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {

			dest = l2_sram_alloc(s->sh_size);
			mod->arch.data_l2 = dest;
			if (dest == NULL) {
				pr_err("L2 SRAM allocation failed\n");
				return -1;
			}
			memcpy(dest, (void *)s->sh_addr, s->sh_size);

		} else if (!strcmp(".l2.bss", shname) ||
		           (!strcmp(".bss", shname) &&
		            (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {

			dest = l2_sram_zalloc(s->sh_size);
			mod->arch.bss_l2 = dest;
			if (dest == NULL) {
				pr_err("L2 SRAM allocation failed\n");
				return -1;
			}

		} else
			continue;

		s->sh_flags &= ~SHF_ALLOC;
		s->sh_addr = (unsigned long)dest;
	}

	return 0;
}