* https://openbios.org/roundup/linuxbios/issue96 - SST_49LF040B flash support for...
[coreboot.git] / util / flashrom / flash_enable.c
1 /*
2  *   flash rom utility: enable flash writes
3  *
4  *   Copyright (C) 2000-2004 ???
5  *   Copyright (C) 2005 coresystems GmbH <stepan@openbios.org>
6  *
7  *   This program is free software; you can redistribute it and/or
8  *   modify it under the terms of the GNU General Public License
9  *   version 2
10  *
11  */
12
13 #include <sys/io.h>
14 #include <stdio.h>
15 #include <pci/pci.h>
16 #include <stdlib.h>
17 #include <stdint.h>
18 #include <string.h>
19 #include "lbtable.h"
20 #include "debug.h"
21
22 // We keep this for the others.
23 static struct pci_access *pacc;
24
25 static int enable_flash_sis630(struct pci_dev *dev, char *name)
26 {
27         char b;
28
29         /* get io privilege access PCI configuration space */
30         if (iopl(3) != 0) {
31                 perror("Can not set io priviliage");
32                 exit(1);
33         }
34
35         /* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */
36         outl(0x80000840, 0x0cf8);
37         b = inb(0x0cfc) | 0x0b;
38         outb(b, 0xcfc);
39         /* Flash write enable on SiS 540/630 */
40         outl(0x80000845, 0x0cf8);
41         b = inb(0x0cfd) | 0x40;
42         outb(b, 0xcfd);
43
44         /* The same thing on SiS 950 SuperIO side */
45         outb(0x87, 0x2e);
46         outb(0x01, 0x2e);
47         outb(0x55, 0x2e);
48         outb(0x55, 0x2e);
49
50         if (inb(0x2f) != 0x87) {
51                 outb(0x87, 0x4e);
52                 outb(0x01, 0x4e);
53                 outb(0x55, 0x4e);
54                 outb(0xaa, 0x4e);
55                 if (inb(0x4f) != 0x87) {
56                         printf("Can not access SiS 950\n");
57                         return -1;
58                 }
59                 outb(0x24, 0x4e);
60                 b = inb(0x4f) | 0xfc;
61                 outb(0x24, 0x4e);
62                 outb(b, 0x4f);
63                 outb(0x02, 0x4e);
64                 outb(0x02, 0x4f);
65         }
66
67         outb(0x24, 0x2e);
68         printf("2f is %#x\n", inb(0x2f));
69         b = inb(0x2f) | 0xfc;
70         outb(0x24, 0x2e);
71         outb(b, 0x2f);
72
73         outb(0x02, 0x2e);
74         outb(0x02, 0x2f);
75
76         return 0;
77 }
78
79 static int enable_flash_e7500(struct pci_dev *dev, char *name)
80 {
81         /* register 4e.b gets or'ed with one */
82         uint8_t old, new;
83         /* if it fails, it fails. There are so many variations of broken mobos
84          * that it is hard to argue that we should quit at this point. 
85          */
86
87         old = pci_read_byte(dev, 0x4e);
88
89         new = old | 1;
90
91         if (new == old)
92                 return 0;
93
94         pci_write_byte(dev, 0x4e, new);
95
96         if (pci_read_byte(dev, 0x4e) != new) {
97                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
98                        0x4e, new, name);
99                 return -1;
100         }
101         return 0;
102 }
103
104 enum {
105         ICH4_BIOS_CNTL = 0x4e,
106         /* see page 375 of "Intel ICH7 External Design Specification"
107          * http://download.intel.com/design/chipsets/datashts/30701302.pdf */
108         ICH7_BIOS_CNTL = 0xdc,
109 };
110 static int enable_flash_ich(struct pci_dev *dev, char *name, int bios_cntl)
111 {
112         /* register 4e.b gets or'ed with one */
113         uint8_t old, new;
114         /* if it fails, it fails. There are so many variations of broken mobos
115          * that it is hard to argue that we should quit at this point. 
116          */
117
118         old = pci_read_byte(dev, bios_cntl);
119
120         new = old | 1;
121
122         if (new == old)
123                 return 0;
124
125         pci_write_byte(dev, bios_cntl, new);
126
127         if (pci_read_byte(dev, bios_cntl) != new) {
128                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
129                        bios_cntl, new, name);
130                 return -1;
131         }
132         return 0;
133 }
134
135 static int enable_flash_ich4(struct pci_dev *dev, char *name)
136 {
137         return enable_flash_ich(dev, name, ICH4_BIOS_CNTL);
138 }
139
140 static int enable_flash_ich7(struct pci_dev *dev, char *name)
141 {
142         return enable_flash_ich(dev, name, ICH7_BIOS_CNTL);
143 }
144
145 static int enable_flash_vt8235(struct pci_dev *dev, char *name)
146 {
147         uint8_t old, new, val;
148         unsigned int base;
149         int ok;
150
151         /* get io privilege access PCI configuration space */
152         if (iopl(3) != 0) {
153                 perror("Can not set io priviliage");
154                 exit(1);
155         }
156
157         old = pci_read_byte(dev, 0x40);
158
159         new = old | 0x10;
160
161         if (new == old)
162                 return 0;
163
164         ok = pci_write_byte(dev, 0x40, new);
165         if (ok != 0) {
166                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
167                        old, new, name);
168         }
169
170         /* enable GPIO15 which is connected to write protect. */
171         base = ((pci_read_byte(dev, 0x88) & 0x80) | pci_read_byte(dev, 0x89) << 8);
172         val = inb(base + 0x4d);
173         val |= 0x80;
174         outb(val, base + 0x4d);
175
176         if (ok != 0) {
177                 return -1;
178         } else {
179                 return 0;
180         }
181 }
182
183 static int enable_flash_vt8231(struct pci_dev *dev, char *name)
184 {
185         uint8_t val;
186
187         val = pci_read_byte(dev, 0x40);
188         val |= 0x10;
189         pci_write_byte(dev, 0x40, val);
190
191         if (pci_read_byte(dev, 0x40) != val) {
192                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
193                        0x40, val, name);
194                 return -1;
195         }
196         return 0;
197 }
198
199 static int enable_flash_cs5530(struct pci_dev *dev, char *name)
200 {
201         uint8_t new;
202
203         pci_write_byte(dev, 0x52, 0xee);
204
205         new = pci_read_byte(dev, 0x52);
206
207         if (new != 0xee) {
208                 printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
209                        0x52, new, name);
210                 return -1;
211         }
212         
213         new = pci_read_byte(dev, 0x5b) | 0x20;
214         pci_write_byte(dev, 0x5b, new);
215         
216         return 0;
217 }
218
219
220 static int enable_flash_sc1100(struct pci_dev *dev, char *name)
221 {
222         uint8_t new;
223
224         pci_write_byte(dev, 0x52, 0xee);
225
226         new = pci_read_byte(dev, 0x52);
227
228         if (new != 0xee) {
229                 printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
230                        0x52, new, name);
231                 return -1;
232         }
233         return 0;
234 }
235
236 static int enable_flash_sis5595(struct pci_dev *dev, char *name)
237 {
238         uint8_t new, newer;
239
240         new = pci_read_byte(dev, 0x45);
241
242         /* clear bit 5 */
243         new &= (~0x20);
244         /* set bit 2 */
245         new |= 0x4;
246
247         pci_write_byte(dev, 0x45, new);
248
249         newer = pci_read_byte(dev, 0x45);
250         if (newer != new) {
251                 printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
252                        0x45, new, name);
253                 printf("Stuck at 0x%x\n", newer);
254                 return -1;
255         }
256         return 0;
257 }
258
259 static int enable_flash_amd8111(struct pci_dev *dev, char *name)
260 {
261         /* register 4e.b gets or'ed with one */
262         uint8_t old, new;
263         /* if it fails, it fails. There are so many variations of broken mobos
264          * that it is hard to argue that we should quit at this point. 
265          */
266
267         /* enable decoding at 0xffb00000 to 0xffffffff */
268         old = pci_read_byte(dev, 0x43);
269         new = old | 0xC0;
270         if (new != old) {
271                 pci_write_byte(dev, 0x43, new);
272                 if (pci_read_byte(dev, 0x43) != new) {
273                         printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
274                                0x43, new, name);
275                 }
276         }
277
278         old = pci_read_byte(dev, 0x40);
279         new = old | 0x01;
280         if (new == old)
281                 return 0;
282         pci_write_byte(dev, 0x40, new);
283
284         if (pci_read_byte(dev, 0x40) != new) {
285                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
286                        0x40, new, name);
287                 return -1;
288         }
289         return 0;
290 }
291
292 //By yhlu
293 static int enable_flash_ck804(struct pci_dev *dev, char *name)
294 {
295         /* register 4e.b gets or'ed with one */
296         uint8_t old, new;
297         /* if it fails, it fails. There are so many variations of broken mobos
298          * that it is hard to argue that we should quit at this point. 
299          */
300
301         //dump_pci_device(dev); 
302         
303         old = pci_read_byte(dev, 0x88);
304         new = old | 0xc0;
305         if (new != old) {
306                 pci_write_byte(dev, 0x88, new);
307                 if (pci_read_byte(dev, 0x88) != new) {
308                         printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
309                                0x88, new, name);
310                 }
311         }
312
313         old = pci_read_byte(dev, 0x6d);
314         new = old | 0x01;
315         if (new == old)
316                 return 0;
317         pci_write_byte(dev, 0x6d, new);
318
319         if (pci_read_byte(dev, 0x6d) != new) {
320                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
321                        0x6d, new, name);
322                 return -1;
323         }
324         return 0;
325 }
326
327 static int enable_flash_sb400(struct pci_dev *dev, char *name)
328 {
329         uint8_t tmp;
330
331         struct pci_filter f;
332         struct pci_dev *smbusdev;
333
334         /* get io privilege access */
335         if (iopl(3) != 0) {
336                 perror("Can not set io priviliage");
337                 exit(1);
338         }
339
340         /* then look for the smbus device */
341         pci_filter_init((struct pci_access *) 0, &f);
342         f.vendor = 0x1002;
343         f.device = 0x4372;
344         
345         for (smbusdev = pacc->devices; smbusdev; smbusdev = smbusdev->next) {
346                 if (pci_filter_match(&f, smbusdev)) {
347                         break;
348                 }
349         }
350         
351         if(!smbusdev) {
352                 perror("smbus device not found. aborting\n");
353                 exit(1);
354         }
355         
356         // enable some smbus stuff
357         tmp=pci_read_byte(smbusdev, 0x79);
358         tmp|=0x01;
359         pci_write_byte(smbusdev, 0x79, tmp);
360
361         // change southbridge
362         tmp=pci_read_byte(dev, 0x48);
363         tmp|=0x21;
364         pci_write_byte(dev, 0x48, tmp);
365
366         // now become a bit silly. 
367         tmp=inb(0xc6f);
368         outb(tmp,0xeb);
369         outb(tmp, 0xeb);
370         tmp|=0x40;
371         outb(tmp, 0xc6f);
372         outb(tmp, 0xeb);
373         outb(tmp, 0xeb);
374
375         return 0;
376 }
377
378 typedef struct penable {
379         unsigned short vendor, device;
380         char *name;
381         int (*doit) (struct pci_dev * dev, char *name);
382 } FLASH_ENABLE;
383
384 static FLASH_ENABLE enables[] = {
385         {0x1039, 0x0630, "sis630", enable_flash_sis630},
386         {0x8086, 0x2480, "E7500", enable_flash_e7500},
387         {0x8086, 0x24c0, "ICH4", enable_flash_ich4},
388         {0x8086, 0x24cc, "ICH4-M", enable_flash_ich4},
389         {0x8086, 0x24d0, "ICH5", enable_flash_ich4},
390         {0x8086, 0x27b8, "ICH7", enable_flash_ich7},
391         {0x1106, 0x8231, "VT8231", enable_flash_vt8231},
392         {0x1106, 0x3177, "VT8235", enable_flash_vt8235},
393         {0x1078, 0x0100, "CS5530", enable_flash_cs5530},
394         {0x100b, 0x0510, "SC1100", enable_flash_sc1100},
395         {0x1039, 0x0008, "SIS5595", enable_flash_sis5595},
396         {0x1022, 0x7468, "AMD8111", enable_flash_amd8111},
397         // this fallthrough looks broken.
398         {0x10de, 0x0050, "NVIDIA CK804", enable_flash_ck804}, // LPC
399         {0x10de, 0x0051, "NVIDIA CK804", enable_flash_ck804}, // Pro
400         {0x10de, 0x00d3, "NVIDIA CK804", enable_flash_ck804}, // Slave, should not be here, to fix known bug for A01.
401         {0x1002, 0x4377, "ATI SB400", enable_flash_sb400}, // ATI Technologies Inc IXP SB400 PCI-ISA Bridge (rev 80)
402 };
403
404 static int mbenable_island_aruma(void)
405 {
406 #define EFIR 0x2e      /* Extended function index register, either 0x2e or 0x4e    */
407 #define EFDR EFIR + 1  /* Extended function data register, one plus the index reg. */
408         char b;
409
410 /*  Disable the flash write protect.  The flash write protect is 
411  *  connected to the WinBond w83627hf GPIO 24.
412  */
413
414         /* get io privilege access winbond config space */
415         if (iopl(3) != 0) {
416                 perror("Can not set io priviliage");
417                 exit(1);
418         }
419         
420         printf("Disabling mainboard flash write protection.\n");
421
422         outb(0x87, EFIR); // sequence to unlock extended functions
423         outb(0x87, EFIR);
424
425         outb(0x20, EFIR); // SIO device ID register
426         b = inb(EFDR); 
427         printf_debug("W83627HF device ID = 0x%x\n",b);
428
429         if (b != 0x52) {
430                 perror("Incorrect device ID, aborting write protect disable\n");
431                 exit(1);
432         }
433
434         outb(0x2b, EFIR); // GPIO multiplexed pin reg.
435         b = inb(EFDR) | 0x10; 
436         outb(0x2b, EFIR); 
437         outb(b, EFDR); // select GPIO 24 instead of WDTO
438
439         outb(0x7, EFIR); // logical device select
440         outb(0x8, EFDR); // point to device 8, GPIO port 2
441
442         outb(0x30, EFIR); // logic device activation control
443         outb(0x1, EFDR); // activate
444
445         outb(0xf0, EFIR); // GPIO 20-27 I/O selection register
446         b = inb(EFDR) & ~0x10; 
447         outb(0xf0, EFIR); 
448         outb(b, EFDR); // set GPIO 24 as an output
449
450         outb(0xf1, EFIR); // GPIO 20-27 data register
451         b = inb(EFDR) | 0x10; 
452         outb(0xf1, EFIR); 
453         outb(b, EFDR); // set GPIO 24
454
455         outb(0xaa, EFIR); // command to exit extended functions
456
457         return 0;
458 }
459
460 typedef struct mbenable {
461         char *vendor, *part;
462         int (*doit)(void);
463 } MAINBOARD_ENABLE;
464
465 static MAINBOARD_ENABLE mbenables[] = {
466         { "ISLAND", "ARUMA", mbenable_island_aruma },
467 };
468
469 int enable_flash_write()
470 {
471         int i;
472         struct pci_dev *dev = 0;
473         FLASH_ENABLE *enable = 0;
474
475         pacc = pci_alloc();     /* Get the pci_access structure */
476         /* Set all options you want -- here we stick with the defaults */
477         pci_init(pacc);         /* Initialize the PCI library */
478         pci_scan_bus(pacc);     /* We want to get the list of devices */
479
480         
481         /* First look whether we have to do something for this
482          * motherboard.
483          */
484         for (i = 0; i < sizeof(mbenables) / sizeof(mbenables[0]); i++) {
485                 if(lb_vendor && !strcmp(mbenables[i].vendor, lb_vendor) &&
486                    lb_part && !strcmp(mbenables[i].part, lb_part)) {
487                         mbenables[i].doit();
488                         break;
489                 }
490         }
491         
492         /* now let's try to find the chipset we have ... */
493         for (i = 0; i < sizeof(enables) / sizeof(enables[0]) && (!dev);
494              i++) {
495                 struct pci_filter f;
496                 struct pci_dev *z;
497                 /* the first param is unused. */
498                 pci_filter_init((struct pci_access *) 0, &f);
499                 f.vendor = enables[i].vendor;
500                 f.device = enables[i].device;
501                 for (z = pacc->devices; z; z = z->next)
502                         if (pci_filter_match(&f, z)) {
503                                 enable = &enables[i];
504                                 dev = z;
505                         }
506         }
507
508         /* now do the deed. */
509         if (enable) {
510                 printf("Enabling flash write on %s...", enable->name);
511                 if (enable->doit(dev, enable->name) == 0)
512                         printf("OK\n");
513         }
514         return 0;
515 }