mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 15:28:50 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
80
drivers/scsi/aic7xxx/aicasm/Makefile
Normal file
80
drivers/scsi/aic7xxx/aicasm/Makefile
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
PROG= aicasm
|
||||
|
||||
.SUFFIXES= .l .y .c .h
|
||||
|
||||
CSRCS= aicasm.c aicasm_symbol.c
|
||||
YSRCS= aicasm_gram.y aicasm_macro_gram.y
|
||||
LSRCS= aicasm_scan.l aicasm_macro_scan.l
|
||||
|
||||
GENHDRS= aicdb.h $(YSRCS:.y=.h)
|
||||
GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c)
|
||||
|
||||
SRCS= ${CSRCS} ${GENSRCS}
|
||||
LIBS= -ldb
|
||||
clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)
|
||||
# Override default kernel CFLAGS. This is a userland app.
|
||||
AICASM_CFLAGS:= -I/usr/include -I.
|
||||
LEX= flex
|
||||
YACC= bison
|
||||
YFLAGS= -d
|
||||
|
||||
NOMAN= noman
|
||||
|
||||
ifneq ($(HOSTCC),)
|
||||
AICASM_CC= $(HOSTCC)
|
||||
else
|
||||
AICASM_CC= $(CC)
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS+= -DDEBUG -g
|
||||
YFLAGS+= -t -v
|
||||
LFLAGS= -d
|
||||
endif
|
||||
|
||||
$(PROG): ${GENHDRS} $(SRCS)
|
||||
$(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) $(LIBS)
|
||||
|
||||
aicdb.h:
|
||||
@if [ -e "/usr/include/db4/db_185.h" ]; then \
|
||||
echo "#include <db4/db_185.h>" > aicdb.h; \
|
||||
elif [ -e "/usr/include/db3/db_185.h" ]; then \
|
||||
echo "#include <db3/db_185.h>" > aicdb.h; \
|
||||
elif [ -e "/usr/include/db2/db_185.h" ]; then \
|
||||
echo "#include <db2/db_185.h>" > aicdb.h; \
|
||||
elif [ -e "/usr/include/db1/db_185.h" ]; then \
|
||||
echo "#include <db1/db_185.h>" > aicdb.h; \
|
||||
elif [ -e "/usr/include/db/db_185.h" ]; then \
|
||||
echo "#include <db/db_185.h>" > aicdb.h; \
|
||||
elif [ -e "/usr/include/db_185.h" ]; then \
|
||||
echo "#include <db_185.h>" > aicdb.h; \
|
||||
else \
|
||||
echo "*** Install db development libraries"; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -f $(clean-files)
|
||||
|
||||
# Create a dependency chain in generated files
|
||||
# to avoid concurrent invocations of the single
|
||||
# rule that builds them all.
|
||||
aicasm_gram.c: aicasm_gram.h
|
||||
aicasm_gram.c aicasm_gram.h: aicasm_gram.y
|
||||
$(YACC) $(YFLAGS) -b $(<:.y=) $<
|
||||
mv $(<:.y=).tab.c $(<:.y=.c)
|
||||
mv $(<:.y=).tab.h $(<:.y=.h)
|
||||
|
||||
# Create a dependency chain in generated files
|
||||
# to avoid concurrent invocations of the single
|
||||
# rule that builds them all.
|
||||
aicasm_macro_gram.c: aicasm_macro_gram.h
|
||||
aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
|
||||
$(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
|
||||
mv $(<:.y=).tab.c $(<:.y=.c)
|
||||
mv $(<:.y=).tab.h $(<:.y=.h)
|
||||
|
||||
aicasm_scan.c: aicasm_scan.l
|
||||
$(LEX) $(LFLAGS) -o$@ $<
|
||||
|
||||
aicasm_macro_scan.c: aicasm_macro_scan.l
|
||||
$(LEX) $(LFLAGS) -Pmm -o$@ $<
|
||||
844
drivers/scsi/aic7xxx/aicasm/aicasm.c
Normal file
844
drivers/scsi/aic7xxx/aicasm/aicasm.c
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
/*
|
||||
* Aic7xxx SCSI host adapter firmware assembler
|
||||
*
|
||||
* Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.
|
||||
* Copyright (c) 2001, 2002 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if linux
|
||||
#include <endian.h>
|
||||
#else
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#include "aicasm.h"
|
||||
#include "aicasm_symbol.h"
|
||||
#include "aicasm_insformat.h"
|
||||
|
||||
typedef struct patch {
|
||||
STAILQ_ENTRY(patch) links;
|
||||
int patch_func;
|
||||
u_int begin;
|
||||
u_int skip_instr;
|
||||
u_int skip_patch;
|
||||
} patch_t;
|
||||
|
||||
STAILQ_HEAD(patch_list, patch) patches;
|
||||
|
||||
static void usage(void);
|
||||
static void back_patch(void);
|
||||
static void output_code(void);
|
||||
static void output_listing(char *ifilename);
|
||||
static void dump_scope(scope_t *scope);
|
||||
static void emit_patch(scope_t *scope, int patch);
|
||||
static int check_patch(patch_t **start_patch, int start_instr,
|
||||
int *skip_addr, int *func_vals);
|
||||
|
||||
struct path_list search_path;
|
||||
int includes_search_curdir;
|
||||
char *appname;
|
||||
char *stock_include_file;
|
||||
FILE *ofile;
|
||||
char *ofilename;
|
||||
char *regfilename;
|
||||
FILE *regfile;
|
||||
char *listfilename;
|
||||
FILE *listfile;
|
||||
char *regdiagfilename;
|
||||
FILE *regdiagfile;
|
||||
int src_mode;
|
||||
int dst_mode;
|
||||
|
||||
static STAILQ_HEAD(,instruction) seq_program;
|
||||
struct cs_tailq cs_tailq;
|
||||
struct scope_list scope_stack;
|
||||
symlist_t patch_functions;
|
||||
|
||||
#if DEBUG
|
||||
extern int yy_flex_debug;
|
||||
extern int mm_flex_debug;
|
||||
extern int yydebug;
|
||||
extern int mmdebug;
|
||||
#endif
|
||||
extern FILE *yyin;
|
||||
extern int yyparse(void);
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int ch;
|
||||
int retval;
|
||||
char *inputfilename;
|
||||
scope_t *sentinal;
|
||||
|
||||
STAILQ_INIT(&patches);
|
||||
SLIST_INIT(&search_path);
|
||||
STAILQ_INIT(&seq_program);
|
||||
TAILQ_INIT(&cs_tailq);
|
||||
SLIST_INIT(&scope_stack);
|
||||
|
||||
/* Set Sentinal scope node */
|
||||
sentinal = scope_alloc();
|
||||
sentinal->type = SCOPE_ROOT;
|
||||
|
||||
includes_search_curdir = 1;
|
||||
appname = *argv;
|
||||
regfile = NULL;
|
||||
listfile = NULL;
|
||||
#if DEBUG
|
||||
yy_flex_debug = 0;
|
||||
mm_flex_debug = 0;
|
||||
yydebug = 0;
|
||||
mmdebug = 0;
|
||||
#endif
|
||||
while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) {
|
||||
switch(ch) {
|
||||
case 'd':
|
||||
#if DEBUG
|
||||
if (strcmp(optarg, "s") == 0) {
|
||||
yy_flex_debug = 1;
|
||||
mm_flex_debug = 1;
|
||||
} else if (strcmp(optarg, "p") == 0) {
|
||||
yydebug = 1;
|
||||
mmdebug = 1;
|
||||
} else {
|
||||
fprintf(stderr, "%s: -d Requires either an "
|
||||
"'s' or 'p' argument\n", appname);
|
||||
usage();
|
||||
}
|
||||
#else
|
||||
stop("-d: Assembler not built with debugging "
|
||||
"information", EX_SOFTWARE);
|
||||
#endif
|
||||
break;
|
||||
case 'i':
|
||||
stock_include_file = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
/* Create a program listing */
|
||||
if ((listfile = fopen(optarg, "w")) == NULL) {
|
||||
perror(optarg);
|
||||
stop(NULL, EX_CANTCREAT);
|
||||
}
|
||||
listfilename = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
/* Don't complain about the -nostdinc directrive */
|
||||
if (strcmp(optarg, "ostdinc")) {
|
||||
fprintf(stderr, "%s: Unknown option -%c%s\n",
|
||||
appname, ch, optarg);
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if ((ofile = fopen(optarg, "w")) == NULL) {
|
||||
perror(optarg);
|
||||
stop(NULL, EX_CANTCREAT);
|
||||
}
|
||||
ofilename = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
/* Create Register Diagnostic "printing" Functions */
|
||||
if ((regdiagfile = fopen(optarg, "w")) == NULL) {
|
||||
perror(optarg);
|
||||
stop(NULL, EX_CANTCREAT);
|
||||
}
|
||||
regdiagfilename = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
if ((regfile = fopen(optarg, "w")) == NULL) {
|
||||
perror(optarg);
|
||||
stop(NULL, EX_CANTCREAT);
|
||||
}
|
||||
regfilename = optarg;
|
||||
break;
|
||||
case 'I':
|
||||
{
|
||||
path_entry_t include_dir;
|
||||
|
||||
if (strcmp(optarg, "-") == 0) {
|
||||
if (includes_search_curdir == 0) {
|
||||
fprintf(stderr, "%s: Warning - '-I-' "
|
||||
"specified multiple "
|
||||
"times\n", appname);
|
||||
}
|
||||
includes_search_curdir = 0;
|
||||
for (include_dir = SLIST_FIRST(&search_path);
|
||||
include_dir != NULL;
|
||||
include_dir = SLIST_NEXT(include_dir,
|
||||
links))
|
||||
/*
|
||||
* All entries before a '-I-' only
|
||||
* apply to includes specified with
|
||||
* quotes instead of "<>".
|
||||
*/
|
||||
include_dir->quoted_includes_only = 1;
|
||||
} else {
|
||||
include_dir =
|
||||
(path_entry_t)malloc(sizeof(*include_dir));
|
||||
if (include_dir == NULL) {
|
||||
perror(optarg);
|
||||
stop(NULL, EX_OSERR);
|
||||
}
|
||||
include_dir->directory = strdup(optarg);
|
||||
if (include_dir->directory == NULL) {
|
||||
perror(optarg);
|
||||
stop(NULL, EX_OSERR);
|
||||
}
|
||||
include_dir->quoted_includes_only = 0;
|
||||
SLIST_INSERT_HEAD(&search_path, include_dir,
|
||||
links);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1) {
|
||||
fprintf(stderr, "%s: No input file specifiled\n", appname);
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (regdiagfile != NULL
|
||||
&& (regfile == NULL || stock_include_file == NULL)) {
|
||||
fprintf(stderr,
|
||||
"%s: The -p option requires the -r and -i options.\n",
|
||||
appname);
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
symtable_open();
|
||||
inputfilename = *argv;
|
||||
include_file(*argv, SOURCE_FILE);
|
||||
retval = yyparse();
|
||||
if (retval == 0) {
|
||||
if (SLIST_FIRST(&scope_stack) == NULL
|
||||
|| SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) {
|
||||
stop("Unterminated conditional expression", EX_DATAERR);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Process outmost scope */
|
||||
process_scope(SLIST_FIRST(&scope_stack));
|
||||
/*
|
||||
* Decend the tree of scopes and insert/emit
|
||||
* patches as appropriate. We perform a depth first
|
||||
* tranversal, recursively handling each scope.
|
||||
*/
|
||||
/* start at the root scope */
|
||||
dump_scope(SLIST_FIRST(&scope_stack));
|
||||
|
||||
/* Patch up forward jump addresses */
|
||||
back_patch();
|
||||
|
||||
if (ofile != NULL)
|
||||
output_code();
|
||||
if (regfile != NULL)
|
||||
symtable_dump(regfile, regdiagfile);
|
||||
if (listfile != NULL)
|
||||
output_listing(inputfilename);
|
||||
}
|
||||
|
||||
stop(NULL, 0);
|
||||
/* NOTREACHED */
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"
|
||||
" [-r register_output_file [-p register_diag_file -i includefile]]\n"
|
||||
" [-l program_list_file]\n"
|
||||
" input_file\n", appname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
static void
|
||||
back_patch()
|
||||
{
|
||||
struct instruction *cur_instr;
|
||||
|
||||
for (cur_instr = STAILQ_FIRST(&seq_program);
|
||||
cur_instr != NULL;
|
||||
cur_instr = STAILQ_NEXT(cur_instr, links)) {
|
||||
if (cur_instr->patch_label != NULL) {
|
||||
struct ins_format3 *f3_instr;
|
||||
u_int address;
|
||||
|
||||
if (cur_instr->patch_label->type != LABEL) {
|
||||
char buf[255];
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"Undefined label %s",
|
||||
cur_instr->patch_label->name);
|
||||
stop(buf, EX_DATAERR);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
f3_instr = &cur_instr->format.format3;
|
||||
address = f3_instr->address;
|
||||
address += cur_instr->patch_label->info.linfo->address;
|
||||
f3_instr->address = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_code()
|
||||
{
|
||||
struct instruction *cur_instr;
|
||||
patch_t *cur_patch;
|
||||
critical_section_t *cs;
|
||||
symbol_node_t *cur_node;
|
||||
int instrcount;
|
||||
|
||||
instrcount = 0;
|
||||
fprintf(ofile,
|
||||
"/*\n"
|
||||
" * DO NOT EDIT - This file is automatically generated\n"
|
||||
" * from the following source files:\n"
|
||||
" *\n"
|
||||
"%s */\n", versions);
|
||||
|
||||
fprintf(ofile, "static const uint8_t seqprog[] = {\n");
|
||||
for (cur_instr = STAILQ_FIRST(&seq_program);
|
||||
cur_instr != NULL;
|
||||
cur_instr = STAILQ_NEXT(cur_instr, links)) {
|
||||
|
||||
fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
|
||||
cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
cur_instr->format.bytes[0],
|
||||
cur_instr->format.bytes[1],
|
||||
cur_instr->format.bytes[2],
|
||||
cur_instr->format.bytes[3]);
|
||||
#else
|
||||
cur_instr->format.bytes[3],
|
||||
cur_instr->format.bytes[2],
|
||||
cur_instr->format.bytes[1],
|
||||
cur_instr->format.bytes[0]);
|
||||
#endif
|
||||
instrcount++;
|
||||
}
|
||||
fprintf(ofile, "\n};\n\n");
|
||||
|
||||
if (patch_arg_list == NULL)
|
||||
stop("Patch argument list not defined",
|
||||
EX_DATAERR);
|
||||
|
||||
/*
|
||||
* Output patch information. Patch functions first.
|
||||
*/
|
||||
fprintf(ofile,
|
||||
"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list);
|
||||
|
||||
for (cur_node = SLIST_FIRST(&patch_functions);
|
||||
cur_node != NULL;
|
||||
cur_node = SLIST_NEXT(cur_node,links)) {
|
||||
fprintf(ofile,
|
||||
"static %spatch_func_t %spatch%d_func;\n"
|
||||
"\n"
|
||||
"static int\n"
|
||||
"%spatch%d_func(%s)\n"
|
||||
"{\n"
|
||||
" return (%s);\n"
|
||||
"}\n\n",
|
||||
prefix,
|
||||
prefix,
|
||||
cur_node->symbol->info.condinfo->func_num,
|
||||
prefix,
|
||||
cur_node->symbol->info.condinfo->func_num,
|
||||
patch_arg_list,
|
||||
cur_node->symbol->name);
|
||||
}
|
||||
|
||||
fprintf(ofile,
|
||||
"static const struct patch {\n"
|
||||
" %spatch_func_t *patch_func;\n"
|
||||
" uint32_t begin :10,\n"
|
||||
" skip_instr :10,\n"
|
||||
" skip_patch :12;\n"
|
||||
"} patches[] = {\n", prefix);
|
||||
|
||||
for (cur_patch = STAILQ_FIRST(&patches);
|
||||
cur_patch != NULL;
|
||||
cur_patch = STAILQ_NEXT(cur_patch,links)) {
|
||||
fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }",
|
||||
cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",
|
||||
prefix,
|
||||
cur_patch->patch_func, cur_patch->begin,
|
||||
cur_patch->skip_instr, cur_patch->skip_patch);
|
||||
}
|
||||
|
||||
fprintf(ofile, "\n};\n\n");
|
||||
|
||||
fprintf(ofile,
|
||||
"static const struct cs {\n"
|
||||
" uint16_t begin;\n"
|
||||
" uint16_t end;\n"
|
||||
"} critical_sections[] = {\n");
|
||||
|
||||
for (cs = TAILQ_FIRST(&cs_tailq);
|
||||
cs != NULL;
|
||||
cs = TAILQ_NEXT(cs, links)) {
|
||||
fprintf(ofile, "%s\t{ %d, %d }",
|
||||
cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",
|
||||
cs->begin_addr, cs->end_addr);
|
||||
}
|
||||
|
||||
fprintf(ofile, "\n};\n\n");
|
||||
|
||||
fprintf(ofile,
|
||||
"static const int num_critical_sections = sizeof(critical_sections)\n"
|
||||
" / sizeof(*critical_sections);\n");
|
||||
|
||||
fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_scope(scope_t *scope)
|
||||
{
|
||||
scope_t *cur_scope;
|
||||
|
||||
/*
|
||||
* Emit the first patch for this scope
|
||||
*/
|
||||
emit_patch(scope, 0);
|
||||
|
||||
/*
|
||||
* Dump each scope within this one.
|
||||
*/
|
||||
cur_scope = TAILQ_FIRST(&scope->inner_scope);
|
||||
|
||||
while (cur_scope != NULL) {
|
||||
|
||||
dump_scope(cur_scope);
|
||||
|
||||
cur_scope = TAILQ_NEXT(cur_scope, scope_links);
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit the second, closing, patch for this scope
|
||||
*/
|
||||
emit_patch(scope, 1);
|
||||
}
|
||||
|
||||
void
|
||||
emit_patch(scope_t *scope, int patch)
|
||||
{
|
||||
patch_info_t *pinfo;
|
||||
patch_t *new_patch;
|
||||
|
||||
pinfo = &scope->patches[patch];
|
||||
|
||||
if (pinfo->skip_instr == 0)
|
||||
/* No-Op patch */
|
||||
return;
|
||||
|
||||
new_patch = (patch_t *)malloc(sizeof(*new_patch));
|
||||
|
||||
if (new_patch == NULL)
|
||||
stop("Could not malloc patch structure", EX_OSERR);
|
||||
|
||||
memset(new_patch, 0, sizeof(*new_patch));
|
||||
|
||||
if (patch == 0) {
|
||||
new_patch->patch_func = scope->func_num;
|
||||
new_patch->begin = scope->begin_addr;
|
||||
} else {
|
||||
new_patch->patch_func = 0;
|
||||
new_patch->begin = scope->end_addr;
|
||||
}
|
||||
new_patch->skip_instr = pinfo->skip_instr;
|
||||
new_patch->skip_patch = pinfo->skip_patch;
|
||||
STAILQ_INSERT_TAIL(&patches, new_patch, links);
|
||||
}
|
||||
|
||||
void
|
||||
output_listing(char *ifilename)
|
||||
{
|
||||
char buf[1024];
|
||||
FILE *ifile;
|
||||
struct instruction *cur_instr;
|
||||
patch_t *cur_patch;
|
||||
symbol_node_t *cur_func;
|
||||
int *func_values;
|
||||
int instrcount;
|
||||
int instrptr;
|
||||
int line;
|
||||
int func_count;
|
||||
int skip_addr;
|
||||
|
||||
instrcount = 0;
|
||||
instrptr = 0;
|
||||
line = 1;
|
||||
skip_addr = 0;
|
||||
if ((ifile = fopen(ifilename, "r")) == NULL) {
|
||||
perror(ifilename);
|
||||
stop(NULL, EX_DATAERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which options to apply to this listing.
|
||||
*/
|
||||
for (func_count = 0, cur_func = SLIST_FIRST(&patch_functions);
|
||||
cur_func != NULL;
|
||||
cur_func = SLIST_NEXT(cur_func, links))
|
||||
func_count++;
|
||||
|
||||
func_values = NULL;
|
||||
if (func_count != 0) {
|
||||
func_values = (int *)malloc(func_count * sizeof(int));
|
||||
|
||||
if (func_values == NULL)
|
||||
stop("Could not malloc", EX_OSERR);
|
||||
|
||||
func_values[0] = 0; /* FALSE func */
|
||||
func_count--;
|
||||
|
||||
/*
|
||||
* Ask the user to fill in the return values for
|
||||
* the rest of the functions.
|
||||
*/
|
||||
|
||||
|
||||
for (cur_func = SLIST_FIRST(&patch_functions);
|
||||
cur_func != NULL && SLIST_NEXT(cur_func, links) != NULL;
|
||||
cur_func = SLIST_NEXT(cur_func, links), func_count--) {
|
||||
int input;
|
||||
|
||||
fprintf(stdout, "\n(%s)\n", cur_func->symbol->name);
|
||||
fprintf(stdout,
|
||||
"Enter the return value for "
|
||||
"this expression[T/F]:");
|
||||
|
||||
while (1) {
|
||||
|
||||
input = getchar();
|
||||
input = toupper(input);
|
||||
|
||||
if (input == 'T') {
|
||||
func_values[func_count] = 1;
|
||||
break;
|
||||
} else if (input == 'F') {
|
||||
func_values[func_count] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isatty(fileno(stdin)) == 0)
|
||||
putchar(input);
|
||||
}
|
||||
fprintf(stdout, "\nThanks!\n");
|
||||
}
|
||||
|
||||
/* Now output the listing */
|
||||
cur_patch = STAILQ_FIRST(&patches);
|
||||
for (cur_instr = STAILQ_FIRST(&seq_program);
|
||||
cur_instr != NULL;
|
||||
cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
|
||||
|
||||
if (check_patch(&cur_patch, instrcount,
|
||||
&skip_addr, func_values) == 0) {
|
||||
/* Don't count this instruction as it is in a patch
|
||||
* that was removed.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
while (line < cur_instr->srcline) {
|
||||
fgets(buf, sizeof(buf), ifile);
|
||||
fprintf(listfile, " \t%s", buf);
|
||||
line++;
|
||||
}
|
||||
fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr,
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
cur_instr->format.bytes[0],
|
||||
cur_instr->format.bytes[1],
|
||||
cur_instr->format.bytes[2],
|
||||
cur_instr->format.bytes[3]);
|
||||
#else
|
||||
cur_instr->format.bytes[3],
|
||||
cur_instr->format.bytes[2],
|
||||
cur_instr->format.bytes[1],
|
||||
cur_instr->format.bytes[0]);
|
||||
#endif
|
||||
/*
|
||||
* Macro expansions can cause several instructions
|
||||
* to be output for a single source line. Only
|
||||
* advance the line once in these cases.
|
||||
*/
|
||||
if (line == cur_instr->srcline) {
|
||||
fgets(buf, sizeof(buf), ifile);
|
||||
fprintf(listfile, "\t%s", buf);
|
||||
line++;
|
||||
} else {
|
||||
fprintf(listfile, "\n");
|
||||
}
|
||||
instrptr++;
|
||||
}
|
||||
/* Dump the remainder of the file */
|
||||
while(fgets(buf, sizeof(buf), ifile) != NULL)
|
||||
fprintf(listfile, " %s", buf);
|
||||
|
||||
fclose(ifile);
|
||||
}
|
||||
|
||||
static int
|
||||
check_patch(patch_t **start_patch, int start_instr,
|
||||
int *skip_addr, int *func_vals)
|
||||
{
|
||||
patch_t *cur_patch;
|
||||
|
||||
cur_patch = *start_patch;
|
||||
|
||||
while (cur_patch != NULL && start_instr == cur_patch->begin) {
|
||||
if (func_vals[cur_patch->patch_func] == 0) {
|
||||
int skip;
|
||||
|
||||
/* Start rejecting code */
|
||||
*skip_addr = start_instr + cur_patch->skip_instr;
|
||||
for (skip = cur_patch->skip_patch;
|
||||
skip > 0 && cur_patch != NULL;
|
||||
skip--)
|
||||
cur_patch = STAILQ_NEXT(cur_patch, links);
|
||||
} else {
|
||||
/* Accepted this patch. Advance to the next
|
||||
* one and wait for our intruction pointer to
|
||||
* hit this point.
|
||||
*/
|
||||
cur_patch = STAILQ_NEXT(cur_patch, links);
|
||||
}
|
||||
}
|
||||
|
||||
*start_patch = cur_patch;
|
||||
if (start_instr < *skip_addr)
|
||||
/* Still skipping */
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out error information if appropriate, and clean up before
|
||||
* terminating the program.
|
||||
*/
|
||||
void
|
||||
stop(const char *string, int err_code)
|
||||
{
|
||||
if (string != NULL) {
|
||||
fprintf(stderr, "%s: ", appname);
|
||||
if (yyfilename != NULL) {
|
||||
fprintf(stderr, "Stopped at file %s, line %d - ",
|
||||
yyfilename, yylineno);
|
||||
}
|
||||
fprintf(stderr, "%s\n", string);
|
||||
}
|
||||
|
||||
if (ofile != NULL) {
|
||||
fclose(ofile);
|
||||
if (err_code != 0) {
|
||||
fprintf(stderr, "%s: Removing %s due to error\n",
|
||||
appname, ofilename);
|
||||
unlink(ofilename);
|
||||
}
|
||||
}
|
||||
|
||||
if (regfile != NULL) {
|
||||
fclose(regfile);
|
||||
if (err_code != 0) {
|
||||
fprintf(stderr, "%s: Removing %s due to error\n",
|
||||
appname, regfilename);
|
||||
unlink(regfilename);
|
||||
}
|
||||
}
|
||||
|
||||
if (listfile != NULL) {
|
||||
fclose(listfile);
|
||||
if (err_code != 0) {
|
||||
fprintf(stderr, "%s: Removing %s due to error\n",
|
||||
appname, listfilename);
|
||||
unlink(listfilename);
|
||||
}
|
||||
}
|
||||
|
||||
symlist_free(&patch_functions);
|
||||
symtable_close();
|
||||
|
||||
exit(err_code);
|
||||
}
|
||||
|
||||
struct instruction *
|
||||
seq_alloc()
|
||||
{
|
||||
struct instruction *new_instr;
|
||||
|
||||
new_instr = (struct instruction *)malloc(sizeof(struct instruction));
|
||||
if (new_instr == NULL)
|
||||
stop("Unable to malloc instruction object", EX_SOFTWARE);
|
||||
memset(new_instr, 0, sizeof(*new_instr));
|
||||
STAILQ_INSERT_TAIL(&seq_program, new_instr, links);
|
||||
new_instr->srcline = yylineno;
|
||||
return new_instr;
|
||||
}
|
||||
|
||||
critical_section_t *
|
||||
cs_alloc()
|
||||
{
|
||||
critical_section_t *new_cs;
|
||||
|
||||
new_cs= (critical_section_t *)malloc(sizeof(critical_section_t));
|
||||
if (new_cs == NULL)
|
||||
stop("Unable to malloc critical_section object", EX_SOFTWARE);
|
||||
memset(new_cs, 0, sizeof(*new_cs));
|
||||
|
||||
TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links);
|
||||
return new_cs;
|
||||
}
|
||||
|
||||
scope_t *
|
||||
scope_alloc()
|
||||
{
|
||||
scope_t *new_scope;
|
||||
|
||||
new_scope = (scope_t *)malloc(sizeof(scope_t));
|
||||
if (new_scope == NULL)
|
||||
stop("Unable to malloc scope object", EX_SOFTWARE);
|
||||
memset(new_scope, 0, sizeof(*new_scope));
|
||||
TAILQ_INIT(&new_scope->inner_scope);
|
||||
|
||||
if (SLIST_FIRST(&scope_stack) != NULL) {
|
||||
TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope,
|
||||
new_scope, scope_links);
|
||||
}
|
||||
/* This patch is now the current scope */
|
||||
SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links);
|
||||
return new_scope;
|
||||
}
|
||||
|
||||
void
|
||||
process_scope(scope_t *scope)
|
||||
{
|
||||
/*
|
||||
* We are "leaving" this scope. We should now have
|
||||
* enough information to process the lists of scopes
|
||||
* we encapsulate.
|
||||
*/
|
||||
scope_t *cur_scope;
|
||||
u_int skip_patch_count;
|
||||
u_int skip_instr_count;
|
||||
|
||||
cur_scope = TAILQ_LAST(&scope->inner_scope, scope_tailq);
|
||||
skip_patch_count = 0;
|
||||
skip_instr_count = 0;
|
||||
while (cur_scope != NULL) {
|
||||
u_int patch0_patch_skip;
|
||||
|
||||
patch0_patch_skip = 0;
|
||||
switch (cur_scope->type) {
|
||||
case SCOPE_IF:
|
||||
case SCOPE_ELSE_IF:
|
||||
if (skip_instr_count != 0) {
|
||||
/* Create a tail patch */
|
||||
patch0_patch_skip++;
|
||||
cur_scope->patches[1].skip_patch =
|
||||
skip_patch_count + 1;
|
||||
cur_scope->patches[1].skip_instr =
|
||||
skip_instr_count;
|
||||
}
|
||||
|
||||
/* Count Head patch */
|
||||
patch0_patch_skip++;
|
||||
|
||||
/* Count any patches contained in our inner scope */
|
||||
patch0_patch_skip += cur_scope->inner_scope_patches;
|
||||
|
||||
cur_scope->patches[0].skip_patch = patch0_patch_skip;
|
||||
cur_scope->patches[0].skip_instr =
|
||||
cur_scope->end_addr - cur_scope->begin_addr;
|
||||
|
||||
skip_instr_count += cur_scope->patches[0].skip_instr;
|
||||
|
||||
skip_patch_count += patch0_patch_skip;
|
||||
if (cur_scope->type == SCOPE_IF) {
|
||||
scope->inner_scope_patches += skip_patch_count;
|
||||
skip_patch_count = 0;
|
||||
skip_instr_count = 0;
|
||||
}
|
||||
break;
|
||||
case SCOPE_ELSE:
|
||||
/* Count any patches contained in our innter scope */
|
||||
skip_patch_count += cur_scope->inner_scope_patches;
|
||||
|
||||
skip_instr_count += cur_scope->end_addr
|
||||
- cur_scope->begin_addr;
|
||||
break;
|
||||
case SCOPE_ROOT:
|
||||
stop("Unexpected scope type encountered", EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
cur_scope = TAILQ_PREV(cur_scope, scope_tailq, scope_links);
|
||||
}
|
||||
}
|
||||
95
drivers/scsi/aic7xxx/aicasm/aicasm.h
Normal file
95
drivers/scsi/aic7xxx/aicasm/aicasm.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters
|
||||
*
|
||||
* Copyright (c) 1997 Justin T. Gibbs.
|
||||
* Copyright (c) 2001, 2002 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#include "../queue.h"
|
||||
#else
|
||||
#include <sys/queue.h>
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
typedef struct path_entry {
|
||||
char *directory;
|
||||
int quoted_includes_only;
|
||||
SLIST_ENTRY(path_entry) links;
|
||||
} *path_entry_t;
|
||||
|
||||
typedef enum {
|
||||
QUOTED_INCLUDE,
|
||||
BRACKETED_INCLUDE,
|
||||
SOURCE_FILE
|
||||
} include_type;
|
||||
|
||||
SLIST_HEAD(path_list, path_entry);
|
||||
|
||||
extern struct path_list search_path;
|
||||
extern struct cs_tailq cs_tailq;
|
||||
extern struct scope_list scope_stack;
|
||||
extern struct symlist patch_functions;
|
||||
extern int includes_search_curdir; /* False if we've seen -I- */
|
||||
extern char *appname;
|
||||
extern char *stock_include_file;
|
||||
extern int yylineno;
|
||||
extern char *yyfilename;
|
||||
extern char *prefix;
|
||||
extern char *patch_arg_list;
|
||||
extern char *versions;
|
||||
extern int src_mode;
|
||||
extern int dst_mode;
|
||||
struct symbol;
|
||||
|
||||
void stop(const char *errstring, int err_code);
|
||||
void include_file(char *file_name, include_type type);
|
||||
void expand_macro(struct symbol *macro_symbol);
|
||||
struct instruction *seq_alloc(void);
|
||||
struct critical_section *cs_alloc(void);
|
||||
struct scope *scope_alloc(void);
|
||||
void process_scope(struct scope *);
|
||||
2004
drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
Normal file
2004
drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
Normal file
File diff suppressed because it is too large
Load diff
218
drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
Normal file
218
drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Instruction formats for the sequencer program downloaded to
|
||||
* Aic7xxx SCSI host adapters
|
||||
*
|
||||
* Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#12 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
/* 8bit ALU logic operations */
|
||||
struct ins_format1 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
uint32_t immediate : 8,
|
||||
source : 9,
|
||||
destination : 9,
|
||||
ret : 1,
|
||||
opcode : 4,
|
||||
parity : 1;
|
||||
#else
|
||||
uint32_t parity : 1,
|
||||
opcode : 4,
|
||||
ret : 1,
|
||||
destination : 9,
|
||||
source : 9,
|
||||
immediate : 8;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* 8bit ALU shift/rotate operations */
|
||||
struct ins_format2 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
uint32_t shift_control : 8,
|
||||
source : 9,
|
||||
destination : 9,
|
||||
ret : 1,
|
||||
opcode : 4,
|
||||
parity : 1;
|
||||
#else
|
||||
uint32_t parity : 1,
|
||||
opcode : 4,
|
||||
ret : 1,
|
||||
destination : 9,
|
||||
source : 9,
|
||||
shift_control : 8;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* 8bit branch control operations */
|
||||
struct ins_format3 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
uint32_t immediate : 8,
|
||||
source : 9,
|
||||
address : 10,
|
||||
opcode : 4,
|
||||
parity : 1;
|
||||
#else
|
||||
uint32_t parity : 1,
|
||||
opcode : 4,
|
||||
address : 10,
|
||||
source : 9,
|
||||
immediate : 8;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* 16bit ALU logic operations */
|
||||
struct ins_format4 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
uint32_t opcode_ext : 8,
|
||||
source : 9,
|
||||
destination : 9,
|
||||
ret : 1,
|
||||
opcode : 4,
|
||||
parity : 1;
|
||||
#else
|
||||
uint32_t parity : 1,
|
||||
opcode : 4,
|
||||
ret : 1,
|
||||
destination : 9,
|
||||
source : 9,
|
||||
opcode_ext : 8;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* 16bit branch control operations */
|
||||
struct ins_format5 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
uint32_t opcode_ext : 8,
|
||||
source : 9,
|
||||
address : 10,
|
||||
opcode : 4,
|
||||
parity : 1;
|
||||
#else
|
||||
uint32_t parity : 1,
|
||||
opcode : 4,
|
||||
address : 10,
|
||||
source : 9,
|
||||
opcode_ext : 8;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Far branch operations */
|
||||
struct ins_format6 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
uint32_t page : 3,
|
||||
opcode_ext : 5,
|
||||
source : 9,
|
||||
address : 10,
|
||||
opcode : 4,
|
||||
parity : 1;
|
||||
#else
|
||||
uint32_t parity : 1,
|
||||
opcode : 4,
|
||||
address : 10,
|
||||
source : 9,
|
||||
opcode_ext : 5,
|
||||
page : 3;
|
||||
#endif
|
||||
};
|
||||
|
||||
union ins_formats {
|
||||
struct ins_format1 format1;
|
||||
struct ins_format2 format2;
|
||||
struct ins_format3 format3;
|
||||
struct ins_format4 format4;
|
||||
struct ins_format5 format5;
|
||||
struct ins_format6 format6;
|
||||
uint8_t bytes[4];
|
||||
uint32_t integer;
|
||||
};
|
||||
struct instruction {
|
||||
union ins_formats format;
|
||||
u_int srcline;
|
||||
struct symbol *patch_label;
|
||||
STAILQ_ENTRY(instruction) links;
|
||||
};
|
||||
|
||||
#define AIC_OP_OR 0x0
|
||||
#define AIC_OP_AND 0x1
|
||||
#define AIC_OP_XOR 0x2
|
||||
#define AIC_OP_ADD 0x3
|
||||
#define AIC_OP_ADC 0x4
|
||||
#define AIC_OP_ROL 0x5
|
||||
#define AIC_OP_BMOV 0x6
|
||||
|
||||
#define AIC_OP_MVI16 0x7
|
||||
|
||||
#define AIC_OP_JMP 0x8
|
||||
#define AIC_OP_JC 0x9
|
||||
#define AIC_OP_JNC 0xa
|
||||
#define AIC_OP_CALL 0xb
|
||||
#define AIC_OP_JNE 0xc
|
||||
#define AIC_OP_JNZ 0xd
|
||||
#define AIC_OP_JE 0xe
|
||||
#define AIC_OP_JZ 0xf
|
||||
|
||||
/* Pseudo Ops */
|
||||
#define AIC_OP_SHL 0x10
|
||||
#define AIC_OP_SHR 0x20
|
||||
#define AIC_OP_ROR 0x30
|
||||
|
||||
/* 16bit Ops. Low byte main opcode. High byte extended opcode. */
|
||||
#define AIC_OP_OR16 0x8005
|
||||
#define AIC_OP_AND16 0x8105
|
||||
#define AIC_OP_XOR16 0x8205
|
||||
#define AIC_OP_ADD16 0x8305
|
||||
#define AIC_OP_ADC16 0x8405
|
||||
#define AIC_OP_JNE16 0x8805
|
||||
#define AIC_OP_JNZ16 0x8905
|
||||
#define AIC_OP_JE16 0x8C05
|
||||
#define AIC_OP_JZ16 0x8B05
|
||||
#define AIC_OP_JMP16 0x9005
|
||||
#define AIC_OP_JC16 0x9105
|
||||
#define AIC_OP_JNC16 0x9205
|
||||
#define AIC_OP_CALL16 0x9305
|
||||
|
||||
/* Page extension is low three bits of second opcode byte. */
|
||||
#define AIC_OP_JMPF 0xA005
|
||||
#define AIC_OP_CALLF 0xB005
|
||||
#define AIC_OP_JCF 0xC005
|
||||
#define AIC_OP_JNCF 0xD005
|
||||
#define AIC_OP_CMPXCHG 0xE005
|
||||
165
drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
Normal file
165
drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
%{
|
||||
/*
|
||||
* Sub-parser for macro invocation in the Aic7xxx SCSI
|
||||
* Host adapter sequencer assembler.
|
||||
*
|
||||
* Copyright (c) 2001 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include "../queue.h"
|
||||
#else
|
||||
#include <sys/queue.h>
|
||||
#endif
|
||||
|
||||
#include "aicasm.h"
|
||||
#include "aicasm_symbol.h"
|
||||
#include "aicasm_insformat.h"
|
||||
|
||||
static symbol_t *macro_symbol;
|
||||
|
||||
static void add_macro_arg(const char *argtext, int position);
|
||||
void mmerror(const char *string);
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
int value;
|
||||
char *str;
|
||||
symbol_t *sym;
|
||||
}
|
||||
|
||||
|
||||
%token <str> T_ARG
|
||||
|
||||
%token <sym> T_SYMBOL
|
||||
|
||||
%type <value> macro_arglist
|
||||
|
||||
%%
|
||||
|
||||
macrocall:
|
||||
T_SYMBOL '('
|
||||
{
|
||||
macro_symbol = $1;
|
||||
}
|
||||
macro_arglist ')'
|
||||
{
|
||||
if (macro_symbol->info.macroinfo->narg != $4) {
|
||||
printf("Narg == %d", macro_symbol->info.macroinfo->narg);
|
||||
stop("Too few arguments for macro invocation",
|
||||
EX_DATAERR);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
macro_symbol = NULL;
|
||||
YYACCEPT;
|
||||
}
|
||||
;
|
||||
|
||||
macro_arglist:
|
||||
{
|
||||
/* Macros can take 0 arguments */
|
||||
$$ = 0;
|
||||
}
|
||||
| T_ARG
|
||||
{
|
||||
$$ = 1;
|
||||
add_macro_arg($1, 1);
|
||||
}
|
||||
| macro_arglist ',' T_ARG
|
||||
{
|
||||
if ($1 == 0) {
|
||||
stop("Comma without preceding argument in arg list",
|
||||
EX_DATAERR);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
$$ = $1 + 1;
|
||||
add_macro_arg($3, $$);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
static void
|
||||
add_macro_arg(const char *argtext, int argnum)
|
||||
{
|
||||
struct macro_arg *marg;
|
||||
int i;
|
||||
|
||||
if (macro_symbol == NULL || macro_symbol->type != MACRO) {
|
||||
stop("Invalid current symbol for adding macro arg",
|
||||
EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
/*
|
||||
* Macro Invocation. Find the appropriate argument and fill
|
||||
* in the replace ment text for this call.
|
||||
*/
|
||||
i = 0;
|
||||
STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) {
|
||||
i++;
|
||||
if (i == argnum)
|
||||
break;
|
||||
}
|
||||
if (marg == NULL) {
|
||||
stop("Too many arguments for macro invocation", EX_DATAERR);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
marg->replacement_text = strdup(argtext);
|
||||
if (marg->replacement_text == NULL) {
|
||||
stop("Unable to replicate replacement text", EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mmerror(const char *string)
|
||||
{
|
||||
stop(string, EX_DATAERR);
|
||||
}
|
||||
157
drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
Normal file
157
drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
%{
|
||||
/*
|
||||
* Sub-Lexical Analyzer for macro invokation in
|
||||
* the Aic7xxx SCSI Host adapter sequencer assembler.
|
||||
*
|
||||
* Copyright (c) 2001 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#8 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#ifdef __linux__
|
||||
#include "../queue.h"
|
||||
#else
|
||||
#include <sys/queue.h>
|
||||
#endif
|
||||
|
||||
#include "aicasm.h"
|
||||
#include "aicasm_symbol.h"
|
||||
#include "aicasm_macro_gram.h"
|
||||
|
||||
#define MAX_STR_CONST 4096
|
||||
static char string_buf[MAX_STR_CONST];
|
||||
static char *string_buf_ptr;
|
||||
static int parren_count;
|
||||
static char buf[255];
|
||||
int mmlineno;
|
||||
%}
|
||||
|
||||
WORD [A-Za-z_][-A-Za-z_0-9]*
|
||||
SPACE [ \t]+
|
||||
MCARG [^(), \t]+
|
||||
|
||||
%x ARGLIST
|
||||
|
||||
%%
|
||||
\n {
|
||||
++mmlineno;
|
||||
}
|
||||
\r ;
|
||||
<ARGLIST>{SPACE} ;
|
||||
<ARGLIST>\( {
|
||||
parren_count++;
|
||||
if (parren_count == 1) {
|
||||
string_buf_ptr = string_buf;
|
||||
return ('(');
|
||||
}
|
||||
*string_buf_ptr++ = '(';
|
||||
}
|
||||
<ARGLIST>\) {
|
||||
if (parren_count == 1) {
|
||||
if (string_buf_ptr != string_buf) {
|
||||
/*
|
||||
* Return an argument and
|
||||
* rescan this parren so we
|
||||
* can return it as well.
|
||||
*/
|
||||
*string_buf_ptr = '\0';
|
||||
mmlval.str = string_buf;
|
||||
string_buf_ptr = string_buf;
|
||||
unput(')');
|
||||
return T_ARG;
|
||||
}
|
||||
BEGIN INITIAL;
|
||||
return (')');
|
||||
}
|
||||
parren_count--;
|
||||
*string_buf_ptr++ = ')';
|
||||
}
|
||||
<ARGLIST>{MCARG} {
|
||||
char *yptr;
|
||||
|
||||
yptr = mmtext;
|
||||
while (*yptr)
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
}
|
||||
<ARGLIST>\, {
|
||||
if (string_buf_ptr != string_buf) {
|
||||
/*
|
||||
* Return an argument and
|
||||
* rescan this comma so we
|
||||
* can return it as well.
|
||||
*/
|
||||
*string_buf_ptr = '\0';
|
||||
mmlval.str = string_buf;
|
||||
string_buf_ptr = string_buf;
|
||||
unput(',');
|
||||
return T_ARG;
|
||||
}
|
||||
return ',';
|
||||
}
|
||||
{WORD}[(] {
|
||||
/* May be a symbol or a macro invocation. */
|
||||
mmlval.sym = symtable_get(mmtext);
|
||||
if (mmlval.sym->type != MACRO) {
|
||||
stop("Expecting Macro Name",
|
||||
EX_DATAERR);
|
||||
}
|
||||
unput('(');
|
||||
parren_count = 0;
|
||||
BEGIN ARGLIST;
|
||||
return T_SYMBOL;
|
||||
}
|
||||
. {
|
||||
snprintf(buf, sizeof(buf), "Invalid character "
|
||||
"'%c'", mmtext[0]);
|
||||
stop(buf, EX_DATAERR);
|
||||
}
|
||||
%%
|
||||
|
||||
int
|
||||
mmwrap()
|
||||
{
|
||||
stop("EOF encountered in macro call", EX_DATAERR);
|
||||
}
|
||||
622
drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
Normal file
622
drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
Normal file
|
|
@ -0,0 +1,622 @@
|
|||
%{
|
||||
/*
|
||||
* Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
|
||||
*
|
||||
* Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
|
||||
* Copyright (c) 2001, 2002 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#20 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#ifdef __linux__
|
||||
#include "../queue.h"
|
||||
#else
|
||||
#include <sys/queue.h>
|
||||
#endif
|
||||
|
||||
#include "aicasm.h"
|
||||
#include "aicasm_symbol.h"
|
||||
#include "aicasm_gram.h"
|
||||
|
||||
/* This is used for macro body capture too, so err on the large size. */
|
||||
#define MAX_STR_CONST 4096
|
||||
static char string_buf[MAX_STR_CONST];
|
||||
static char *string_buf_ptr;
|
||||
static int parren_count;
|
||||
static int quote_count;
|
||||
static char buf[255];
|
||||
%}
|
||||
|
||||
PATH ([/]*[-A-Za-z0-9_.])+
|
||||
WORD [A-Za-z_][-A-Za-z_0-9]*
|
||||
SPACE [ \t]+
|
||||
MCARG [^(), \t]+
|
||||
MBODY ((\\[^\n])*[^\n\\]*)+
|
||||
|
||||
%x COMMENT
|
||||
%x CEXPR
|
||||
%x INCLUDE
|
||||
%x STRING
|
||||
%x MACRODEF
|
||||
%x MACROARGLIST
|
||||
%x MACROCALLARGS
|
||||
%x MACROBODY
|
||||
|
||||
%%
|
||||
\n { ++yylineno; }
|
||||
\r ;
|
||||
"/*" { BEGIN COMMENT; /* Enter comment eating state */ }
|
||||
<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); }
|
||||
<COMMENT>\n { ++yylineno; }
|
||||
<COMMENT>[^*/\n]* ;
|
||||
<COMMENT>"*"+[^*/\n]* ;
|
||||
<COMMENT>"/"+[^*/\n]* ;
|
||||
<COMMENT>"*"+"/" { BEGIN INITIAL; }
|
||||
if[ \t]*\( {
|
||||
string_buf_ptr = string_buf;
|
||||
parren_count = 1;
|
||||
BEGIN CEXPR;
|
||||
return T_IF;
|
||||
}
|
||||
<CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; }
|
||||
<CEXPR>\) {
|
||||
parren_count--;
|
||||
if (parren_count == 0) {
|
||||
/* All done */
|
||||
BEGIN INITIAL;
|
||||
*string_buf_ptr = '\0';
|
||||
yylval.sym = symtable_get(string_buf);
|
||||
return T_CEXPR;
|
||||
} else {
|
||||
*string_buf_ptr++ = ')';
|
||||
}
|
||||
}
|
||||
<CEXPR>\n { ++yylineno; }
|
||||
<CEXPR>\r ;
|
||||
<CEXPR>[^()\n]+ {
|
||||
char *yptr;
|
||||
|
||||
yptr = yytext;
|
||||
while (*yptr != '\0') {
|
||||
/* Remove duplicate spaces */
|
||||
if (*yptr == '\t')
|
||||
*yptr = ' ';
|
||||
if (*yptr == ' '
|
||||
&& string_buf_ptr != string_buf
|
||||
&& string_buf_ptr[-1] == ' ')
|
||||
yptr++;
|
||||
else
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
}
|
||||
}
|
||||
else { return T_ELSE; }
|
||||
VERSION { return T_VERSION; }
|
||||
PREFIX { return T_PREFIX; }
|
||||
PATCH_ARG_LIST { return T_PATCH_ARG_LIST; }
|
||||
\" {
|
||||
string_buf_ptr = string_buf;
|
||||
BEGIN STRING;
|
||||
}
|
||||
<STRING>[^"]+ {
|
||||
char *yptr;
|
||||
|
||||
yptr = yytext;
|
||||
while (*yptr)
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
}
|
||||
<STRING>\" {
|
||||
/* All done */
|
||||
BEGIN INITIAL;
|
||||
*string_buf_ptr = '\0';
|
||||
yylval.str = string_buf;
|
||||
return T_STRING;
|
||||
}
|
||||
{SPACE} ;
|
||||
|
||||
/* Register/SCB/SRAM definition keywords */
|
||||
export { return T_EXPORT; }
|
||||
register { return T_REGISTER; }
|
||||
const { yylval.value = FALSE; return T_CONST; }
|
||||
download { return T_DOWNLOAD; }
|
||||
address { return T_ADDRESS; }
|
||||
count { return T_COUNT; }
|
||||
access_mode { return T_ACCESS_MODE; }
|
||||
dont_generate_debug_code { return T_DONT_GENERATE_DEBUG_CODE; }
|
||||
modes { return T_MODES; }
|
||||
RW|RO|WO {
|
||||
if (strcmp(yytext, "RW") == 0)
|
||||
yylval.value = RW;
|
||||
else if (strcmp(yytext, "RO") == 0)
|
||||
yylval.value = RO;
|
||||
else
|
||||
yylval.value = WO;
|
||||
return T_MODE;
|
||||
}
|
||||
field { return T_FIELD; }
|
||||
enum { return T_ENUM; }
|
||||
mask { return T_MASK; }
|
||||
alias { return T_ALIAS; }
|
||||
size { return T_SIZE; }
|
||||
scb { return T_SCB; }
|
||||
scratch_ram { return T_SRAM; }
|
||||
accumulator { return T_ACCUM; }
|
||||
mode_pointer { return T_MODE_PTR; }
|
||||
allones { return T_ALLONES; }
|
||||
allzeros { return T_ALLZEROS; }
|
||||
none { return T_NONE; }
|
||||
sindex { return T_SINDEX; }
|
||||
A { return T_A; }
|
||||
|
||||
/* Instruction Formatting */
|
||||
PAD_PAGE { return T_PAD_PAGE; }
|
||||
BEGIN_CRITICAL { return T_BEGIN_CS; }
|
||||
END_CRITICAL { return T_END_CS; }
|
||||
SET_SRC_MODE { return T_SET_SRC_MODE; }
|
||||
SET_DST_MODE { return T_SET_DST_MODE; }
|
||||
|
||||
/* Opcodes */
|
||||
shl { return T_SHL; }
|
||||
shr { return T_SHR; }
|
||||
ror { return T_ROR; }
|
||||
rol { return T_ROL; }
|
||||
mvi { return T_MVI; }
|
||||
mov { return T_MOV; }
|
||||
clr { return T_CLR; }
|
||||
jmp { return T_JMP; }
|
||||
jc { return T_JC; }
|
||||
jnc { return T_JNC; }
|
||||
je { return T_JE; }
|
||||
jne { return T_JNE; }
|
||||
jz { return T_JZ; }
|
||||
jnz { return T_JNZ; }
|
||||
call { return T_CALL; }
|
||||
add { return T_ADD; }
|
||||
adc { return T_ADC; }
|
||||
bmov { return T_BMOV; }
|
||||
inc { return T_INC; }
|
||||
dec { return T_DEC; }
|
||||
stc { return T_STC; }
|
||||
clc { return T_CLC; }
|
||||
cmp { return T_CMP; }
|
||||
not { return T_NOT; }
|
||||
xor { return T_XOR; }
|
||||
test { return T_TEST;}
|
||||
and { return T_AND; }
|
||||
or { return T_OR; }
|
||||
ret { return T_RET; }
|
||||
nop { return T_NOP; }
|
||||
|
||||
/* ARP2 16bit extensions */
|
||||
/* or16 { return T_OR16; } */
|
||||
/* and16 { return T_AND16; }*/
|
||||
/* xor16 { return T_XOR16; }*/
|
||||
/* add16 { return T_ADD16; }*/
|
||||
/* adc16 { return T_ADC16; }*/
|
||||
/* mvi16 { return T_MVI16; }*/
|
||||
/* test16 { return T_TEST16; }*/
|
||||
/* cmp16 { return T_CMP16; }*/
|
||||
/* cmpxchg { return T_CMPXCHG; }*/
|
||||
|
||||
/* Allowed Symbols */
|
||||
\<\< { return T_EXPR_LSHIFT; }
|
||||
\>\> { return T_EXPR_RSHIFT; }
|
||||
[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }
|
||||
|
||||
/* Number processing */
|
||||
0[0-7]* {
|
||||
yylval.value = strtol(yytext, NULL, 8);
|
||||
return T_NUMBER;
|
||||
}
|
||||
|
||||
0[xX][0-9a-fA-F]+ {
|
||||
yylval.value = strtoul(yytext + 2, NULL, 16);
|
||||
return T_NUMBER;
|
||||
}
|
||||
|
||||
[1-9][0-9]* {
|
||||
yylval.value = strtol(yytext, NULL, 10);
|
||||
return T_NUMBER;
|
||||
}
|
||||
/* Include Files */
|
||||
#include{SPACE} {
|
||||
BEGIN INCLUDE;
|
||||
quote_count = 0;
|
||||
return T_INCLUDE;
|
||||
}
|
||||
<INCLUDE>[<] { return yytext[0]; }
|
||||
<INCLUDE>[>] { BEGIN INITIAL; return yytext[0]; }
|
||||
<INCLUDE>[\"] {
|
||||
if (quote_count != 0)
|
||||
BEGIN INITIAL;
|
||||
quote_count++;
|
||||
return yytext[0];
|
||||
}
|
||||
<INCLUDE>{PATH} {
|
||||
char *yptr;
|
||||
|
||||
yptr = yytext;
|
||||
string_buf_ptr = string_buf;
|
||||
while (*yptr)
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
yylval.str = string_buf;
|
||||
*string_buf_ptr = '\0';
|
||||
return T_PATH;
|
||||
}
|
||||
<INCLUDE>. { stop("Invalid include line", EX_DATAERR); }
|
||||
#define{SPACE} {
|
||||
BEGIN MACRODEF;
|
||||
return T_DEFINE;
|
||||
}
|
||||
<MACRODEF>{WORD}{SPACE} {
|
||||
char *yptr;
|
||||
|
||||
/* Strip space and return as a normal symbol */
|
||||
yptr = yytext;
|
||||
while (*yptr != ' ' && *yptr != '\t')
|
||||
yptr++;
|
||||
*yptr = '\0';
|
||||
yylval.sym = symtable_get(yytext);
|
||||
string_buf_ptr = string_buf;
|
||||
BEGIN MACROBODY;
|
||||
return T_SYMBOL;
|
||||
}
|
||||
<MACRODEF>{WORD}\( {
|
||||
/*
|
||||
* We store the symbol with its opening
|
||||
* parren so we can differentiate macros
|
||||
* that take args from macros with the
|
||||
* same name that do not take args as
|
||||
* is allowed in C.
|
||||
*/
|
||||
BEGIN MACROARGLIST;
|
||||
yylval.sym = symtable_get(yytext);
|
||||
unput('(');
|
||||
return T_SYMBOL;
|
||||
}
|
||||
<MACROARGLIST>{WORD} {
|
||||
yylval.str = yytext;
|
||||
return T_ARG;
|
||||
}
|
||||
<MACROARGLIST>{SPACE} ;
|
||||
<MACROARGLIST>[(,] {
|
||||
return yytext[0];
|
||||
}
|
||||
<MACROARGLIST>[)] {
|
||||
string_buf_ptr = string_buf;
|
||||
BEGIN MACROBODY;
|
||||
return ')';
|
||||
}
|
||||
<MACROARGLIST>. {
|
||||
snprintf(buf, sizeof(buf), "Invalid character "
|
||||
"'%c' in macro argument list",
|
||||
yytext[0]);
|
||||
stop(buf, EX_DATAERR);
|
||||
}
|
||||
<MACROCALLARGS>{SPACE} ;
|
||||
<MACROCALLARGS>\( {
|
||||
parren_count++;
|
||||
if (parren_count == 1)
|
||||
return ('(');
|
||||
*string_buf_ptr++ = '(';
|
||||
}
|
||||
<MACROCALLARGS>\) {
|
||||
parren_count--;
|
||||
if (parren_count == 0) {
|
||||
BEGIN INITIAL;
|
||||
return (')');
|
||||
}
|
||||
*string_buf_ptr++ = ')';
|
||||
}
|
||||
<MACROCALLARGS>{MCARG} {
|
||||
char *yptr;
|
||||
|
||||
yptr = yytext;
|
||||
while (*yptr)
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
}
|
||||
<MACROCALLARGS>\, {
|
||||
if (string_buf_ptr != string_buf) {
|
||||
/*
|
||||
* Return an argument and
|
||||
* rescan this comma so we
|
||||
* can return it as well.
|
||||
*/
|
||||
*string_buf_ptr = '\0';
|
||||
yylval.str = string_buf;
|
||||
string_buf_ptr = string_buf;
|
||||
unput(',');
|
||||
return T_ARG;
|
||||
}
|
||||
return ',';
|
||||
}
|
||||
<MACROBODY>\\\n {
|
||||
/* Eat escaped newlines. */
|
||||
++yylineno;
|
||||
}
|
||||
<MACROBODY>\r ;
|
||||
<MACROBODY>\n {
|
||||
/* Macros end on the first unescaped newline. */
|
||||
BEGIN INITIAL;
|
||||
*string_buf_ptr = '\0';
|
||||
yylval.str = string_buf;
|
||||
++yylineno;
|
||||
return T_MACROBODY;
|
||||
}
|
||||
<MACROBODY>{MBODY} {
|
||||
char *yptr;
|
||||
char c;
|
||||
|
||||
yptr = yytext;
|
||||
while (c = *yptr++) {
|
||||
/*
|
||||
* Strip carriage returns.
|
||||
*/
|
||||
if (c == '\r')
|
||||
continue;
|
||||
*string_buf_ptr++ = c;
|
||||
}
|
||||
}
|
||||
{WORD}\( {
|
||||
char *yptr;
|
||||
char *ycopy;
|
||||
|
||||
/* May be a symbol or a macro invocation. */
|
||||
yylval.sym = symtable_get(yytext);
|
||||
if (yylval.sym->type == MACRO) {
|
||||
YY_BUFFER_STATE old_state;
|
||||
YY_BUFFER_STATE temp_state;
|
||||
|
||||
ycopy = strdup(yytext);
|
||||
yptr = ycopy + yyleng;
|
||||
while (yptr > ycopy)
|
||||
unput(*--yptr);
|
||||
old_state = YY_CURRENT_BUFFER;
|
||||
temp_state =
|
||||
yy_create_buffer(stdin,
|
||||
YY_BUF_SIZE);
|
||||
yy_switch_to_buffer(temp_state);
|
||||
mm_switch_to_buffer(old_state);
|
||||
mmparse();
|
||||
mm_switch_to_buffer(temp_state);
|
||||
yy_switch_to_buffer(old_state);
|
||||
mm_delete_buffer(temp_state);
|
||||
expand_macro(yylval.sym);
|
||||
} else {
|
||||
if (yylval.sym->type == UNINITIALIZED) {
|
||||
/* Try without the '(' */
|
||||
symbol_delete(yylval.sym);
|
||||
yytext[yyleng-1] = '\0';
|
||||
yylval.sym =
|
||||
symtable_get(yytext);
|
||||
}
|
||||
unput('(');
|
||||
return T_SYMBOL;
|
||||
}
|
||||
}
|
||||
{WORD} {
|
||||
yylval.sym = symtable_get(yytext);
|
||||
if (yylval.sym->type == MACRO) {
|
||||
expand_macro(yylval.sym);
|
||||
} else {
|
||||
return T_SYMBOL;
|
||||
}
|
||||
}
|
||||
. {
|
||||
snprintf(buf, sizeof(buf), "Invalid character "
|
||||
"'%c'", yytext[0]);
|
||||
stop(buf, EX_DATAERR);
|
||||
}
|
||||
%%
|
||||
|
||||
typedef struct include {
|
||||
YY_BUFFER_STATE buffer;
|
||||
int lineno;
|
||||
char *filename;
|
||||
SLIST_ENTRY(include) links;
|
||||
}include_t;
|
||||
|
||||
SLIST_HEAD(, include) include_stack;
|
||||
|
||||
void
|
||||
include_file(char *file_name, include_type type)
|
||||
{
|
||||
FILE *newfile;
|
||||
include_t *include;
|
||||
|
||||
newfile = NULL;
|
||||
/* Try the current directory first */
|
||||
if (includes_search_curdir != 0 || type == SOURCE_FILE)
|
||||
newfile = fopen(file_name, "r");
|
||||
|
||||
if (newfile == NULL && type != SOURCE_FILE) {
|
||||
path_entry_t include_dir;
|
||||
for (include_dir = search_path.slh_first;
|
||||
include_dir != NULL;
|
||||
include_dir = include_dir->links.sle_next) {
|
||||
char fullname[PATH_MAX];
|
||||
|
||||
if ((include_dir->quoted_includes_only == TRUE)
|
||||
&& (type != QUOTED_INCLUDE))
|
||||
continue;
|
||||
|
||||
snprintf(fullname, sizeof(fullname),
|
||||
"%s/%s", include_dir->directory, file_name);
|
||||
|
||||
if ((newfile = fopen(fullname, "r")) != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newfile == NULL) {
|
||||
perror(file_name);
|
||||
stop("Unable to open input file", EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (type != SOURCE_FILE) {
|
||||
include = (include_t *)malloc(sizeof(include_t));
|
||||
if (include == NULL) {
|
||||
stop("Unable to allocate include stack entry",
|
||||
EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
include->buffer = YY_CURRENT_BUFFER;
|
||||
include->lineno = yylineno;
|
||||
include->filename = yyfilename;
|
||||
SLIST_INSERT_HEAD(&include_stack, include, links);
|
||||
}
|
||||
yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
|
||||
yylineno = 1;
|
||||
yyfilename = strdup(file_name);
|
||||
}
|
||||
|
||||
static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
|
||||
const char **next_match,
|
||||
struct macro_arg **match_marg, regmatch_t *match);
|
||||
|
||||
void
|
||||
expand_macro(struct symbol *macro_symbol)
|
||||
{
|
||||
struct macro_arg *marg;
|
||||
struct macro_arg *match_marg;
|
||||
const char *body_head;
|
||||
const char *body_pos;
|
||||
const char *next_match;
|
||||
|
||||
/*
|
||||
* Due to the nature of unput, we must work
|
||||
* backwards through the macro body performing
|
||||
* any expansions.
|
||||
*/
|
||||
body_head = macro_symbol->info.macroinfo->body;
|
||||
body_pos = body_head + strlen(body_head);
|
||||
while (body_pos > body_head) {
|
||||
regmatch_t match;
|
||||
|
||||
next_match = body_head;
|
||||
match_marg = NULL;
|
||||
next_substitution(macro_symbol, body_pos, &next_match,
|
||||
&match_marg, &match);
|
||||
|
||||
/* Put back everything up until the replacement. */
|
||||
while (body_pos > next_match)
|
||||
unput(*--body_pos);
|
||||
|
||||
/* Perform the replacement. */
|
||||
if (match_marg != NULL) {
|
||||
const char *strp;
|
||||
|
||||
next_match = match_marg->replacement_text;
|
||||
strp = next_match + strlen(next_match);
|
||||
while (strp > next_match)
|
||||
unput(*--strp);
|
||||
|
||||
/* Skip past the unexpanded macro arg. */
|
||||
body_pos -= match.rm_eo - match.rm_so;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup replacement text. */
|
||||
STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) {
|
||||
free(marg->replacement_text);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next substitution in the macro working backwards from
|
||||
* body_pos until the beginning of the macro buffer. next_match
|
||||
* should be initialized to the beginning of the macro buffer prior
|
||||
* to calling this routine.
|
||||
*/
|
||||
static void
|
||||
next_substitution(struct symbol *mac_symbol, const char *body_pos,
|
||||
const char **next_match, struct macro_arg **match_marg,
|
||||
regmatch_t *match)
|
||||
{
|
||||
regmatch_t matches[2];
|
||||
struct macro_arg *marg;
|
||||
const char *search_pos;
|
||||
int retval;
|
||||
|
||||
do {
|
||||
search_pos = *next_match;
|
||||
|
||||
STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {
|
||||
|
||||
retval = regexec(&marg->arg_regex, search_pos, 2,
|
||||
matches, 0);
|
||||
if (retval == 0
|
||||
&& (matches[1].rm_eo + search_pos) <= body_pos
|
||||
&& (matches[1].rm_eo + search_pos) > *next_match) {
|
||||
*match = matches[1];
|
||||
*next_match = match->rm_eo + search_pos;
|
||||
*match_marg = marg;
|
||||
}
|
||||
}
|
||||
} while (search_pos != *next_match);
|
||||
}
|
||||
|
||||
int
|
||||
yywrap()
|
||||
{
|
||||
include_t *include;
|
||||
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
(void)fclose(yyin);
|
||||
if (yyfilename != NULL)
|
||||
free(yyfilename);
|
||||
yyfilename = NULL;
|
||||
include = include_stack.slh_first;
|
||||
if (include != NULL) {
|
||||
yy_switch_to_buffer(include->buffer);
|
||||
yylineno = include->lineno;
|
||||
yyfilename = include->filename;
|
||||
SLIST_REMOVE_HEAD(&include_stack, links);
|
||||
free(include);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
693
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
Normal file
693
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
/*
|
||||
* Aic7xxx SCSI host adapter firmware assembler symbol table implementation
|
||||
*
|
||||
* Copyright (c) 1997 Justin T. Gibbs.
|
||||
* Copyright (c) 2002 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include "aicdb.h"
|
||||
#else
|
||||
#include <db.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "aicasm_symbol.h"
|
||||
#include "aicasm.h"
|
||||
|
||||
static DB *symtable;
|
||||
|
||||
symbol_t *
|
||||
symbol_create(char *name)
|
||||
{
|
||||
symbol_t *new_symbol;
|
||||
|
||||
new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
|
||||
if (new_symbol == NULL) {
|
||||
perror("Unable to create new symbol");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
memset(new_symbol, 0, sizeof(*new_symbol));
|
||||
new_symbol->name = strdup(name);
|
||||
if (new_symbol->name == NULL)
|
||||
stop("Unable to strdup symbol name", EX_SOFTWARE);
|
||||
new_symbol->type = UNINITIALIZED;
|
||||
new_symbol->count = 1;
|
||||
return (new_symbol);
|
||||
}
|
||||
|
||||
void
|
||||
symbol_delete(symbol_t *symbol)
|
||||
{
|
||||
if (symtable != NULL) {
|
||||
DBT key;
|
||||
|
||||
key.data = symbol->name;
|
||||
key.size = strlen(symbol->name);
|
||||
symtable->del(symtable, &key, /*flags*/0);
|
||||
}
|
||||
switch(symbol->type) {
|
||||
case SCBLOC:
|
||||
case SRAMLOC:
|
||||
case REGISTER:
|
||||
if (symbol->info.rinfo != NULL)
|
||||
free(symbol->info.rinfo);
|
||||
break;
|
||||
case ALIAS:
|
||||
if (symbol->info.ainfo != NULL)
|
||||
free(symbol->info.ainfo);
|
||||
break;
|
||||
case MASK:
|
||||
case FIELD:
|
||||
case ENUM:
|
||||
case ENUM_ENTRY:
|
||||
if (symbol->info.finfo != NULL) {
|
||||
symlist_free(&symbol->info.finfo->symrefs);
|
||||
free(symbol->info.finfo);
|
||||
}
|
||||
break;
|
||||
case DOWNLOAD_CONST:
|
||||
case CONST:
|
||||
if (symbol->info.cinfo != NULL)
|
||||
free(symbol->info.cinfo);
|
||||
break;
|
||||
case LABEL:
|
||||
if (symbol->info.linfo != NULL)
|
||||
free(symbol->info.linfo);
|
||||
break;
|
||||
case UNINITIALIZED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(symbol->name);
|
||||
free(symbol);
|
||||
}
|
||||
|
||||
void
|
||||
symtable_open()
|
||||
{
|
||||
symtable = dbopen(/*filename*/NULL,
|
||||
O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
|
||||
/*openinfo*/NULL);
|
||||
|
||||
if (symtable == NULL) {
|
||||
perror("Symbol table creation failed");
|
||||
exit(EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
symtable_close()
|
||||
{
|
||||
if (symtable != NULL) {
|
||||
DBT key;
|
||||
DBT data;
|
||||
|
||||
while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
|
||||
symbol_t *stored_ptr;
|
||||
|
||||
memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
|
||||
symbol_delete(stored_ptr);
|
||||
}
|
||||
symtable->close(symtable);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The semantics of get is to return an uninitialized symbol entry
|
||||
* if a lookup fails.
|
||||
*/
|
||||
symbol_t *
|
||||
symtable_get(char *name)
|
||||
{
|
||||
symbol_t *stored_ptr;
|
||||
DBT key;
|
||||
DBT data;
|
||||
int retval;
|
||||
|
||||
key.data = (void *)name;
|
||||
key.size = strlen(name);
|
||||
|
||||
if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
|
||||
if (retval == -1) {
|
||||
perror("Symbol table get operation failed");
|
||||
exit(EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
} else if (retval == 1) {
|
||||
/* Symbol wasn't found, so create a new one */
|
||||
symbol_t *new_symbol;
|
||||
|
||||
new_symbol = symbol_create(name);
|
||||
data.data = &new_symbol;
|
||||
data.size = sizeof(new_symbol);
|
||||
if (symtable->put(symtable, &key, &data,
|
||||
/*flags*/0) !=0) {
|
||||
perror("Symtable put failed");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
return (new_symbol);
|
||||
} else {
|
||||
perror("Unexpected return value from db get routine");
|
||||
exit(EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
|
||||
stored_ptr->count++;
|
||||
data.data = &stored_ptr;
|
||||
if (symtable->put(symtable, &key, &data, /*flags*/0) !=0) {
|
||||
perror("Symtable put failed");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
return (stored_ptr);
|
||||
}
|
||||
|
||||
symbol_node_t *
|
||||
symlist_search(symlist_t *symlist, char *symname)
|
||||
{
|
||||
symbol_node_t *curnode;
|
||||
|
||||
curnode = SLIST_FIRST(symlist);
|
||||
while(curnode != NULL) {
|
||||
if (strcmp(symname, curnode->symbol->name) == 0)
|
||||
break;
|
||||
curnode = SLIST_NEXT(curnode, links);
|
||||
}
|
||||
return (curnode);
|
||||
}
|
||||
|
||||
void
|
||||
symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
|
||||
{
|
||||
symbol_node_t *newnode;
|
||||
|
||||
newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
|
||||
if (newnode == NULL) {
|
||||
stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
newnode->symbol = symbol;
|
||||
if (how == SYMLIST_SORT) {
|
||||
symbol_node_t *curnode;
|
||||
int field;
|
||||
|
||||
field = FALSE;
|
||||
switch(symbol->type) {
|
||||
case REGISTER:
|
||||
case SCBLOC:
|
||||
case SRAMLOC:
|
||||
break;
|
||||
case FIELD:
|
||||
case MASK:
|
||||
case ENUM:
|
||||
case ENUM_ENTRY:
|
||||
field = TRUE;
|
||||
break;
|
||||
default:
|
||||
stop("symlist_add: Invalid symbol type for sorting",
|
||||
EX_SOFTWARE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
curnode = SLIST_FIRST(symlist);
|
||||
if (curnode == NULL
|
||||
|| (field
|
||||
&& (curnode->symbol->type > newnode->symbol->type
|
||||
|| (curnode->symbol->type == newnode->symbol->type
|
||||
&& (curnode->symbol->info.finfo->value >
|
||||
newnode->symbol->info.finfo->value))))
|
||||
|| (!field && (curnode->symbol->info.rinfo->address >
|
||||
newnode->symbol->info.rinfo->address))) {
|
||||
SLIST_INSERT_HEAD(symlist, newnode, links);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (SLIST_NEXT(curnode, links) == NULL) {
|
||||
SLIST_INSERT_AFTER(curnode, newnode,
|
||||
links);
|
||||
break;
|
||||
} else {
|
||||
symbol_t *cursymbol;
|
||||
|
||||
cursymbol = SLIST_NEXT(curnode, links)->symbol;
|
||||
if ((field
|
||||
&& (cursymbol->type > symbol->type
|
||||
|| (cursymbol->type == symbol->type
|
||||
&& (cursymbol->info.finfo->value >
|
||||
symbol->info.finfo->value))))
|
||||
|| (!field
|
||||
&& (cursymbol->info.rinfo->address >
|
||||
symbol->info.rinfo->address))) {
|
||||
SLIST_INSERT_AFTER(curnode, newnode,
|
||||
links);
|
||||
break;
|
||||
}
|
||||
}
|
||||
curnode = SLIST_NEXT(curnode, links);
|
||||
}
|
||||
} else {
|
||||
SLIST_INSERT_HEAD(symlist, newnode, links);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
symlist_free(symlist_t *symlist)
|
||||
{
|
||||
symbol_node_t *node1, *node2;
|
||||
|
||||
node1 = SLIST_FIRST(symlist);
|
||||
while (node1 != NULL) {
|
||||
node2 = SLIST_NEXT(node1, links);
|
||||
free(node1);
|
||||
node1 = node2;
|
||||
}
|
||||
SLIST_INIT(symlist);
|
||||
}
|
||||
|
||||
void
|
||||
symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
|
||||
symlist_t *symlist_src2)
|
||||
{
|
||||
symbol_node_t *node;
|
||||
|
||||
*symlist_dest = *symlist_src1;
|
||||
while((node = SLIST_FIRST(symlist_src2)) != NULL) {
|
||||
SLIST_REMOVE_HEAD(symlist_src2, links);
|
||||
SLIST_INSERT_HEAD(symlist_dest, node, links);
|
||||
}
|
||||
|
||||
/* These are now empty */
|
||||
SLIST_INIT(symlist_src1);
|
||||
SLIST_INIT(symlist_src2);
|
||||
}
|
||||
|
||||
void
|
||||
aic_print_file_prologue(FILE *ofile)
|
||||
{
|
||||
|
||||
if (ofile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(ofile,
|
||||
"/*\n"
|
||||
" * DO NOT EDIT - This file is automatically generated\n"
|
||||
" * from the following source files:\n"
|
||||
" *\n"
|
||||
"%s */\n",
|
||||
versions);
|
||||
}
|
||||
|
||||
void
|
||||
aic_print_include(FILE *dfile, char *include_file)
|
||||
{
|
||||
|
||||
if (dfile == NULL)
|
||||
return;
|
||||
fprintf(dfile, "\n#include \"%s\"\n\n", include_file);
|
||||
}
|
||||
|
||||
void
|
||||
aic_print_reg_dump_types(FILE *ofile)
|
||||
{
|
||||
if (ofile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(ofile,
|
||||
"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n"
|
||||
"typedef struct %sreg_parse_entry {\n"
|
||||
" char *name;\n"
|
||||
" uint8_t value;\n"
|
||||
" uint8_t mask;\n"
|
||||
"} %sreg_parse_entry_t;\n"
|
||||
"\n",
|
||||
prefix, prefix, prefix);
|
||||
}
|
||||
|
||||
static void
|
||||
aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
|
||||
{
|
||||
if (dfile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(dfile,
|
||||
"static const %sreg_parse_entry_t %s_parse_table[] = {\n",
|
||||
prefix,
|
||||
regnode->symbol->name);
|
||||
}
|
||||
|
||||
static void
|
||||
aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
|
||||
symbol_node_t *regnode, u_int num_entries)
|
||||
{
|
||||
char *lower_name;
|
||||
char *letter;
|
||||
|
||||
lower_name = strdup(regnode->symbol->name);
|
||||
if (lower_name == NULL)
|
||||
stop("Unable to strdup symbol name", EX_SOFTWARE);
|
||||
|
||||
for (letter = lower_name; *letter != '\0'; letter++)
|
||||
*letter = tolower(*letter);
|
||||
|
||||
if (dfile != NULL) {
|
||||
if (num_entries != 0)
|
||||
fprintf(dfile,
|
||||
"\n"
|
||||
"};\n"
|
||||
"\n");
|
||||
|
||||
fprintf(dfile,
|
||||
"int\n"
|
||||
"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n"
|
||||
"{\n"
|
||||
" return (%sprint_register(%s%s, %d, \"%s\",\n"
|
||||
" 0x%02x, regvalue, cur_col, wrap));\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
prefix,
|
||||
lower_name,
|
||||
prefix,
|
||||
num_entries != 0 ? regnode->symbol->name : "NULL",
|
||||
num_entries != 0 ? "_parse_table" : "",
|
||||
num_entries,
|
||||
regnode->symbol->name,
|
||||
regnode->symbol->info.rinfo->address);
|
||||
}
|
||||
|
||||
fprintf(ofile,
|
||||
"#if AIC_DEBUG_REGISTERS\n"
|
||||
"%sreg_print_t %s%s_print;\n"
|
||||
"#else\n"
|
||||
"#define %s%s_print(regvalue, cur_col, wrap) \\\n"
|
||||
" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n"
|
||||
"#endif\n"
|
||||
"\n",
|
||||
prefix,
|
||||
prefix,
|
||||
lower_name,
|
||||
prefix,
|
||||
lower_name,
|
||||
prefix,
|
||||
regnode->symbol->name,
|
||||
regnode->symbol->info.rinfo->address);
|
||||
}
|
||||
|
||||
static void
|
||||
aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode)
|
||||
{
|
||||
int num_tabs;
|
||||
|
||||
if (dfile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(dfile,
|
||||
" { \"%s\",",
|
||||
curnode->symbol->name);
|
||||
|
||||
num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8;
|
||||
|
||||
while (num_tabs-- > 0)
|
||||
fputc('\t', dfile);
|
||||
fprintf(dfile, "0x%02x, 0x%02x }",
|
||||
curnode->symbol->info.finfo->value,
|
||||
curnode->symbol->info.finfo->mask);
|
||||
}
|
||||
|
||||
void
|
||||
symtable_dump(FILE *ofile, FILE *dfile)
|
||||
{
|
||||
/*
|
||||
* Sort the registers by address with a simple insertion sort.
|
||||
* Put bitmasks next to the first register that defines them.
|
||||
* Put constants at the end.
|
||||
*/
|
||||
symlist_t registers;
|
||||
symlist_t masks;
|
||||
symlist_t constants;
|
||||
symlist_t download_constants;
|
||||
symlist_t aliases;
|
||||
symlist_t exported_labels;
|
||||
symbol_node_t *curnode;
|
||||
symbol_node_t *regnode;
|
||||
DBT key;
|
||||
DBT data;
|
||||
int flag;
|
||||
int reg_count = 0, reg_used = 0;
|
||||
u_int i;
|
||||
|
||||
if (symtable == NULL)
|
||||
return;
|
||||
|
||||
SLIST_INIT(®isters);
|
||||
SLIST_INIT(&masks);
|
||||
SLIST_INIT(&constants);
|
||||
SLIST_INIT(&download_constants);
|
||||
SLIST_INIT(&aliases);
|
||||
SLIST_INIT(&exported_labels);
|
||||
flag = R_FIRST;
|
||||
while (symtable->seq(symtable, &key, &data, flag) == 0) {
|
||||
symbol_t *cursym;
|
||||
|
||||
memcpy(&cursym, data.data, sizeof(cursym));
|
||||
switch(cursym->type) {
|
||||
case REGISTER:
|
||||
case SCBLOC:
|
||||
case SRAMLOC:
|
||||
symlist_add(®isters, cursym, SYMLIST_SORT);
|
||||
break;
|
||||
case MASK:
|
||||
case FIELD:
|
||||
case ENUM:
|
||||
case ENUM_ENTRY:
|
||||
symlist_add(&masks, cursym, SYMLIST_SORT);
|
||||
break;
|
||||
case CONST:
|
||||
symlist_add(&constants, cursym,
|
||||
SYMLIST_INSERT_HEAD);
|
||||
break;
|
||||
case DOWNLOAD_CONST:
|
||||
symlist_add(&download_constants, cursym,
|
||||
SYMLIST_INSERT_HEAD);
|
||||
break;
|
||||
case ALIAS:
|
||||
symlist_add(&aliases, cursym,
|
||||
SYMLIST_INSERT_HEAD);
|
||||
break;
|
||||
case LABEL:
|
||||
if (cursym->info.linfo->exported == 0)
|
||||
break;
|
||||
symlist_add(&exported_labels, cursym,
|
||||
SYMLIST_INSERT_HEAD);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flag = R_NEXT;
|
||||
}
|
||||
|
||||
/* Register dianostic functions/declarations first. */
|
||||
aic_print_file_prologue(ofile);
|
||||
aic_print_reg_dump_types(ofile);
|
||||
aic_print_file_prologue(dfile);
|
||||
aic_print_include(dfile, stock_include_file);
|
||||
SLIST_FOREACH(curnode, ®isters, links) {
|
||||
|
||||
if (curnode->symbol->dont_generate_debug_code)
|
||||
continue;
|
||||
|
||||
switch(curnode->symbol->type) {
|
||||
case REGISTER:
|
||||
case SCBLOC:
|
||||
case SRAMLOC:
|
||||
{
|
||||
symlist_t *fields;
|
||||
symbol_node_t *fieldnode;
|
||||
int num_entries;
|
||||
|
||||
num_entries = 0;
|
||||
reg_count++;
|
||||
if (curnode->symbol->count == 1)
|
||||
break;
|
||||
fields = &curnode->symbol->info.rinfo->fields;
|
||||
SLIST_FOREACH(fieldnode, fields, links) {
|
||||
if (num_entries == 0)
|
||||
aic_print_reg_dump_start(dfile,
|
||||
curnode);
|
||||
else if (dfile != NULL)
|
||||
fputs(",\n", dfile);
|
||||
num_entries++;
|
||||
aic_print_reg_dump_entry(dfile, fieldnode);
|
||||
}
|
||||
aic_print_reg_dump_end(ofile, dfile,
|
||||
curnode, num_entries);
|
||||
reg_used++;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s: %d of %d register definitions used\n", appname,
|
||||
reg_used, reg_count);
|
||||
|
||||
/* Fold in the masks and bits */
|
||||
while (SLIST_FIRST(&masks) != NULL) {
|
||||
char *regname;
|
||||
|
||||
curnode = SLIST_FIRST(&masks);
|
||||
SLIST_REMOVE_HEAD(&masks, links);
|
||||
|
||||
regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs);
|
||||
regname = regnode->symbol->name;
|
||||
regnode = symlist_search(®isters, regname);
|
||||
SLIST_INSERT_AFTER(regnode, curnode, links);
|
||||
}
|
||||
|
||||
/* Add the aliases */
|
||||
while (SLIST_FIRST(&aliases) != NULL) {
|
||||
char *regname;
|
||||
|
||||
curnode = SLIST_FIRST(&aliases);
|
||||
SLIST_REMOVE_HEAD(&aliases, links);
|
||||
|
||||
regname = curnode->symbol->info.ainfo->parent->name;
|
||||
regnode = symlist_search(®isters, regname);
|
||||
SLIST_INSERT_AFTER(regnode, curnode, links);
|
||||
}
|
||||
|
||||
/* Output generated #defines. */
|
||||
while (SLIST_FIRST(®isters) != NULL) {
|
||||
symbol_node_t *curnode;
|
||||
u_int value;
|
||||
char *tab_str;
|
||||
char *tab_str2;
|
||||
|
||||
curnode = SLIST_FIRST(®isters);
|
||||
SLIST_REMOVE_HEAD(®isters, links);
|
||||
switch(curnode->symbol->type) {
|
||||
case REGISTER:
|
||||
case SCBLOC:
|
||||
case SRAMLOC:
|
||||
fprintf(ofile, "\n");
|
||||
value = curnode->symbol->info.rinfo->address;
|
||||
tab_str = "\t";
|
||||
tab_str2 = "\t\t";
|
||||
break;
|
||||
case ALIAS:
|
||||
{
|
||||
symbol_t *parent;
|
||||
|
||||
parent = curnode->symbol->info.ainfo->parent;
|
||||
value = parent->info.rinfo->address;
|
||||
tab_str = "\t";
|
||||
tab_str2 = "\t\t";
|
||||
break;
|
||||
}
|
||||
case MASK:
|
||||
case FIELD:
|
||||
case ENUM:
|
||||
case ENUM_ENTRY:
|
||||
value = curnode->symbol->info.finfo->value;
|
||||
tab_str = "\t\t";
|
||||
tab_str2 = "\t";
|
||||
break;
|
||||
default:
|
||||
value = 0; /* Quiet compiler */
|
||||
tab_str = NULL;
|
||||
tab_str2 = NULL;
|
||||
stop("symtable_dump: Invalid symbol type "
|
||||
"encountered", EX_SOFTWARE);
|
||||
break;
|
||||
}
|
||||
fprintf(ofile, "#define%s%-16s%s0x%02x\n",
|
||||
tab_str, curnode->symbol->name, tab_str2,
|
||||
value);
|
||||
free(curnode);
|
||||
}
|
||||
fprintf(ofile, "\n\n");
|
||||
|
||||
while (SLIST_FIRST(&constants) != NULL) {
|
||||
symbol_node_t *curnode;
|
||||
|
||||
curnode = SLIST_FIRST(&constants);
|
||||
SLIST_REMOVE_HEAD(&constants, links);
|
||||
fprintf(ofile, "#define\t%-8s\t0x%02x\n",
|
||||
curnode->symbol->name,
|
||||
curnode->symbol->info.cinfo->value);
|
||||
free(curnode);
|
||||
}
|
||||
|
||||
fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
|
||||
|
||||
for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
|
||||
symbol_node_t *curnode;
|
||||
|
||||
curnode = SLIST_FIRST(&download_constants);
|
||||
SLIST_REMOVE_HEAD(&download_constants, links);
|
||||
fprintf(ofile, "#define\t%-8s\t0x%02x\n",
|
||||
curnode->symbol->name,
|
||||
curnode->symbol->info.cinfo->value);
|
||||
free(curnode);
|
||||
}
|
||||
fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i);
|
||||
|
||||
fprintf(ofile, "\n\n/* Exported Labels */\n");
|
||||
|
||||
while (SLIST_FIRST(&exported_labels) != NULL) {
|
||||
symbol_node_t *curnode;
|
||||
|
||||
curnode = SLIST_FIRST(&exported_labels);
|
||||
SLIST_REMOVE_HEAD(&exported_labels, links);
|
||||
fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n",
|
||||
curnode->symbol->name,
|
||||
curnode->symbol->info.linfo->address);
|
||||
free(curnode);
|
||||
}
|
||||
}
|
||||
|
||||
209
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
Normal file
209
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Aic7xxx SCSI host adapter firmware assembler symbol table definitions
|
||||
*
|
||||
* Copyright (c) 1997 Justin T. Gibbs.
|
||||
* Copyright (c) 2002 Adaptec Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#include "../queue.h"
|
||||
#else
|
||||
#include <sys/queue.h>
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UNINITIALIZED,
|
||||
REGISTER,
|
||||
ALIAS,
|
||||
SCBLOC,
|
||||
SRAMLOC,
|
||||
ENUM_ENTRY,
|
||||
FIELD,
|
||||
MASK,
|
||||
ENUM,
|
||||
CONST,
|
||||
DOWNLOAD_CONST,
|
||||
LABEL,
|
||||
CONDITIONAL,
|
||||
MACRO
|
||||
} symtype;
|
||||
|
||||
typedef enum {
|
||||
RO = 0x01,
|
||||
WO = 0x02,
|
||||
RW = 0x03
|
||||
}amode_t;
|
||||
|
||||
typedef SLIST_HEAD(symlist, symbol_node) symlist_t;
|
||||
|
||||
struct reg_info {
|
||||
u_int address;
|
||||
int size;
|
||||
amode_t mode;
|
||||
symlist_t fields;
|
||||
uint8_t valid_bitmask;
|
||||
uint8_t modes;
|
||||
int typecheck_masks;
|
||||
};
|
||||
|
||||
struct field_info {
|
||||
symlist_t symrefs;
|
||||
uint8_t value;
|
||||
uint8_t mask;
|
||||
};
|
||||
|
||||
struct const_info {
|
||||
u_int value;
|
||||
int define;
|
||||
};
|
||||
|
||||
struct alias_info {
|
||||
struct symbol *parent;
|
||||
};
|
||||
|
||||
struct label_info {
|
||||
int address;
|
||||
int exported;
|
||||
};
|
||||
|
||||
struct cond_info {
|
||||
int func_num;
|
||||
};
|
||||
|
||||
struct macro_arg {
|
||||
STAILQ_ENTRY(macro_arg) links;
|
||||
regex_t arg_regex;
|
||||
char *replacement_text;
|
||||
};
|
||||
STAILQ_HEAD(macro_arg_list, macro_arg) args;
|
||||
|
||||
struct macro_info {
|
||||
struct macro_arg_list args;
|
||||
int narg;
|
||||
const char* body;
|
||||
};
|
||||
|
||||
typedef struct expression_info {
|
||||
symlist_t referenced_syms;
|
||||
int value;
|
||||
} expression_t;
|
||||
|
||||
typedef struct symbol {
|
||||
char *name;
|
||||
symtype type;
|
||||
int count;
|
||||
union {
|
||||
struct reg_info *rinfo;
|
||||
struct field_info *finfo;
|
||||
struct const_info *cinfo;
|
||||
struct alias_info *ainfo;
|
||||
struct label_info *linfo;
|
||||
struct cond_info *condinfo;
|
||||
struct macro_info *macroinfo;
|
||||
} info;
|
||||
int dont_generate_debug_code;
|
||||
} symbol_t;
|
||||
|
||||
typedef struct symbol_ref {
|
||||
symbol_t *symbol;
|
||||
int offset;
|
||||
} symbol_ref_t;
|
||||
|
||||
typedef struct symbol_node {
|
||||
SLIST_ENTRY(symbol_node) links;
|
||||
symbol_t *symbol;
|
||||
} symbol_node_t;
|
||||
|
||||
typedef struct critical_section {
|
||||
TAILQ_ENTRY(critical_section) links;
|
||||
int begin_addr;
|
||||
int end_addr;
|
||||
} critical_section_t;
|
||||
|
||||
typedef enum {
|
||||
SCOPE_ROOT,
|
||||
SCOPE_IF,
|
||||
SCOPE_ELSE_IF,
|
||||
SCOPE_ELSE
|
||||
} scope_type;
|
||||
|
||||
typedef struct patch_info {
|
||||
int skip_patch;
|
||||
int skip_instr;
|
||||
} patch_info_t;
|
||||
|
||||
typedef struct scope {
|
||||
SLIST_ENTRY(scope) scope_stack_links;
|
||||
TAILQ_ENTRY(scope) scope_links;
|
||||
TAILQ_HEAD(, scope) inner_scope;
|
||||
scope_type type;
|
||||
int inner_scope_patches;
|
||||
int begin_addr;
|
||||
int end_addr;
|
||||
patch_info_t patches[2];
|
||||
int func_num;
|
||||
} scope_t;
|
||||
|
||||
TAILQ_HEAD(cs_tailq, critical_section);
|
||||
SLIST_HEAD(scope_list, scope);
|
||||
TAILQ_HEAD(scope_tailq, scope);
|
||||
|
||||
void symbol_delete(symbol_t *symbol);
|
||||
|
||||
void symtable_open(void);
|
||||
|
||||
void symtable_close(void);
|
||||
|
||||
symbol_t *
|
||||
symtable_get(char *name);
|
||||
|
||||
symbol_node_t *
|
||||
symlist_search(symlist_t *symlist, char *symname);
|
||||
|
||||
void
|
||||
symlist_add(symlist_t *symlist, symbol_t *symbol, int how);
|
||||
#define SYMLIST_INSERT_HEAD 0x00
|
||||
#define SYMLIST_SORT 0x01
|
||||
|
||||
void symlist_free(symlist_t *symlist);
|
||||
|
||||
void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
|
||||
symlist_t *symlist_src2);
|
||||
void symtable_dump(FILE *ofile, FILE *dfile);
|
||||
Loading…
Add table
Add a link
Reference in a new issue