4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * This module implements DSP code management for the DSP/BIOS Bridge
7 * environment. It is mostly a thin wrapper.
9 * This module provides an interface for loading both static and
10 * dynamic code objects onto DSP systems.
12 * Copyright (C) 2005-2006 Texas Instruments, Inc.
14 * This package is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
18 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 #include <linux/types.h>
25 /* ----------------------------------- Host OS */
26 #include <dspbridge/host_os.h>
28 #include <linux/uaccess.h>
30 /* ----------------------------------- DSP/BIOS Bridge */
31 #include <dspbridge/dbdefs.h>
33 /* ----------------------------------- Trace & Debug */
34 #include <dspbridge/dbc.h>
36 /* ----------------------------------- OS Adaptation Layer */
37 #include <dspbridge/ldr.h>
39 /* ----------------------------------- Platform Manager */
40 /* Include appropriate loader header file */
41 #include <dspbridge/dbll.h>
43 /* ----------------------------------- This */
44 #include <dspbridge/cod.h>
47 * ======== cod_manager ========
50 struct dbll_tar_obj *target;
51 struct dbll_library_obj *base_lib;
52 bool loaded; /* Base library loaded? */
54 struct ldr_module *dll_obj;
55 struct dbll_fxns fxns;
56 struct dbll_attrs attrs;
57 char sz_zl_file[COD_MAXPATHLENGTH];
61 * ======== cod_libraryobj ========
63 struct cod_libraryobj {
64 struct dbll_library_obj *dbll_lib;
65 struct cod_manager *cod_mgr;
70 static struct dbll_fxns ldr_fxns = {
71 (dbll_close_fxn) dbll_close,
72 (dbll_create_fxn) dbll_create,
73 (dbll_delete_fxn) dbll_delete,
74 (dbll_exit_fxn) dbll_exit,
75 (dbll_get_attrs_fxn) dbll_get_attrs,
76 (dbll_get_addr_fxn) dbll_get_addr,
77 (dbll_get_c_addr_fxn) dbll_get_c_addr,
78 (dbll_get_sect_fxn) dbll_get_sect,
79 (dbll_init_fxn) dbll_init,
80 (dbll_load_fxn) dbll_load,
81 (dbll_load_sect_fxn) dbll_load_sect,
82 (dbll_open_fxn) dbll_open,
83 (dbll_read_sect_fxn) dbll_read_sect,
84 (dbll_set_attrs_fxn) dbll_set_attrs,
85 (dbll_unload_fxn) dbll_unload,
86 (dbll_unload_sect_fxn) dbll_unload_sect,
89 static bool no_op(void);
92 * File operations (originally were under kfile.c)
94 static s32 cod_f_close(struct file *filp)
96 /* Check for valid handle */
100 filp_close(filp, NULL);
102 /* we can't use 0 here */
106 static struct file *cod_f_open(const char *psz_file_name, const char *sz_mode)
114 /* ignore given mode and open file as read-only */
115 filp = filp_open(psz_file_name, O_RDONLY, 0);
125 static s32 cod_f_read(void __user *pbuffer, s32 size, s32 count,
128 /* check for valid file handle */
132 if ((size > 0) && (count > 0) && pbuffer) {
139 dw_bytes_read = filp->f_op->read(filp, pbuffer, size * count,
146 return dw_bytes_read / size;
152 static s32 cod_f_seek(struct file *filp, s32 offset, s32 origin)
156 /* check for valid file handle */
160 /* based on the origin flag, move the internal pointer */
161 dw_cur_pos = filp->f_op->llseek(filp, offset, origin);
163 if ((s32) dw_cur_pos < 0)
166 /* we can't use 0 here */
170 static s32 cod_f_tell(struct file *filp)
177 /* Get current position */
178 dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR);
180 if ((s32) dw_cur_pos < 0)
187 * ======== cod_close ========
189 void cod_close(struct cod_libraryobj *lib)
191 struct cod_manager *hmgr;
193 DBC_REQUIRE(refs > 0);
194 DBC_REQUIRE(lib != NULL);
195 DBC_REQUIRE(lib->cod_mgr);
198 hmgr->fxns.close_fxn(lib->dbll_lib);
204 * ======== cod_create ========
206 * Create an object to manage code on a DSP system.
207 * This object can be used to load an initial program image with
208 * arguments that can later be expanded with
209 * dynamically loaded object files.
212 int cod_create(struct cod_manager **mgr, char *str_zl_file,
213 const struct cod_attrs *attrs)
215 struct cod_manager *mgr_new;
216 struct dbll_attrs zl_attrs;
219 DBC_REQUIRE(refs > 0);
220 DBC_REQUIRE(mgr != NULL);
225 /* we don't support non-default attrs yet */
229 mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL);
233 /* Set up loader functions */
234 mgr_new->fxns = ldr_fxns;
236 /* initialize the ZL module */
237 mgr_new->fxns.init_fxn();
239 zl_attrs.alloc = (dbll_alloc_fxn) no_op;
240 zl_attrs.free = (dbll_free_fxn) no_op;
241 zl_attrs.fread = (dbll_read_fxn) cod_f_read;
242 zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek;
243 zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell;
244 zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close;
245 zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open;
246 zl_attrs.sym_lookup = NULL;
247 zl_attrs.base_image = true;
248 zl_attrs.log_write = NULL;
249 zl_attrs.log_write_handle = NULL;
250 zl_attrs.write = NULL;
251 zl_attrs.rmm_handle = NULL;
252 zl_attrs.input_params = NULL;
253 zl_attrs.sym_handle = NULL;
254 zl_attrs.sym_arg = NULL;
256 mgr_new->attrs = zl_attrs;
258 status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs);
265 /* return the new manager */
272 * ======== cod_delete ========
274 * Delete a code manager object.
276 void cod_delete(struct cod_manager *cod_mgr_obj)
278 DBC_REQUIRE(refs > 0);
279 DBC_REQUIRE(cod_mgr_obj);
281 if (cod_mgr_obj->base_lib) {
282 if (cod_mgr_obj->loaded)
283 cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib,
284 &cod_mgr_obj->attrs);
286 cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
288 if (cod_mgr_obj->target) {
289 cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target);
290 cod_mgr_obj->fxns.exit_fxn();
296 * ======== cod_exit ========
298 * Discontinue usage of the COD module.
303 DBC_REQUIRE(refs > 0);
307 DBC_ENSURE(refs >= 0);
311 * ======== cod_get_base_lib ========
313 * Get handle to the base image DBL library.
315 int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
316 struct dbll_library_obj **plib)
320 DBC_REQUIRE(refs > 0);
321 DBC_REQUIRE(cod_mgr_obj);
322 DBC_REQUIRE(plib != NULL);
324 *plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;
330 * ======== cod_get_base_name ========
332 int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
337 DBC_REQUIRE(refs > 0);
338 DBC_REQUIRE(cod_mgr_obj);
339 DBC_REQUIRE(sz_name != NULL);
341 if (usize <= COD_MAXPATHLENGTH)
342 strncpy(sz_name, cod_mgr_obj->sz_zl_file, usize);
350 * ======== cod_get_entry ========
352 * Retrieve the entry point of a loaded DSP program image
355 int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt)
357 DBC_REQUIRE(refs > 0);
358 DBC_REQUIRE(cod_mgr_obj);
359 DBC_REQUIRE(entry_pt != NULL);
361 *entry_pt = cod_mgr_obj->ul_entry;
367 * ======== cod_get_loader ========
369 * Get handle to the DBLL loader.
371 int cod_get_loader(struct cod_manager *cod_mgr_obj,
372 struct dbll_tar_obj **loader)
376 DBC_REQUIRE(refs > 0);
377 DBC_REQUIRE(cod_mgr_obj);
378 DBC_REQUIRE(loader != NULL);
380 *loader = (struct dbll_tar_obj *)cod_mgr_obj->target;
386 * ======== cod_get_section ========
388 * Retrieve the starting address and length of a section in the COFF file
389 * given the section name.
391 int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
394 struct cod_manager *cod_mgr_obj;
397 DBC_REQUIRE(refs > 0);
398 DBC_REQUIRE(lib != NULL);
399 DBC_REQUIRE(lib->cod_mgr);
400 DBC_REQUIRE(str_sect != NULL);
401 DBC_REQUIRE(addr != NULL);
402 DBC_REQUIRE(len != NULL);
407 cod_mgr_obj = lib->cod_mgr;
408 status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect,
414 DBC_ENSURE(!status || ((*addr == 0) && (*len == 0)));
420 * ======== cod_get_sym_value ========
422 * Retrieve the value for the specified symbol. The symbol is first
423 * searched for literally and then, if not found, searched for as a
427 int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym,
430 struct dbll_sym_val *dbll_sym;
432 DBC_REQUIRE(refs > 0);
433 DBC_REQUIRE(cod_mgr_obj);
434 DBC_REQUIRE(str_sym != NULL);
435 DBC_REQUIRE(pul_value != NULL);
437 dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n",
438 __func__, cod_mgr_obj, str_sym, pul_value);
439 if (cod_mgr_obj->base_lib) {
440 if (!cod_mgr_obj->fxns.
441 get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) {
442 if (!cod_mgr_obj->fxns.
443 get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym,
451 *pul_value = dbll_sym->value;
457 * ======== cod_init ========
459 * Initialize the COD module's private state.
466 DBC_REQUIRE(refs >= 0);
471 DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0));
476 * ======== cod_load_base ========
478 * Load the initial program image, optionally with command-line arguments,
479 * on the DSP system managed by the supplied handle. The program to be
480 * loaded must be the first element of the args array and must be a fully
481 * qualified pathname.
483 * if num_argc doesn't match the number of arguments in the args array, the
484 * args array is searched for a NULL terminating entry, and argc is
485 * recalculated to reflect this. In this way, we can support NULL
486 * terminating args arrays, if num_argc is very large.
488 int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[],
489 cod_writefxn pfn_write, void *arb, char *envp[])
492 struct dbll_attrs save_attrs;
493 struct dbll_attrs new_attrs;
497 DBC_REQUIRE(refs > 0);
498 DBC_REQUIRE(cod_mgr_obj);
499 DBC_REQUIRE(num_argc > 0);
500 DBC_REQUIRE(args != NULL);
501 DBC_REQUIRE(args[0] != NULL);
502 DBC_REQUIRE(pfn_write != NULL);
503 DBC_REQUIRE(cod_mgr_obj->base_lib != NULL);
506 * Make sure every argv[] stated in argc has a value, or change argc to
507 * reflect true number in NULL terminated argv array.
509 for (i = 0; i < num_argc; i++) {
510 if (args[i] == NULL) {
516 /* set the write function for this operation */
517 cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs);
519 new_attrs = save_attrs;
520 new_attrs.write = (dbll_write_fxn) pfn_write;
521 new_attrs.input_params = arb;
522 new_attrs.alloc = (dbll_alloc_fxn) no_op;
523 new_attrs.free = (dbll_free_fxn) no_op;
524 new_attrs.log_write = NULL;
525 new_attrs.log_write_handle = NULL;
528 flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
529 status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags,
531 &cod_mgr_obj->ul_entry);
533 cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
536 cod_mgr_obj->loaded = true;
538 cod_mgr_obj->base_lib = NULL;
544 * ======== cod_open ========
545 * Open library for reading sections.
547 int cod_open(struct cod_manager *hmgr, char *sz_coff_path,
548 u32 flags, struct cod_libraryobj **lib_obj)
551 struct cod_libraryobj *lib = NULL;
553 DBC_REQUIRE(refs > 0);
555 DBC_REQUIRE(sz_coff_path != NULL);
556 DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB);
557 DBC_REQUIRE(lib_obj != NULL);
561 lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
567 status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags,
574 pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n",
575 __func__, status, sz_coff_path, flags);
580 * ======== cod_open_base ========
582 * Open base image for reading sections.
584 int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
588 struct dbll_library_obj *lib;
590 DBC_REQUIRE(refs > 0);
592 DBC_REQUIRE(sz_coff_path != NULL);
594 /* if we previously opened a base image, close it now */
595 if (hmgr->base_lib) {
597 hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
598 hmgr->loaded = false;
600 hmgr->fxns.close_fxn(hmgr->base_lib);
601 hmgr->base_lib = NULL;
603 status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, &lib);
605 /* hang onto the library for subsequent sym table usage */
606 hmgr->base_lib = lib;
607 strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1);
608 hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0';
612 pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__,
613 status, sz_coff_path);
618 * ======== cod_read_section ========
620 * Retrieve the content of a code section given the section name.
622 int cod_read_section(struct cod_libraryobj *lib, char *str_sect,
623 char *str_content, u32 content_size)
627 DBC_REQUIRE(refs > 0);
628 DBC_REQUIRE(lib != NULL);
629 DBC_REQUIRE(lib->cod_mgr);
630 DBC_REQUIRE(str_sect != NULL);
631 DBC_REQUIRE(str_content != NULL);
635 lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect,
636 str_content, content_size);
644 * ======== no_op ========
649 static bool no_op(void)