-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy path80-Avoid-failing-fuse-check-if-different-bits-are-reserved.patch
125 lines (117 loc) · 4.21 KB
/
80-Avoid-failing-fuse-check-if-different-bits-are-reserved.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
--- avr.c
+++ avr.c
@@ -1058,6 +1058,39 @@
return 0;
}
+uint8_t get_fuse_bitmask(AVRMEM * m) {
+ uint8_t bitmask_r = 0;
+ uint8_t bitmask_w = 0;
+ int i, j;
+
+ if (m->size > 1) {
+ // not a fuse, compare bytes directly
+ return 0xFF;
+ }
+
+ for (i=0; i<AVR_OP_MAX; i++) {
+ if (m->op[i] && i == AVR_OP_READ) {
+ for (j=7; j>=0; j--) {
+ bitmask_r |= (m->op[i]->bit[j].type != AVR_CMDBIT_IGNORE) << j;
+ }
+ }
+ if (m->op[i] && i == AVR_OP_WRITE) {
+ for (j=7; j>=0; j--) {
+ bitmask_w |= (m->op[i]->bit[j].type != AVR_CMDBIT_VALUE &&
+ m->op[i]->bit[j].type != AVR_CMDBIT_IGNORE) << j;
+ }
+ }
+ }
+ return bitmask_r & bitmask_w;
+}
+
+int compare_memory_masked(AVRMEM * m, unsigned char buf1, unsigned char buf2) {
+ uint8_t bitmask = 0xFF;
+ if(m) {
+ bitmask = get_fuse_bitmask(m);
+ }
+ return ((buf1 & bitmask) != (buf2 & bitmask));
+}
/*
* Verify the memory buffer of p with that of v. The byte range of v,
@@ -1104,11 +1137,18 @@
for (i=0; i<size; i++) {
if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
buf1[i] != buf2[i]) {
- avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
- "%s0x%02x != 0x%02x\n",
- progname, i,
- progbuf, buf1[i], buf2[i]);
- return -1;
+ if(compare_memory_masked(a , buf1[i], buf2[i])) {
+ avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
+ "%s0x%02x != 0x%02x\n",
+ progname, i,
+ progbuf, buf1[i], buf2[i]);
+ return -1;
+ } else {
+ avrdude_message(MSG_INFO, "%s: WARNING: invalid value for unused bits in fuse \"%s\", should be set to 1 according to datasheet\n"
+ "This behaviour is deprecated and will result in an error in future version\n"
+ "You probably want to use 0x%02x instead of 0x%02x (double check with your datasheet first).\n",
+ progname, memtype, buf1[i], buf2[i]);
+ }
}
}
--- libavrdude.h
+++ libavrdude.h
@@ -337,6 +337,10 @@
void *cookie);
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
void sort_avrparts(LISTID avrparts);
+
+uint8_t get_fuse_bitmask(AVRMEM * m);
+int compare_memory_masked(AVRMEM * m, unsigned char buf1, unsigned char buf2);
+
#ifdef __cplusplus
}
#endif
--- main.c
+++ main.c
@@ -1264,8 +1264,11 @@
}
}
+ AVRMEM * m;
+
/* Now check what fuses are against what they should be */
- if (safemodeafter_fuse != safemode_fuse) {
+ m = avr_locate_mem(p, "fuse");
+ if (compare_memory_masked(m, safemodeafter_fuse, safemode_fuse)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
progname, safemode_fuse, safemodeafter_fuse);
@@ -1293,7 +1296,8 @@
}
/* Now check what fuses are against what they should be */
- if (safemodeafter_lfuse != safemode_lfuse) {
+ m = avr_locate_mem(p, "lfuse");
+ if (compare_memory_masked(m, safemodeafter_lfuse, safemode_lfuse)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
progname, safemode_lfuse, safemodeafter_lfuse);
@@ -1321,7 +1325,8 @@
}
/* Now check what fuses are against what they should be */
- if (safemodeafter_hfuse != safemode_hfuse) {
+ m = avr_locate_mem(p, "hfuse");
+ if (compare_memory_masked(m, safemodeafter_hfuse, safemode_hfuse)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
progname, safemode_hfuse, safemodeafter_hfuse);
@@ -1346,7 +1351,8 @@
}
/* Now check what fuses are against what they should be */
- if (safemodeafter_efuse != safemode_efuse) {
+ m = avr_locate_mem(p, "efuse");
+ if (compare_memory_masked(m, safemodeafter_efuse, safemode_efuse)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
progname, safemode_efuse, safemodeafter_efuse);