summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2010-07-14 14:31:18 +0000
committergibbs <gibbs@FreeBSD.org>2010-07-14 14:31:18 +0000
commit6cc9a00e92553e95008045af113d896f5b8c075c (patch)
tree4c45cb872f5abca9d960f035acfac8156003ad05 /sys/dev/aic7xxx
parentb8b00841c93af095bbb283ea2d9a8662a7c55687 (diff)
downloadFreeBSD-src-6cc9a00e92553e95008045af113d896f5b8c075c.zip
FreeBSD-src-6cc9a00e92553e95008045af113d896f5b8c075c.tar.gz
Correct logic bug in aicasm's undefined register bit access detection code.
The code in question verifies that all register write operations only change bits that are defined (in the register definition file) for that effected register. The bug effectively disabled this checking. o Fix the check by testing the opcode against all supported read ("and" based) operands. o Add missing bit definitions to the aic7xxx and aic79xx register definition files so that the warning (treated as a fatal error) does not spuriously fire. Reported by: Pawel Worach <pawel.worach@gmail.com> MFC after: 1 week
Diffstat (limited to 'sys/dev/aic7xxx')
-rw-r--r--sys/dev/aic7xxx/aic79xx.reg1
-rw-r--r--sys/dev/aic7xxx/aic7xxx.reg1
-rw-r--r--sys/dev/aic7xxx/aicasm/aicasm_gram.y15
3 files changed, 12 insertions, 5 deletions
diff --git a/sys/dev/aic7xxx/aic79xx.reg b/sys/dev/aic7xxx/aic79xx.reg
index e856b62..86a86a9 100644
--- a/sys/dev/aic7xxx/aic79xx.reg
+++ b/sys/dev/aic7xxx/aic79xx.reg
@@ -3813,6 +3813,7 @@ scb {
SCB_RESIDUAL_SGPTR {
size 4
field SG_ADDR_MASK 0xf8 /* In the last byte */
+ field SG_ADDR_BIT 0x04
field SG_OVERRUN_RESID 0x02 /* In the first byte */
field SG_LIST_NULL 0x01 /* In the first byte */
}
diff --git a/sys/dev/aic7xxx/aic7xxx.reg b/sys/dev/aic7xxx/aic7xxx.reg
index 076c2ba..5042c50 100644
--- a/sys/dev/aic7xxx/aic7xxx.reg
+++ b/sys/dev/aic7xxx/aic7xxx.reg
@@ -1448,6 +1448,7 @@ scratch_ram {
mask EXIT_MSG_LOOP 0x08
mask CONT_MSG_LOOP 0x04
mask CONT_TARG_SESSION 0x02
+ mask SPARE 0x01
alias RETURN_1
}
ARG_2 {
diff --git a/sys/dev/aic7xxx/aicasm/aicasm_gram.y b/sys/dev/aic7xxx/aicasm/aicasm_gram.y
index 91ae8ea..d50d2b9 100644
--- a/sys/dev/aic7xxx/aicasm/aicasm_gram.y
+++ b/sys/dev/aic7xxx/aicasm/aicasm_gram.y
@@ -1821,9 +1821,15 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode)
{
symbol_node_t *node;
int and_op;
+ uint8_t invalid_bits;
and_op = FALSE;
- if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
+ if (opcode == AIC_OP_AND
+ || opcode == AIC_OP_BMOV
+ || opcode == AIC_OP_JE
+ || opcode == AIC_OP_JNE
+ || opcode == AIC_OP_JNZ
+ || opcode == AIC_OP_JZ)
and_op = TRUE;
/*
@@ -1831,12 +1837,11 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode)
* 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) {
+ invalid_bits = expression->value & ~symbol->info.rinfo->valid_bitmask;
+ if (and_op == FALSE && invalid_bits != 0) {
snprintf(errbuf, sizeof(errbuf),
"Invalid bit(s) 0x%x in immediate written to %s",
- expression->value & ~symbol->info.rinfo->valid_bitmask,
- symbol->name);
+ invalid_bits, symbol->name);
stop(errbuf, EX_DATAERR);
/* NOTREACHED */
}
OpenPOWER on IntegriCloud