Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/microblaze/include/asm/flat.h
15126 views
1
/*
2
* uClinux flat-format executables
3
*
4
* Copyright (C) 2005 John Williams <[email protected]>
5
*
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.
9
*/
10
11
#ifndef _ASM_MICROBLAZE_FLAT_H
12
#define _ASM_MICROBLAZE_FLAT_H
13
14
#include <asm/unaligned.h>
15
16
#define flat_argvp_envp_on_stack() 0
17
#define flat_old_ram_flag(flags) (flags)
18
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
19
#define flat_set_persistent(relval, p) 0
20
21
/*
22
* Microblaze works a little differently from other arches, because
23
* of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split
24
* over two instructions, an 'imm' instruction which provides the top
25
* 16 bits, then the instruction "proper" which provides the low 16
26
* bits.
27
*/
28
29
/*
30
* Crack open a symbol reference and extract the address to be
31
* relocated. rp is a potentially unaligned pointer to the
32
* reference
33
*/
34
35
static inline unsigned long
36
flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
37
unsigned long flags, unsigned long *persistent)
38
{
39
unsigned long addr;
40
(void)flags;
41
42
/* Is it a split 64/32 reference? */
43
if (relval & 0x80000000) {
44
/* Grab the two halves of the reference */
45
unsigned long val_hi, val_lo;
46
47
val_hi = get_unaligned(rp);
48
val_lo = get_unaligned(rp+1);
49
50
/* Crack the address out */
51
addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
52
} else {
53
/* Get the address straight out */
54
addr = get_unaligned(rp);
55
}
56
57
return addr;
58
}
59
60
/*
61
* Insert an address into the symbol reference at rp. rp is potentially
62
* unaligned.
63
*/
64
65
static inline void
66
flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
67
{
68
/* Is this a split 64/32 reloc? */
69
if (relval & 0x80000000) {
70
/* Get the two "halves" */
71
unsigned long val_hi = get_unaligned(rp);
72
unsigned long val_lo = get_unaligned(rp + 1);
73
74
/* insert the address */
75
val_hi = (val_hi & 0xffff0000) | addr >> 16;
76
val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
77
78
/* store the two halves back into memory */
79
put_unaligned(val_hi, rp);
80
put_unaligned(val_lo, rp+1);
81
} else {
82
/* Put it straight in, no messing around */
83
put_unaligned(addr, rp);
84
}
85
}
86
87
#define flat_get_relocate_addr(rel) (rel & 0x7fffffff)
88
89
#endif /* _ASM_MICROBLAZE_FLAT_H */
90
91