aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/vpe.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/vpe.c')
-rw-r--r--arch/mips/kernel/vpe.c113
1 files changed, 52 insertions, 61 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 29933652ff4a..1765bab000a0 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -254,7 +254,7 @@ static void __maybe_unused dump_mtregs(void)
254 val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT); 254 val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
255} 255}
256 256
257/* Find some VPE program space */ 257/* Find some VPE program space */
258static void *alloc_progmem(unsigned long len) 258static void *alloc_progmem(unsigned long len)
259{ 259{
260 void *addr; 260 void *addr;
@@ -292,7 +292,7 @@ static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
292} 292}
293 293
294/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld 294/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
295 might -- code, read-only data, read-write data, small data. Tally 295 might -- code, read-only data, read-write data, small data. Tally
296 sizes, and place the offsets into sh_entsize fields: high bit means it 296 sizes, and place the offsets into sh_entsize fields: high bit means it
297 belongs in init. */ 297 belongs in init. */
298static void layout_sections(struct module *mod, const Elf_Ehdr * hdr, 298static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
@@ -386,7 +386,7 @@ static int apply_r_mips_pc16(struct module *me, uint32_t *location,
386 386
387 if( (rel > 32768) || (rel < -32768) ) { 387 if( (rel > 32768) || (rel < -32768) ) {
388 printk(KERN_DEBUG "VPE loader: " 388 printk(KERN_DEBUG "VPE loader: "
389 "apply_r_mips_pc16: relative address out of range 0x%x\n", rel); 389 "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
390 return -ENOEXEC; 390 return -ENOEXEC;
391 } 391 }
392 392
@@ -458,7 +458,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
458 Elf32_Addr val, vallo; 458 Elf32_Addr val, vallo;
459 struct mips_hi16 *l, *next; 459 struct mips_hi16 *l, *next;
460 460
461 /* Sign extend the addend we extract from the lo insn. */ 461 /* Sign extend the addend we extract from the lo insn. */
462 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; 462 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
463 463
464 if (mips_hi16_list != NULL) { 464 if (mips_hi16_list != NULL) {
@@ -470,7 +470,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
470 /* 470 /*
471 * The value for the HI16 had best be the same. 471 * The value for the HI16 had best be the same.
472 */ 472 */
473 if (v != l->value) { 473 if (v != l->value) {
474 printk(KERN_DEBUG "VPE loader: " 474 printk(KERN_DEBUG "VPE loader: "
475 "apply_r_mips_lo16/hi16: \t" 475 "apply_r_mips_lo16/hi16: \t"
476 "inconsistent value information\n"); 476 "inconsistent value information\n");
@@ -505,7 +505,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
505 } 505 }
506 506
507 /* 507 /*
508 * Ok, we're done with the HI16 relocs. Now deal with the LO16. 508 * Ok, we're done with the HI16 relocs. Now deal with the LO16.
509 */ 509 */
510 val = v + vallo; 510 val = v + vallo;
511 insnlo = (insnlo & ~0xffff) | (val & 0xffff); 511 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
@@ -579,7 +579,7 @@ static int apply_relocations(Elf32_Shdr *sechdrs,
579 res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v); 579 res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
580 if( res ) { 580 if( res ) {
581 char *r = rstrs[ELF32_R_TYPE(r_info)]; 581 char *r = rstrs[ELF32_R_TYPE(r_info)];
582 printk(KERN_WARNING "VPE loader: .text+0x%x " 582 printk(KERN_WARNING "VPE loader: .text+0x%x "
583 "relocation type %s for symbol \"%s\" failed\n", 583 "relocation type %s for symbol \"%s\" failed\n",
584 rel[i].r_offset, r ? r : "UNKNOWN", 584 rel[i].r_offset, r ? r : "UNKNOWN",
585 strtab + sym->st_name); 585 strtab + sym->st_name);
@@ -697,18 +697,7 @@ static int vpe_run(struct vpe * v)
697 dmt_flag = dmt(); 697 dmt_flag = dmt();
698 vpeflags = dvpe(); 698 vpeflags = dvpe();
699 699
700 if (!list_empty(&v->tc)) { 700 if (list_empty(&v->tc)) {
701 if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
702 evpe(vpeflags);
703 emt(dmt_flag);
704 local_irq_restore(flags);
705
706 printk(KERN_WARNING
707 "VPE loader: TC %d is already in use.\n",
708 v->tc->index);
709 return -ENOEXEC;
710 }
711 } else {
712 evpe(vpeflags); 701 evpe(vpeflags);
713 emt(dmt_flag); 702 emt(dmt_flag);
714 local_irq_restore(flags); 703 local_irq_restore(flags);
@@ -720,6 +709,8 @@ static int vpe_run(struct vpe * v)
720 return -ENOEXEC; 709 return -ENOEXEC;
721 } 710 }
722 711
712 t = list_first_entry(&v->tc, struct tc, tc);
713
723 /* Put MVPE's into 'configuration state' */ 714 /* Put MVPE's into 'configuration state' */
724 set_c0_mvpcontrol(MVPCONTROL_VPC); 715 set_c0_mvpcontrol(MVPCONTROL_VPC);
725 716
@@ -772,7 +763,7 @@ static int vpe_run(struct vpe * v)
772 763
773 /* Set up the XTC bit in vpeconf0 to point at our tc */ 764 /* Set up the XTC bit in vpeconf0 to point at our tc */
774 write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC)) 765 write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
775 | (t->index << VPECONF0_XTC_SHIFT)); 766 | (t->index << VPECONF0_XTC_SHIFT));
776 767
777 back_to_back_c0_hazard(); 768 back_to_back_c0_hazard();
778 769
@@ -926,34 +917,34 @@ static int vpe_elfload(struct vpe * v)
926 secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr); 917 secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr);
927 } 918 }
928 919
929 /* Fix up syms, so that st_value is a pointer to location. */ 920 /* Fix up syms, so that st_value is a pointer to location. */
930 simplify_symbols(sechdrs, symindex, strtab, secstrings, 921 simplify_symbols(sechdrs, symindex, strtab, secstrings,
931 hdr->e_shnum, &mod); 922 hdr->e_shnum, &mod);
932 923
933 /* Now do relocations. */ 924 /* Now do relocations. */
934 for (i = 1; i < hdr->e_shnum; i++) { 925 for (i = 1; i < hdr->e_shnum; i++) {
935 const char *strtab = (char *)sechdrs[strindex].sh_addr; 926 const char *strtab = (char *)sechdrs[strindex].sh_addr;
936 unsigned int info = sechdrs[i].sh_info; 927 unsigned int info = sechdrs[i].sh_info;
937 928
938 /* Not a valid relocation section? */ 929 /* Not a valid relocation section? */
939 if (info >= hdr->e_shnum) 930 if (info >= hdr->e_shnum)
940 continue; 931 continue;
941 932
942 /* Don't bother with non-allocated sections */ 933 /* Don't bother with non-allocated sections */
943 if (!(sechdrs[info].sh_flags & SHF_ALLOC)) 934 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
944 continue; 935 continue;
945 936
946 if (sechdrs[i].sh_type == SHT_REL) 937 if (sechdrs[i].sh_type == SHT_REL)
947 err = apply_relocations(sechdrs, strtab, symindex, i, 938 err = apply_relocations(sechdrs, strtab, symindex, i,
948 &mod); 939 &mod);
949 else if (sechdrs[i].sh_type == SHT_RELA) 940 else if (sechdrs[i].sh_type == SHT_RELA)
950 err = apply_relocate_add(sechdrs, strtab, symindex, i, 941 err = apply_relocate_add(sechdrs, strtab, symindex, i,
951 &mod); 942 &mod);
952 if (err < 0) 943 if (err < 0)
953 return err; 944 return err;
954 945
955 } 946 }
956 } else { 947 } else {
957 struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff); 948 struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
958 949
959 for (i = 0; i < hdr->e_phnum; i++) { 950 for (i = 0; i < hdr->e_phnum; i++) {
@@ -968,16 +959,16 @@ static int vpe_elfload(struct vpe * v)
968 } 959 }
969 960
970 for (i = 0; i < hdr->e_shnum; i++) { 961 for (i = 0; i < hdr->e_shnum; i++) {
971 /* Internal symbols and strings. */ 962 /* Internal symbols and strings. */
972 if (sechdrs[i].sh_type == SHT_SYMTAB) { 963 if (sechdrs[i].sh_type == SHT_SYMTAB) {
973 symindex = i; 964 symindex = i;
974 strindex = sechdrs[i].sh_link; 965 strindex = sechdrs[i].sh_link;
975 strtab = (char *)hdr + sechdrs[strindex].sh_offset; 966 strtab = (char *)hdr + sechdrs[strindex].sh_offset;
976 967
977 /* mark the symtab's address for when we try to find the 968 /* mark the symtab's address for when we try to find the
978 magic symbols */ 969 magic symbols */
979 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; 970 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
980 } 971 }
981 } 972 }
982 } 973 }
983 974
@@ -1049,7 +1040,7 @@ static int getcwd(char *buff, int size)
1049 return ret; 1040 return ret;
1050} 1041}
1051 1042
1052/* checks VPE is unused and gets ready to load program */ 1043/* checks VPE is unused and gets ready to load program */
1053static int vpe_open(struct inode *inode, struct file *filp) 1044static int vpe_open(struct inode *inode, struct file *filp)
1054{ 1045{
1055 enum vpe_state state; 1046 enum vpe_state state;
@@ -1121,11 +1112,11 @@ static int vpe_release(struct inode *inode, struct file *filp)
1121 if (vpe_elfload(v) >= 0) { 1112 if (vpe_elfload(v) >= 0) {
1122 vpe_run(v); 1113 vpe_run(v);
1123 } else { 1114 } else {
1124 printk(KERN_WARNING "VPE loader: ELF load failed.\n"); 1115 printk(KERN_WARNING "VPE loader: ELF load failed.\n");
1125 ret = -ENOEXEC; 1116 ret = -ENOEXEC;
1126 } 1117 }
1127 } else { 1118 } else {
1128 printk(KERN_WARNING "VPE loader: only elf files are supported\n"); 1119 printk(KERN_WARNING "VPE loader: only elf files are supported\n");
1129 ret = -ENOEXEC; 1120 ret = -ENOEXEC;
1130 } 1121 }
1131 1122