aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/aic7xxx/aicasm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx/aicasm')
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm.c8
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_gram.y124
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h1
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y3
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l3
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_scan.l20
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c30
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h6
8 files changed, 130 insertions, 65 deletions
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c
index 924102720b1..2e3117aa382 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm.c
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c
@@ -1,5 +1,5 @@
/*
- * Aic7xxx SCSI host adapter firmware asssembler
+ * Aic7xxx SCSI host adapter firmware assembler
*
* Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.
* Copyright (c) 2001, 2002 Adaptec Inc.
@@ -362,7 +362,7 @@ output_code()
" *\n"
"%s */\n", versions);
- fprintf(ofile, "static uint8_t seqprog[] = {\n");
+ 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)) {
@@ -415,7 +415,7 @@ output_code()
}
fprintf(ofile,
-"static struct patch {\n"
+"static const struct patch {\n"
" %spatch_func_t *patch_func;\n"
" uint32_t begin :10,\n"
" skip_instr :10,\n"
@@ -435,7 +435,7 @@ output_code()
fprintf(ofile, "\n};\n\n");
fprintf(ofile,
-"static struct cs {\n"
+"static const struct cs {\n"
" uint16_t begin;\n"
" uint16_t end;\n"
"} critical_sections[] = {\n");
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
index c328596def3..f1586a43790 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -101,11 +101,13 @@ static void format_3_instr(int opcode, symbol_ref_t *src,
expression_t *immed, symbol_ref_t *address);
static void test_readable_symbol(symbol_t *symbol);
static void test_writable_symbol(symbol_t *symbol);
-static void type_check(symbol_t *symbol, expression_t *expression, int and_op);
+static void type_check(symbol_ref_t *sym, expression_t *expression, int and_op);
static void make_expression(expression_t *immed, int value);
static void add_conditional(symbol_t *symbol);
static void add_version(const char *verstring);
static int is_download_const(expression_t *immed);
+static int is_location_address(symbol_t *symbol);
+void yyerror(const char *string);
#define SRAM_SYMNAME "SRAM_BASE"
#define SCB_SYMNAME "SCB_BASE"
@@ -141,8 +143,12 @@ static int is_download_const(expression_t *immed);
%token <value> T_ADDRESS
+%token T_COUNT
+
%token T_ACCESS_MODE
+%token T_DONT_GENERATE_DEBUG_CODE
+
%token T_MODES
%token T_DEFINE
@@ -191,10 +197,10 @@ static int is_download_const(expression_t *immed);
%token <value> T_OR
-/* 16 bit extensions */
-%token <value> T_OR16 T_AND16 T_XOR16 T_ADD16
-%token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG
-
+/* 16 bit extensions, not implemented
+ * %token <value> T_OR16 T_AND16 T_XOR16 T_ADD16
+ * %token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG
+ */
%token T_RET
%token T_NOP
@@ -213,7 +219,7 @@ static int is_download_const(expression_t *immed);
%type <expression> expression immediate immediate_or_a
-%type <value> export ret f1_opcode f2_opcode f4_opcode jmp_jc_jnc_call jz_jnz je_jne
+%type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
%type <value> mode_value mode_list macro_arglist
@@ -312,13 +318,13 @@ reg_definition:
stop("Register multiply defined", EX_DATAERR);
/* NOTREACHED */
}
- cur_symbol = $1;
+ cur_symbol = $1;
cur_symbol->type = cur_symtype;
initialize_symbol(cur_symbol);
}
reg_attribute_list
'}'
- {
+ {
/*
* Default to allowing everything in for registers
* with no bit or mask definitions.
@@ -348,10 +354,12 @@ reg_attribute_list:
| reg_attribute_list reg_attribute
;
-reg_attribute:
+reg_attribute:
reg_address
| size
+| count
| access_mode
+| dont_generate_debug_code
| modes
| field_defn
| enum_defn
@@ -391,6 +399,13 @@ size:
}
;
+count:
+ T_COUNT T_NUMBER
+ {
+ cur_symbol->count += $2;
+ }
+;
+
access_mode:
T_ACCESS_MODE T_MODE
{
@@ -398,6 +413,13 @@ access_mode:
}
;
+dont_generate_debug_code:
+ T_DONT_GENERATE_DEBUG_CODE
+ {
+ cur_symbol->dont_generate_debug_code = 1;
+ }
+;
+
modes:
T_MODES mode_list
{
@@ -640,14 +662,14 @@ expression:
&($1.referenced_syms),
&($3.referenced_syms));
}
-| expression T_EXPR_LSHIFT expression
+| expression T_EXPR_LSHIFT expression
{
$$.value = $1.value << $3.value;
symlist_merge(&$$.referenced_syms,
&$1.referenced_syms,
&$3.referenced_syms);
}
-| expression T_EXPR_RSHIFT expression
+| expression T_EXPR_RSHIFT expression
{
$$.value = $1.value >> $3.value;
symlist_merge(&$$.referenced_syms,
@@ -713,7 +735,7 @@ expression:
;
constant:
- T_CONST T_SYMBOL expression
+ T_CONST T_SYMBOL expression
{
if ($2->type != UNINITIALIZED) {
stop("Re-definition of symbol as a constant",
@@ -781,7 +803,7 @@ macro_arglist:
| macro_arglist ',' T_ARG
{
if ($1 == 0) {
- stop("Comma without preceeding argument in arg list",
+ stop("Comma without preceding argument in arg list",
EX_DATAERR);
/* NOTREACHED */
}
@@ -799,6 +821,7 @@ scratch_ram:
cur_symtype = SRAMLOC;
cur_symbol->type = SRAMLOC;
initialize_symbol(cur_symbol);
+ cur_symbol->count += 1;
}
reg_address
{
@@ -830,6 +853,7 @@ scb:
initialize_symbol(cur_symbol);
/* 64 bytes of SCB space */
cur_symbol->info.rinfo->size = 64;
+ cur_symbol->count += 1;
}
reg_address
{
@@ -1295,8 +1319,8 @@ code:
;
/*
- * This grammer differs from the one in the aic7xxx
- * reference manual since the grammer listed there is
+ * This grammar differs from the one in the aic7xxx
+ * reference manual since the grammar listed there is
* ambiguous and causes a shift/reduce conflict.
* It also seems more logical as the "immediate"
* argument is listed as the second arg like the
@@ -1310,14 +1334,18 @@ f2_opcode:
| T_ROR { $$ = AIC_OP_ROR; }
;
-f4_opcode:
- T_OR16 { $$ = AIC_OP_OR16; }
-| T_AND16 { $$ = AIC_OP_AND16; }
-| T_XOR16 { $$ = AIC_OP_XOR16; }
-| T_ADD16 { $$ = AIC_OP_ADD16; }
-| T_ADC16 { $$ = AIC_OP_ADC16; }
-| T_MVI16 { $$ = AIC_OP_MVI16; }
-;
+/*
+ * 16bit opcodes, not used
+ *
+ *f4_opcode:
+ * T_OR16 { $$ = AIC_OP_OR16; }
+ *| T_AND16 { $$ = AIC_OP_AND16; }
+ *| T_XOR16 { $$ = AIC_OP_XOR16; }
+ *| T_ADD16 { $$ = AIC_OP_ADD16; }
+ *| T_ADC16 { $$ = AIC_OP_ADC16; }
+ *| T_MVI16 { $$ = AIC_OP_MVI16; }
+ *;
+ */
code:
f2_opcode destination ',' expression opt_source ret ';'
@@ -1356,6 +1384,7 @@ code:
code:
T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';'
{
+ type_check(&$2, &$4, AIC_OP_OR);
format_3_instr($5, &$2, &$4, &$6);
}
;
@@ -1527,7 +1556,7 @@ initialize_symbol(symbol_t *symbol)
sizeof(struct cond_info));
break;
case MACRO:
- symbol->info.macroinfo =
+ symbol->info.macroinfo =
(struct macro_info *)malloc(sizeof(struct macro_info));
if (symbol->info.macroinfo == NULL) {
stop("Can't create macro info", EX_SOFTWARE);
@@ -1551,7 +1580,6 @@ add_macro_arg(const char *argtext, int argnum)
struct macro_arg *marg;
int i;
int retval;
-
if (cur_symbol == NULL || cur_symbol->type != MACRO) {
stop("Invalid current symbol for adding macro arg",
@@ -1632,8 +1660,10 @@ format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed,
test_writable_symbol(dest->symbol);
test_readable_symbol(src->symbol);
- /* Ensure that immediate makes sense for this destination */
- type_check(dest->symbol, immed, opcode);
+ if (!is_location_address(dest->symbol)) {
+ /* Ensure that immediate makes sense for this destination */
+ type_check(dest, immed, opcode);
+ }
/* Allocate sequencer space for the instruction and fill it out */
instr = seq_alloc();
@@ -1765,14 +1795,11 @@ format_3_instr(int opcode, symbol_ref_t *src,
/* Test register permissions */
test_readable_symbol(src->symbol);
- /* Ensure that immediate makes sense for this source */
- type_check(src->symbol, immed, opcode);
-
/* Allocate sequencer space for the instruction and fill it out */
instr = seq_alloc();
f3_instr = &instr->format.format3;
if (address->symbol == NULL) {
- /* 'dot' referrence. Use the current instruction pointer */
+ /* 'dot' reference. Use the current instruction pointer */
addr = instruction_ptr + address->offset;
} else if (address->symbol->type == UNINITIALIZED) {
/* forward reference */
@@ -1796,7 +1823,6 @@ format_3_instr(int opcode, symbol_ref_t *src,
static void
test_readable_symbol(symbol_t *symbol)
{
-
if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) {
snprintf(errbuf, sizeof(errbuf),
"Register %s unavailable in source reg mode %d",
@@ -1814,7 +1840,6 @@ test_readable_symbol(symbol_t *symbol)
static void
test_writable_symbol(symbol_t *symbol)
{
-
if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) {
snprintf(errbuf, sizeof(errbuf),
"Register %s unavailable in destination reg mode %d",
@@ -1830,25 +1855,34 @@ test_writable_symbol(symbol_t *symbol)
}
static void
-type_check(symbol_t *symbol, expression_t *expression, int opcode)
+type_check(symbol_ref_t *sym, expression_t *expression, int opcode)
{
+ symbol_t *symbol = sym->symbol;
symbol_node_t *node;
int and_op;
+ int8_t value, mask;
and_op = FALSE;
- if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
- and_op = TRUE;
-
/*
* Make sure that we aren't attempting to write something
* that hasn't been defined. If this is an and operation,
* this is a mask, so "undefined" bits are okay.
*/
- if (and_op == FALSE
- && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) {
+ if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ ||
+ opcode == AIC_OP_JZ || opcode == AIC_OP_JNE ||
+ opcode == AIC_OP_BMOV)
+ and_op = TRUE;
+
+ /*
+ * Defaulting to 8 bit logic
+ */
+ mask = (int8_t)~symbol->info.rinfo->valid_bitmask;
+ value = (int8_t)expression->value;
+
+ if (and_op == FALSE && (mask & value) != 0 ) {
snprintf(errbuf, sizeof(errbuf),
"Invalid bit(s) 0x%x in immediate written to %s",
- expression->value & ~symbol->info.rinfo->valid_bitmask,
+ (mask & value),
symbol->name);
stop(errbuf, EX_DATAERR);
/* NOTREACHED */
@@ -1958,3 +1992,13 @@ is_download_const(expression_t *immed)
return (FALSE);
}
+
+static int
+is_location_address(symbol_t *sym)
+{
+ if (sym->type == SCBLOC ||
+ sym->type == SRAMLOC)
+ return (TRUE);
+ return (FALSE);
+}
+
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
index 9df9e2ce353..8373447bd7d 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
@@ -209,7 +209,6 @@ struct instruction {
#define AIC_OP_JC16 0x9105
#define AIC_OP_JNC16 0x9205
#define AIC_OP_CALL16 0x9305
-#define AIC_OP_CALL16 0x9305
/* Page extension is low three bits of second opcode byte. */
#define AIC_OP_JMPF 0xA005
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
index 439f760b34b..708326df076 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
@@ -65,6 +65,7 @@
static symbol_t *macro_symbol;
static void add_macro_arg(const char *argtext, int position);
+void mmerror(const char *string);
%}
@@ -114,7 +115,7 @@ macro_arglist:
| macro_arglist ',' T_ARG
{
if ($1 == 0) {
- stop("Comma without preceeding argument in arg list",
+ stop("Comma without preceding argument in arg list",
EX_DATAERR);
/* NOTREACHED */
}
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
index f06e7035cb3..c0457b8c3b7 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
@@ -66,6 +66,7 @@ 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]*
@@ -76,7 +77,7 @@ MCARG [^(), \t]+
%%
\n {
- ++yylineno;
+ ++mmlineno;
}
\r ;
<ARGLIST>{SPACE} ;
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
index 7c3983f868a..93c8667cd70 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
@@ -162,7 +162,9 @@ 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)
@@ -228,15 +230,15 @@ 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; }
+ /* 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; }
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
index f1f448dff56..232aff1fe78 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
@@ -1,5 +1,5 @@
/*
- * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
+ * Aic7xxx SCSI host adapter firmware assembler symbol table implementation
*
* Copyright (c) 1997 Justin T. Gibbs.
* Copyright (c) 2002 Adaptec Inc.
@@ -77,6 +77,7 @@ symbol_create(char *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);
}
@@ -198,6 +199,12 @@ symtable_get(char *name)
}
}
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);
}
@@ -256,7 +263,7 @@ symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
&& (curnode->symbol->info.finfo->value >
newnode->symbol->info.finfo->value))))
|| (!field && (curnode->symbol->info.rinfo->address >
- newnode->symbol->info.rinfo->address))) {
+ newnode->symbol->info.rinfo->address))) {
SLIST_INSERT_HEAD(symlist, newnode, links);
return;
}
@@ -271,7 +278,7 @@ symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
cursymbol = SLIST_NEXT(curnode, links)->symbol;
if ((field
- && (cursymbol->type > symbol->type
+ && (cursymbol->type > symbol->type
|| (cursymbol->type == symbol->type
&& (cursymbol->info.finfo->value >
symbol->info.finfo->value))))
@@ -351,7 +358,7 @@ 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"
@@ -370,7 +377,7 @@ aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
return;
fprintf(dfile,
-"static %sreg_parse_entry_t %s_parse_table[] = {\n",
+"static const %sreg_parse_entry_t %s_parse_table[] = {\n",
prefix,
regnode->symbol->name);
}
@@ -385,7 +392,7 @@ aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
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);
@@ -472,6 +479,7 @@ symtable_dump(FILE *ofile, FILE *dfile)
DBT key;
DBT data;
int flag;
+ int reg_count = 0, reg_used = 0;
u_int i;
if (symtable == NULL)
@@ -531,6 +539,9 @@ symtable_dump(FILE *ofile, FILE *dfile)
aic_print_include(dfile, stock_include_file);
SLIST_FOREACH(curnode, &registers, links) {
+ if (curnode->symbol->dont_generate_debug_code)
+ continue;
+
switch(curnode->symbol->type) {
case REGISTER:
case SCBLOC:
@@ -541,6 +552,9 @@ symtable_dump(FILE *ofile, FILE *dfile)
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)
@@ -553,11 +567,14 @@ symtable_dump(FILE *ofile, FILE *dfile)
}
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) {
@@ -646,7 +663,6 @@ symtable_dump(FILE *ofile, FILE *dfile)
free(curnode);
}
-
fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
index afc22e8b490..34bbcad7f83 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
@@ -1,5 +1,5 @@
/*
- * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions
+ * Aic7xxx SCSI host adapter firmware assembler symbol table definitions
*
* Copyright (c) 1997 Justin T. Gibbs.
* Copyright (c) 2002 Adaptec Inc.
@@ -128,6 +128,7 @@ typedef struct expression_info {
typedef struct symbol {
char *name;
symtype type;
+ int count;
union {
struct reg_info *rinfo;
struct field_info *finfo;
@@ -136,7 +137,8 @@ typedef struct symbol {
struct label_info *linfo;
struct cond_info *condinfo;
struct macro_info *macroinfo;
- }info;
+ } info;
+ int dont_generate_debug_code;
} symbol_t;
typedef struct symbol_ref {