8 #include <linux/kernel.h>
13 #include <linux/string.h>
14 #include <linux/ctype.h>
17 #include <asm/processor.h>
19 #include <asm/cacheflush.h>
27 static void *module_map(
unsigned long size)
33 __builtin_return_address(0));
36 static void *module_map(
unsigned long size)
50 ret = module_map(size);
68 for (symidx = 0; sechdrs[symidx].sh_type !=
SHT_SYMTAB; symidx++) {
69 if (symidx == hdr->e_shnum-1) {
74 sym = (
Elf_Sym *)sechdrs[symidx].sh_addr;
75 strtab = (
char *)sechdrs[sechdrs[symidx].sh_link].sh_addr;
77 for (i = 1; i < sechdrs[symidx].sh_size /
sizeof(
Elf_Sym); i++) {
88 unsigned int symindex,
93 Elf_Rela *rel = (
void *)sechdrs[relsec].sh_addr;
98 for (i = 0; i < sechdrs[relsec].sh_size /
sizeof(*rel); i++) {
102 location = (
u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr
104 loc32 = (
u32 *) location;
106 #ifdef CONFIG_SPARC64
112 sym = (
Elf_Sym *)sechdrs[symindex].sh_addr
114 v = sym->st_value + rel[
i].r_addend;
121 #ifdef CONFIG_SPARC64
123 location[0] = v >> 56;
124 location[1] = v >> 48;
125 location[2] = v >> 40;
126 location[3] = v >> 32;
127 location[4] = v >> 24;
128 location[5] = v >> 16;
129 location[6] = v >> 8;
130 location[7] = v >> 0;
135 *loc32 = (*loc32 & ~0x7ffff) |
136 ((v >> 2) & 0x7ffff);
140 *loc32 = (*loc32 & ~0x1fff) |
149 location[0] = v >> 24;
150 location[1] = v >> 16;
151 location[2] = v >> 8;
152 location[3] = v >> 0;
157 *loc32 = (*loc32 & ~0x3fffffff) |
158 ((v >> 2) & 0x3fffffff);
163 *loc32 = (*loc32 & ~0x3fffff) |
164 ((v >> 2) & 0x3fffff);
168 *loc32 = (*loc32 & ~0x3ff) | (v & 0x3ff);
172 *loc32 = (*loc32 & ~0x3fffff) |
173 ((v >> 10) & 0x3fffff);
186 #ifdef CONFIG_SPARC64
191 char *secstrings = (
void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
193 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
194 if (!
strcmp(
".sun4v_1insn_patch", secstrings + s->sh_name))
196 if (!
strcmp(
".sun4v_2insn_patch", secstrings + s->sh_name))
200 if (sun4v_1insn &&
tlb_type == hypervisor) {
201 void *
p = (
void *) sun4v_1insn->sh_addr;
204 if (sun4v_2insn &&
tlb_type == hypervisor) {
205 void *p = (
void *) sun4v_2insn->sh_addr;
215 jump_label_apply_nops(me);
217 do_patch_sections(hdr, sechdrs);
224 for (va = 0; va < (
PAGE_SIZE << 1); va += 32)
225 spitfire_put_icache_tag(va, 0x0);
226 __asm__ __volatile__(
"flush %g6");