aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c
blob: 09cc64f213c0a00e065443d6b4336abaf56e98ef (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * tramp_table_c6000.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "dload_internal.h"

/*  These are defined in coff.h, but may not be available on all platforms
	so we'll go ahead and define them here. */
#ifndef R_C60LO16
#define R_C60LO16	  0x54	/* C60: MVK Low Half Register */
#define R_C60HI16	  0x55	/* C60: MVKH/MVKLH High Half Register */
#endif

#define C6X_TRAMP_WORD_COUNT			8
#define C6X_TRAMP_MAX_RELOS			 8

/*  THIS HASH FUNCTION MUST MATCH THE ONE reloc_table_c6000.c */
#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63)

/*  THIS MUST MATCH reloc_record_t FOR A SYMBOL BASED RELO */
struct c6000_relo_record {
	s32 vaddr;
	s32 symndx;
#ifndef _BIG_ENDIAN
	u16 disp;
	u16 type;
#else
	u16 type;
	u16 disp;
#endif
};

struct c6000_gen_code {
	struct tramp_gen_code_hdr hdr;
	u32 tramp_instrs[C6X_TRAMP_WORD_COUNT];
	struct c6000_relo_record relos[C6X_TRAMP_MAX_RELOS];
};

/*  Hash mapping for relos that can cause trampolines. */
static const u16 tramp_map[] = {
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	0,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535,
	65535
};

static const struct c6000_gen_code tramp_gen_info[] = {
	/*  Tramp caused by R_C60PCR21 */
	{
	 /*  Header - 8 instructions, 2 relos */
	 {
	  sizeof(u32) * C6X_TRAMP_WORD_COUNT,
	  2,
	  FIELD_OFFSET(struct c6000_gen_code, relos)
	  },

	 /*  Trampoline instructions */
	 {
	  0x053C54F7,		/*       STW.D2T2  B10, *sp--[2] */
	  0x0500002A,		/*  || MVK.S2   <blank>, B10 */
	  0x0500006A,		/*       MVKH.S2   <blank>, B10 */
	  0x00280362,		/*       B.S2     B10 */
	  0x053C52E6,		/*       LDW.D2T2  *++sp[2], B10 */
	  0x00006000,		/*       NOP       4 */
	  0x00000000,		/*       NOP */
	  0x00000000		/*       NOP */
	  },

	 /*  Relocations */
	 {
	  {4, 0, 0, R_C60LO16},
	  {8, 0, 0, R_C60HI16},
	  {0, 0, 0, 0x0000},
	  {0, 0, 0, 0x0000},
	  {0, 0, 0, 0x0000},
	  {0, 0, 0, 0x0000},
	  {0, 0, 0, 0x0000},
	  {0, 0, 0, 0x0000}
	  }
	 }
};

/*  TARGET SPECIFIC FUNCTIONS THAT MUST BE DEFINED */
static u32 tramp_size_get(void)
{
	return sizeof(u32) * C6X_TRAMP_WORD_COUNT;
}

static u32 tramp_img_pkt_size_get(void)
{
	return sizeof(struct c6000_gen_code);
}