Path: blob/master/arch/microblaze/include/asm/flat.h
15126 views
/*1* uClinux flat-format executables2*3* Copyright (C) 2005 John Williams <[email protected]>4*5* This file is subject to the terms and conditions of the GNU General6* Public License. See the file COPYING in the main directory of this7* archive for more details.8*/910#ifndef _ASM_MICROBLAZE_FLAT_H11#define _ASM_MICROBLAZE_FLAT_H1213#include <asm/unaligned.h>1415#define flat_argvp_envp_on_stack() 016#define flat_old_ram_flag(flags) (flags)17#define flat_reloc_valid(reloc, size) ((reloc) <= (size))18#define flat_set_persistent(relval, p) 01920/*21* Microblaze works a little differently from other arches, because22* of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split23* over two instructions, an 'imm' instruction which provides the top24* 16 bits, then the instruction "proper" which provides the low 1625* bits.26*/2728/*29* Crack open a symbol reference and extract the address to be30* relocated. rp is a potentially unaligned pointer to the31* reference32*/3334static inline unsigned long35flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,36unsigned long flags, unsigned long *persistent)37{38unsigned long addr;39(void)flags;4041/* Is it a split 64/32 reference? */42if (relval & 0x80000000) {43/* Grab the two halves of the reference */44unsigned long val_hi, val_lo;4546val_hi = get_unaligned(rp);47val_lo = get_unaligned(rp+1);4849/* Crack the address out */50addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);51} else {52/* Get the address straight out */53addr = get_unaligned(rp);54}5556return addr;57}5859/*60* Insert an address into the symbol reference at rp. rp is potentially61* unaligned.62*/6364static inline void65flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)66{67/* Is this a split 64/32 reloc? */68if (relval & 0x80000000) {69/* Get the two "halves" */70unsigned long val_hi = get_unaligned(rp);71unsigned long val_lo = get_unaligned(rp + 1);7273/* insert the address */74val_hi = (val_hi & 0xffff0000) | addr >> 16;75val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);7677/* store the two halves back into memory */78put_unaligned(val_hi, rp);79put_unaligned(val_lo, rp+1);80} else {81/* Put it straight in, no messing around */82put_unaligned(addr, rp);83}84}8586#define flat_get_relocate_addr(rel) (rel & 0x7fffffff)8788#endif /* _ASM_MICROBLAZE_FLAT_H */899091