libspe2  0.9a
load.c
Go to the documentation of this file.
1 /*
2  * libspe2 - A wrapper library to adapt the JSRE SPU usage model to SPUFS
3  * Copyright (C) 2005 IBM Corp.
4  *
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation; either version 2.1 of the License,
8  * or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 #include <fcntl.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 
26 #include "elf_loader.h"
27 #include "create.h"
28 #include "spebase.h"
29 
30 #ifndef SPE_EMULATED_LOADER_FILE
31 #define SPE_EMULATED_LOADER_FILE "/usr/lib/spe/emulated-loader.bin"
32 #endif
33 
39 {
40  int objfd, len;
41  char buf[20];
42  spe_program_handle_t *program;
43 
44  program = spectx->base_private->loaded_program;
45 
46  if (!program || !program->elf_image) {
47  DEBUG_PRINTF("%s called, but no program loaded\n", __func__);
48  return;
49  }
50 
51  objfd = openat(spectx->base_private->fd_spe_dir, "object-id", O_RDWR);
52  if (objfd < 0)
53  return;
54 
55  len = sprintf(buf, "%p", program->elf_image);
56  write(objfd, buf, len + 1);
57  close(objfd);
58 
60 }
61 
73 static inline int __write_isolated_load_params(struct spe_context *spe,
74  uint32_t addr_h, uint32_t addr_l, uint32_t size)
75 {
76  int fd = _base_spe_open_if_closed(spe, FD_WBOX, 0);
77 
78  if (fd < 0) {
79  DEBUG_PRINTF("%s: can't open wbox\n", __FUNCTION__);
80  return -1;
81  }
82 
83  if ((write(fd, &addr_h, sizeof(uint32_t)) != sizeof(uint32_t)) ||
84  (write(fd, &addr_l, sizeof(uint32_t)) != sizeof(uint32_t)) ||
85  (write(fd, &size, sizeof(uint32_t)) != sizeof(uint32_t))) {
86  DEBUG_PRINTF("%s: error writing to wbox\n", __FUNCTION__);
87  return -1;
88  }
89 
90  return 0;
91 }
92 
102 static int spe_start_isolated_app(struct spe_context *spe,
103  spe_program_handle_t *handle)
104 {
105  uint64_t addr;
106  uint32_t size, addr_h, addr_l;
107 
108  if (_base_spe_parse_isolated_elf(handle, &addr, &size)) {
109  DEBUG_PRINTF("%s: invalid isolated image\n", __FUNCTION__);
110  errno = ENOEXEC;
111  return -errno;
112  }
113 
114  if (addr & 0xf) {
115  DEBUG_PRINTF("%s: isolated image is incorrectly aligned\n",
116  __FUNCTION__);
117  errno = EINVAL;
118  return -errno;
119  }
120 
121  addr_l = (uint32_t)(addr & 0xffffffff);
122  addr_h = (uint32_t)(addr >> 32);
123 
124  DEBUG_PRINTF("%s: Sending isolated app params: 0x%08x 0x%08x 0x%08x\n",
125  __FUNCTION__, addr_h, addr_l, size);
126 
127  if (__write_isolated_load_params(spe, addr_h, addr_l, size)) {
128  errno = EIO;
129  return -errno;
130  }
131 
132  return 0;
133 }
134 
141 static spe_program_handle_t *emulated_loader_program(void)
142 {
143  static spe_program_handle_t *loader = NULL;
144 
145  if (!loader)
147 
148  if (!loader)
149  DEBUG_PRINTF("Can't load emulated loader '%s': %s\n",
150  SPE_EMULATED_LOADER_FILE, strerror(errno));
151 
152  return loader;
153 }
154 
160 {
161  spe_program_handle_t *loader = emulated_loader_program();
162 
163  if (!loader)
164  return 0;
165 
166  return !_base_spe_verify_spe_elf_image(loader);
167 }
168 
181 static int spe_start_emulated_isolated_app(struct spe_context *spe,
182  spe_program_handle_t *handle, struct spe_ld_info *ld_info)
183 
184 {
185  int rc;
186  spe_program_handle_t *loader;
187 
188  /* load emulated loader from the filesystem */
189  loader = emulated_loader_program();
190 
191  if (!loader)
192  return -1;
193 
194  rc = _base_spe_load_spe_elf(loader, spe->base_private->mem_mmap_base, ld_info);
195  if (rc != 0) {
196  DEBUG_PRINTF("%s: No loader available\n", __FUNCTION__);
197  return rc;
198  }
199 
200  return spe_start_isolated_app(spe, handle);
201 }
202 
204 {
205  int rc = 0;
206  struct spe_ld_info ld_info;
207 
208  spe->base_private->loaded_program = program;
209 
210  if (spe->base_private->flags & SPE_ISOLATE) {
211  rc = spe_start_isolated_app(spe, program);
212 
213  } else if (spe->base_private->flags & SPE_ISOLATE_EMULATE) {
214  rc = spe_start_emulated_isolated_app(spe, program, &ld_info);
215 
216  } else {
217  rc = _base_spe_load_spe_elf(program,
218  spe->base_private->mem_mmap_base, &ld_info);
219  if (!rc)
221  }
222 
223  if (rc != 0) {
224  DEBUG_PRINTF ("Load SPE ELF failed..\n");
225  return -1;
226  }
227 
228  spe->base_private->entry = ld_info.entry;
229  spe->base_private->emulated_entry = ld_info.entry;
230 
231  return 0;
232 }
#define DEBUG_PRINTF(fmt, args...)
Definition: elf_loader.c:45
int _base_spe_emulated_loader_present(void)
Definition: load.c:159
#define SPE_EMULATED_LOADER_FILE
Definition: load.c:31
spe_program_handle_t * loaded_program
Definition: spebase.h:99
int _base_spe_open_if_closed(struct spe_context *spe, enum fd_name fdesc, int locked)
Definition: create.c:101
int _base_spe_load_spe_elf(spe_program_handle_t *handle, void *ld_buffer, struct spe_ld_info *ld_info)
Definition: elf_loader.c:201
int _base_spe_verify_spe_elf_image(spe_program_handle_t *handle)
Definition: elf_loader.c:99
int _base_spe_parse_isolated_elf(spe_program_handle_t *handle, uint64_t *addr, uint32_t *size)
Definition: elf_loader.c:111
unsigned int entry
Definition: elf_loader.h:36
spe_program_handle_t * _base_spe_image_open(const char *filename)
Definition: image.c:37
void __spe_context_update_event(void)
struct spe_context_base_priv * base_private
Definition: libspe2-types.h:76
int _base_spe_program_load(spe_context_ptr_t spe, spe_program_handle_t *program)
Definition: load.c:203
#define SPE_ISOLATE_EMULATE
unsigned int flags
Definition: spebase.h:74
#define SPE_ISOLATE
void * mem_mmap_base
Definition: spebase.h:85
void _base_spe_program_load_complete(spe_context_ptr_t spectx)
Definition: load.c:38