1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker /**
26*61046927SAndroid Build Coastguard Worker * \file glapi_entrypoint.c
27*61046927SAndroid Build Coastguard Worker *
28*61046927SAndroid Build Coastguard Worker * Arch-specific code for manipulating GL API entrypoints (dispatch stubs).
29*61046927SAndroid Build Coastguard Worker */
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include <string.h>
33*61046927SAndroid Build Coastguard Worker
34*61046927SAndroid Build Coastguard Worker #include "c11/threads.h"
35*61046927SAndroid Build Coastguard Worker #include "glapi/glapi_priv.h"
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker #ifdef USE_X86_ASM
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker extern GLubyte gl_dispatch_functions_start[];
41*61046927SAndroid Build Coastguard Worker extern GLubyte gl_dispatch_functions_end[];
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker #endif /* USE_X86_ASM */
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker #if defined(DISPATCH_FUNCTION_SIZE)
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker _glapi_proc
get_entrypoint_address(unsigned int functionOffset)49*61046927SAndroid Build Coastguard Worker get_entrypoint_address(unsigned int functionOffset)
50*61046927SAndroid Build Coastguard Worker {
51*61046927SAndroid Build Coastguard Worker return (_glapi_proc) (gl_dispatch_functions_start
52*61046927SAndroid Build Coastguard Worker + (DISPATCH_FUNCTION_SIZE * functionOffset));
53*61046927SAndroid Build Coastguard Worker }
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker #endif
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker #if defined(USE_X86_ASM)
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker /**
61*61046927SAndroid Build Coastguard Worker * Perform platform-specific GL API entry-point fixups.
62*61046927SAndroid Build Coastguard Worker */
63*61046927SAndroid Build Coastguard Worker static void
init_glapi_relocs(void)64*61046927SAndroid Build Coastguard Worker init_glapi_relocs( void )
65*61046927SAndroid Build Coastguard Worker {
66*61046927SAndroid Build Coastguard Worker #if !defined(GLX_X86_READONLY_TEXT)
67*61046927SAndroid Build Coastguard Worker extern unsigned long _x86_get_dispatch(void);
68*61046927SAndroid Build Coastguard Worker char run_time_patch[] = {
69*61046927SAndroid Build Coastguard Worker 0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
70*61046927SAndroid Build Coastguard Worker };
71*61046927SAndroid Build Coastguard Worker GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
72*61046927SAndroid Build Coastguard Worker const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
73*61046927SAndroid Build Coastguard Worker GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker *offset = _x86_get_dispatch();
76*61046927SAndroid Build Coastguard Worker while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
77*61046927SAndroid Build Coastguard Worker (void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
78*61046927SAndroid Build Coastguard Worker curr_func += DISPATCH_FUNCTION_SIZE;
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker #endif
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker #elif defined(USE_SPARC_ASM)
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker extern void __glapi_sparc_icache_flush(unsigned int *);
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker static void
init_glapi_relocs(void)88*61046927SAndroid Build Coastguard Worker init_glapi_relocs( void )
89*61046927SAndroid Build Coastguard Worker {
90*61046927SAndroid Build Coastguard Worker static const unsigned int template[] = {
91*61046927SAndroid Build Coastguard Worker 0x05000000, /* sethi %hi(_glapi_tls_Dispatch), %g2 */
92*61046927SAndroid Build Coastguard Worker 0x8730e00a, /* srl %g3, 10, %g3 */
93*61046927SAndroid Build Coastguard Worker 0x8410a000, /* or %g2, %lo(_glapi_tls_Dispatch), %g2 */
94*61046927SAndroid Build Coastguard Worker #ifdef __arch64__
95*61046927SAndroid Build Coastguard Worker 0xc259c002, /* ldx [%g7 + %g2], %g1 */
96*61046927SAndroid Build Coastguard Worker 0xc2584003, /* ldx [%g1 + %g3], %g1 */
97*61046927SAndroid Build Coastguard Worker #else
98*61046927SAndroid Build Coastguard Worker 0xc201c002, /* ld [%g7 + %g2], %g1 */
99*61046927SAndroid Build Coastguard Worker 0xc2004003, /* ld [%g1 + %g3], %g1 */
100*61046927SAndroid Build Coastguard Worker #endif
101*61046927SAndroid Build Coastguard Worker 0x81c04000, /* jmp %g1 */
102*61046927SAndroid Build Coastguard Worker 0x01000000, /* nop */
103*61046927SAndroid Build Coastguard Worker };
104*61046927SAndroid Build Coastguard Worker extern unsigned int __glapi_sparc_tls_stub;
105*61046927SAndroid Build Coastguard Worker extern unsigned long __glapi_sparc_get_dispatch(void);
106*61046927SAndroid Build Coastguard Worker unsigned int *code = &__glapi_sparc_tls_stub;
107*61046927SAndroid Build Coastguard Worker unsigned long dispatch = __glapi_sparc_get_dispatch();
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker code[0] = template[0] | (dispatch >> 10);
110*61046927SAndroid Build Coastguard Worker code[1] = template[1];
111*61046927SAndroid Build Coastguard Worker __glapi_sparc_icache_flush(&code[0]);
112*61046927SAndroid Build Coastguard Worker code[2] = template[2] | (dispatch & 0x3ff);
113*61046927SAndroid Build Coastguard Worker code[3] = template[3];
114*61046927SAndroid Build Coastguard Worker __glapi_sparc_icache_flush(&code[2]);
115*61046927SAndroid Build Coastguard Worker code[4] = template[4];
116*61046927SAndroid Build Coastguard Worker code[5] = template[5];
117*61046927SAndroid Build Coastguard Worker __glapi_sparc_icache_flush(&code[4]);
118*61046927SAndroid Build Coastguard Worker code[6] = template[6];
119*61046927SAndroid Build Coastguard Worker __glapi_sparc_icache_flush(&code[6]);
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker #else /* USE_*_ASM */
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker static void
init_glapi_relocs(void)126*61046927SAndroid Build Coastguard Worker init_glapi_relocs( void )
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker #endif /* USE_*_ASM */
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker void
init_glapi_relocs_once(void)134*61046927SAndroid Build Coastguard Worker init_glapi_relocs_once( void )
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker static once_flag flag = ONCE_FLAG_INIT;
137*61046927SAndroid Build Coastguard Worker call_once(&flag, init_glapi_relocs);
138*61046927SAndroid Build Coastguard Worker }
139