diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aicasm')
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm.c | 6 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | 105 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm_scan.l | 19 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c | 25 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h | 1 |
5 files changed, 102 insertions, 54 deletions
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c index 924102720b14..e4a778720301 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm.c +++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c @@ -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 702e2dbd11fb..81be6a261cc8 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y @@ -101,11 +101,12 @@ 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" @@ -142,6 +143,8 @@ void yyerror(const char *string); %token <value> T_ADDRESS +%token T_COUNT + %token T_ACCESS_MODE %token T_MODES @@ -192,10 +195,10 @@ void yyerror(const char *string); %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 @@ -214,7 +217,7 @@ void yyerror(const char *string); %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 @@ -313,13 +316,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. @@ -349,9 +352,10 @@ reg_attribute_list: | reg_attribute_list reg_attribute ; -reg_attribute: +reg_attribute: reg_address | size +| count | access_mode | modes | field_defn @@ -392,6 +396,13 @@ size: } ; +count: + T_COUNT T_NUMBER + { + cur_symbol->count += $2; + } +; + access_mode: T_ACCESS_MODE T_MODE { @@ -641,14 +652,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, @@ -714,7 +725,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", @@ -800,6 +811,7 @@ scratch_ram: cur_symtype = SRAMLOC; cur_symbol->type = SRAMLOC; initialize_symbol(cur_symbol); + cur_symbol->count += 1; } reg_address { @@ -831,6 +843,7 @@ scb: initialize_symbol(cur_symbol); /* 64 bytes of SCB space */ cur_symbol->info.rinfo->size = 64; + cur_symbol->count += 1; } reg_address { @@ -1311,14 +1324,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 ';' @@ -1357,6 +1374,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); } ; @@ -1528,7 +1546,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); @@ -1552,7 +1570,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", @@ -1633,8 +1650,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(); @@ -1766,9 +1785,6 @@ 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; @@ -1797,7 +1813,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", @@ -1815,7 +1830,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", @@ -1831,25 +1845,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 || opcode == 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 */ @@ -1959,3 +1982,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_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l index 7c3983f868a9..2c7f02daf88d 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l @@ -162,6 +162,7 @@ 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; } modes { return T_MODES; } RW|RO|WO { @@ -228,15 +229,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 f1f448dff569..fcd357872b43 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c @@ -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) @@ -541,6 +549,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 +564,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 +660,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 afc22e8b4903..05190c1a2fb7 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h @@ -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; |