MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / include / asm-nios2nommu / flat.h
blob15050dbfec6c0be0fb5353072bdb71032da7a0a1
1 /*
2 * include/asm-nios2nommu/flat.h -- uClinux bFLT relocations
4 * Copyright (C) 2004,05 Microtronix Datacom Ltd
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file COPYING in the main directory of this
8 * archive for more details.
10 * Written by Wentao Xu <wentao@microtronix.com>
13 #ifndef __NIOS2_FLAT_H__
14 #define __NIOS2_FLAT_H__
16 #define flat_reloc_valid(reloc, size) ((reloc) <= (size + 0x8000))
18 /* The stack is 64-bit aligned for Nios II, so (sp - 1) shall
19 * be 64-bit aligned, where -1 is for argc
21 #define flat_stack_align(sp) (sp = (unsigned long *)(((unsigned long)sp - 1) & (-8)))
23 /* The uClibc port for Nios II expects the argc is followed by argv and envp */
24 #define flat_argvp_envp_on_stack() 1
26 #define flat_old_ram_flag(flags) (flags)
28 /* We store the type of relocation in the top 4 bits of the `relval.' */
30 /* Convert a relocation entry into an address. */
31 static inline unsigned long
32 flat_get_relocate_addr (unsigned long relval)
34 return relval & 0x0fffffff; /* Mask out top 4-bits */
37 #define FLAT_NIOS2_RELOC_TYPE(relval) ((relval) >> 28)
39 #define FLAT_NIOS2_R_32 0 /* Normal 32-bit reloc */
40 #define FLAT_NIOS2_R_HI_LO 1 /* High 16-bits + low 16-bits field */
41 #define FLAT_NIOS2_R_HIADJ_LO 2 /* High 16-bits adjust + low 16-bits field */
42 #define FLAT_NIOS2_R_CALL26 4 /* Call imm26 */
44 /* Extract the address to be relocated from the symbol reference at rp;
45 * relval is the raw relocation-table entry from which RP is derived.
46 * rp shall always be 32-bit aligned
48 static inline unsigned long flat_get_addr_from_rp (unsigned long *rp,
49 unsigned long relval,
50 unsigned long flags)
52 switch (FLAT_NIOS2_RELOC_TYPE(relval))
54 case FLAT_NIOS2_R_32:
55 /* Simple 32-bit address. The loader expect it in bigger endian */
56 return htonl(*rp);
58 case FLAT_NIOS2_R_HI_LO:
59 /* get the two 16-bit immediate value from instructions, then
60 * construct a 32-bit value. Again the loader expect bigger endian
62 return htonl ((((rp[0] >> 6) & 0xFFFF) << 16 ) |
63 ((rp[1] >> 6) & 0xFFFF));
65 case FLAT_NIOS2_R_HIADJ_LO:
67 /* get the two 16-bit immediate value from instructions, then
68 * construct a 32-bit value. Again the loader expect bigger endian
70 unsigned int low, high;
71 high = (rp[0] >> 6) & 0xFFFF;
72 low = (rp[1] >> 6) & 0xFFFF;
74 if ((low >> 15) & 1) high--;
76 return htonl ((high << 16 ) | low );
78 case FLAT_NIOS2_R_CALL26:
79 /* the 26-bit immediate value is actually 28-bit */
80 return htonl(((*rp) >> 6) << 2);
82 default:
83 return ~0; /* bogus value */
87 /* Insert the address addr into the symbol reference at rp;
88 * relval is the raw relocation-table entry from which rp is derived.
89 * rp shall always be 32-bit aligned
91 static inline void flat_put_addr_at_rp (unsigned long *rp, unsigned long addr,
92 unsigned long relval)
94 unsigned long exist_val;
95 switch (FLAT_NIOS2_RELOC_TYPE (relval)) {
96 case FLAT_NIOS2_R_32:
97 /* Simple 32-bit address. */
98 *rp = addr;
99 break;
101 case FLAT_NIOS2_R_HI_LO:
102 exist_val = rp[0];
103 rp[0] = ((((exist_val >> 22) << 16) | (addr >> 16)) << 6) | (exist_val & 0x3F);
104 exist_val = rp[1];
105 rp[1] = ((((exist_val >> 22) << 16) | (addr & 0xFFFF)) << 6) | (exist_val & 0x3F);
106 break;
108 case FLAT_NIOS2_R_HIADJ_LO:
110 unsigned int high = (addr >> 16);
111 if ((addr >> 15) & 1)
112 high = (high + 1) & 0xFFFF;
113 exist_val = rp[0];
114 rp[0] = ((((exist_val >> 22) << 16) | high) << 6) | (exist_val & 0x3F);
115 exist_val = rp[1];
116 rp[1] = ((((exist_val >> 22) << 16) | (addr & 0xFFFF)) << 6) | (exist_val & 0x3F);
117 break;
119 case FLAT_NIOS2_R_CALL26:
120 /* the opcode of CALL is 0, so just store the value */
121 *rp = ((addr >> 2) << 6);
122 break;
126 #endif /* __NIOS2_FLAT_H__ */