home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-v850 / flat.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  4.7 KB  |  132 lines

  1. /*
  2.  * include/asm-v850/flat.h -- uClinux flat-format executables
  3.  *
  4.  *  Copyright (C) 2002,03  NEC Electronics Corporation
  5.  *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
  6.  *
  7.  * This file is subject to the terms and conditions of the GNU General
  8.  * Public License.  See the file COPYING in the main directory of this
  9.  * archive for more details.
  10.  *
  11.  * Written by Miles Bader <miles@gnu.org>
  12.  */
  13.  
  14. #ifndef __V850_FLAT_H__
  15. #define __V850_FLAT_H__
  16.  
  17. /* The amount by which a relocation can exceed the program image limits
  18.    without being regarded as an error.  On the v850, the relocations of
  19.    some base-pointers can be offset by 0x8000 (to allow better usage of the
  20.    space offered by 16-bit signed offsets -- in most cases the offsets used
  21.    with such a base-pointer will be negative).  */
  22.  
  23. #define    flat_reloc_valid(reloc, size)    ((reloc) <= (size + 0x8000))
  24.  
  25. #define    flat_stack_align(sp)        /* nothing needed */
  26. #define    flat_argvp_envp_on_stack()    0
  27. #define    flat_old_ram_flag(flags)    (flags)
  28.  
  29. /* We store the type of relocation in the top 4 bits of the `relval.' */
  30.  
  31. /* Convert a relocation entry into an address.  */
  32. static inline unsigned long
  33. flat_get_relocate_addr (unsigned long relval)
  34. {
  35.     return relval & 0x0fffffff; /* Mask out top 4-bits */
  36. }
  37.  
  38. #define flat_v850_get_reloc_type(relval) ((relval) >> 28)
  39.  
  40. #define FLAT_V850_R_32        0 /* Normal 32-bit reloc */
  41. #define FLAT_V850_R_HI16S_LO15    1 /* High 16-bits + signed 15-bit low field */
  42. #define FLAT_V850_R_HI16S_LO16    2 /* High 16-bits + signed 16-bit low field */
  43.  
  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.    For the v850, RP should always be half-word aligned.  */
  47. static inline unsigned long flat_get_addr_from_rp (unsigned long *rp,
  48.                            unsigned long relval,
  49.                            unsigned long flags)
  50. {
  51.     short *srp = (short *)rp;
  52.  
  53.     switch (flat_v850_get_reloc_type (relval))
  54.     {
  55.     case FLAT_V850_R_32:
  56.         /* Simple 32-bit address.  */
  57.         return srp[0] | (srp[1] << 16);
  58.  
  59.     case FLAT_V850_R_HI16S_LO16:
  60.         /* The high and low halves of the address are in the 16
  61.            bits at RP, and the 2nd word of the 32-bit instruction
  62.            following that, respectively.  The low half is _signed_
  63.            so we have to sign-extend it and add it to the upper
  64.            half instead of simply or-ing them together.
  65.  
  66.            Unlike most relocated address, this one is stored in
  67.            native (little-endian) byte-order to avoid problems with
  68.            trashing the low-order bit, so we have to convert to
  69.            network-byte-order before returning, as that's what the
  70.            caller expects.  */
  71.         return htonl ((srp[0] << 16) + srp[2]);
  72.  
  73.     case FLAT_V850_R_HI16S_LO15:
  74.         /* The high and low halves of the address are in the 16
  75.            bits at RP, and the upper 15 bits of the 2nd word of the
  76.            32-bit instruction following that, respectively.  The
  77.            low half is _signed_ so we have to sign-extend it and
  78.            add it to the upper half instead of simply or-ing them
  79.            together.  The lowest bit is always zero.
  80.  
  81.            Unlike most relocated address, this one is stored in
  82.            native (little-endian) byte-order to avoid problems with
  83.            trashing the low-order bit, so we have to convert to
  84.            network-byte-order before returning, as that's what the
  85.            caller expects.  */
  86.         return htonl ((srp[0] << 16) + (srp[2] & ~0x1));
  87.  
  88.     default:
  89.         return ~0;    /* bogus value */
  90.     }
  91. }
  92.  
  93. /* Insert the address ADDR into the symbol reference at RP;
  94.    RELVAL is the raw relocation-table entry from which RP is derived.
  95.    For the v850, RP should always be half-word aligned.  */
  96. static inline void flat_put_addr_at_rp (unsigned long *rp, unsigned long addr,
  97.                     unsigned long relval)
  98. {
  99.     short *srp = (short *)rp;
  100.  
  101.     switch (flat_v850_get_reloc_type (relval)) {
  102.     case FLAT_V850_R_32:
  103.         /* Simple 32-bit address.  */
  104.         srp[0] = addr & 0xFFFF;
  105.         srp[1] = (addr >> 16);
  106.         break;
  107.  
  108.     case FLAT_V850_R_HI16S_LO16:
  109.         /* The high and low halves of the address are in the 16
  110.            bits at RP, and the 2nd word of the 32-bit instruction
  111.            following that, respectively.  The low half is _signed_
  112.            so we must carry its sign bit to the upper half before
  113.            writing the upper half.  */
  114.         srp[0] = (addr >> 16) + ((addr >> 15) & 0x1);
  115.         srp[2] = addr & 0xFFFF;
  116.         break;
  117.  
  118.     case FLAT_V850_R_HI16S_LO15:
  119.         /* The high and low halves of the address are in the 16
  120.            bits at RP, and the upper 15 bits of the 2nd word of the
  121.            32-bit instruction following that, respectively.  The
  122.            low half is _signed_ so we must carry its sign bit to
  123.            the upper half before writing the upper half.  The
  124.            lowest bit we preserve from the existing instruction.  */
  125.         srp[0] = (addr >> 16) + ((addr >> 15) & 0x1);
  126.         srp[2] = (addr & 0xFFFE) | (srp[2] & 0x1);
  127.         break;
  128.     }
  129. }
  130.  
  131. #endif /* __V850_FLAT_H__ */
  132.