Annotation of qemu/roms/openbios/utils/devbios/programming.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *                     OpenBIOS - free your system! 
                      3:  *              ( firmware/flash device driver for Linux )
                      4:  *                          
                      5:  *  programming.c - flash device programming and probing algorithms.  
                      6:  *  
                      7:  *  This program is part of a free implementation of the IEEE 1275-1994 
                      8:  *  Standard for Boot (Initialization Configuration) Firmware.
                      9:  *
                     10:  *  Copyright (C) 1998-2004  Stefan Reinauer, <[email protected]>
                     11:  *
                     12:  *  This program is free software; you can redistribute it and/or modify
                     13:  *  it under the terms of the GNU General Public License as published by
                     14:  *  the Free Software Foundation; version 2 of the License.
                     15:  *
                     16:  *  This program is distributed in the hope that it will be useful,
                     17:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     18:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     19:  *  GNU General Public License for more details.
                     20:  *
                     21:  *  You should have received a copy of the GNU General Public License
                     22:  *  along with this program; if not, write to the Free Software
                     23:  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
                     24:  *
                     25:  */
                     26: 
                     27: // <-- C++ style comments are for experimental comments only.
                     28: // They will disappear as soon as I fixed all the stuff.
                     29: 
                     30: /* #define DEBUG_PROBING */
                     31: 
                     32: #include <linux/config.h>
                     33: #include <linux/version.h>
                     34: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) && defined(MODVERSIONS)
                     35: #include <linux/modversions.h>
                     36: #endif
                     37: 
                     38: #include <linux/pci.h>
                     39: #include <linux/errno.h>
                     40: #include <linux/types.h>
                     41: #include <linux/vmalloc.h>
                     42: #include <linux/delay.h>
                     43: #include <linux/spinlock.h>
                     44: #include <asm/io.h>
                     45: #include <asm/delay.h>
                     46: #include <asm/uaccess.h>
                     47: 
                     48: #include "bios.h"
                     49: #include "pcisets.h"
                     50: #include "flashchips.h"
                     51: #include "programming.h"
                     52: 
                     53: struct flashdevice flashdevices[BIOS_MAXDEV];
                     54: int flashcount;
                     55: 
                     56: /*
                     57:  * ******************************************
                     58:  *
                     59:  *     flashchip handling
                     60:  *
                     61:  * ****************************************** 
                     62:  */
                     63: 
                     64: 
                     65: void flash_command (unsigned char *addr, unsigned char command)
                     66: #if 1
                     67: {
                     68:        flash_writeb(addr, 0x5555, 0xaa);
                     69:        flash_writeb(addr, 0x2AAA, 0x55);
                     70:        flash_writeb(addr, 0x5555, command);
                     71: }
                     72: void fwh_flash_command(unsigned char *addr, unsigned char command)
                     73: #endif
                     74: {
                     75:        flash_writeb(addr, 0x75555, 0xaa);
                     76:        flash_writeb(addr, 0x72aaa, 0x55);
                     77:        flash_writeb(addr, 0x75555, command);
                     78: }
                     79: 
                     80: #define CFLASH flashdevices[flashcount]
                     81: int flash_probe_address(void *address)
                     82: {
                     83:        int flashnum=0, manufnum=0, sectors=0;
                     84:        unsigned short flash_id, testflash;
                     85:        unsigned long flags;
                     86: #ifdef DEBUG_PROBING
                     87:        printk( KERN_DEBUG "BIOS: Probing for flash chip @0x%08lx\n", (unsigned long) address);
                     88: #endif
                     89: 
                     90: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
                     91:        save_flags(flags);
                     92: #endif
                     93:        spin_lock_irqsave(&bios_lock, flags);
                     94: 
                     95:        testflash= (flash_readb(address, 0))+(flash_readb(address, 1)<<8);
                     96: 
                     97:        /* 1st method: Intel, Atmel listen to this.. */
                     98: 
                     99:        flash_command(address, 0x90);
                    100:        udelay(20);
                    101: 
                    102:        flash_id = (flash_readb(address, 0))+(flash_readb(address, 1)<<8);
                    103: 
                    104: #ifdef DEBUG_PROBING
                    105:        printk (KERN_DEBUG "BIOS: testflash[%04x] flash_id[%04x]\n",
                    106:                testflash, flash_id); 
                    107: #endif
                    108:        
                    109:        /* 2nd method: Winbond (I think this is Jedec standard) */
                    110: 
                    111:        if (flash_id==testflash) {
                    112: #ifdef DEBUG_PROBING
                    113:                printk (KERN_DEBUG "BIOS: Trying 2nd ID method.\n"); 
                    114: #endif
                    115:                flash_command(address, 0xf0); /* Reset */
                    116:                udelay(20);
                    117: 
                    118:                flash_command(address, 0x80);
                    119:                flash_command(address, 0x60);
                    120:                udelay(20);
                    121: 
                    122:                flash_id = (flash_readb(address, 0))+(flash_readb(address, 1)<<8);
                    123: #ifdef DEBUG_PROBING
                    124:        printk (KERN_DEBUG "BIOS: testflash[%04x] flash_id[%04x]\n",
                    125:                testflash, flash_id); 
                    126: #endif
                    127:        }
                    128: 
                    129:        /* 3rd Method: Some Winbonds seem to want this */
                    130: 
                    131:        if (flash_id==testflash) {
                    132: #ifdef DEBUG_PROBING
                    133:                printk (KERN_DEBUG "BIOS: Trying 3rd ID method.\n"); 
                    134: #endif
                    135:                flash_command(address, 0xf0); /* Reset again */
                    136:                udelay(20);
                    137: 
                    138:                flash_command(address, 0x80);
                    139:                flash_command(address, 0x20);
                    140:                udelay(20);
                    141: 
                    142:                flash_id = (flash_readb(address, 0))+(flash_readb(address, 1)<<8);
                    143: #ifdef DEBUG_PROBING
                    144:        printk (KERN_DEBUG "BIOS: testflash[%04x] flash_id[%04x]\n",
                    145:                testflash, flash_id); 
                    146: #endif
                    147:        }
                    148: 
                    149:        if (flash_id==0x7f7f && flash_readb(address, 0x100)==0x1c) {
                    150:                /* We have an Eon flashchip. They keep their
                    151:                 * device id at 0x101 instead of 0x1
                    152:                 */
                    153:                printk(KERN_INFO "BIOS: Eon flash device detected\n");
                    154:                flash_id=(flash_readb(address, 0x1))+(flash_readb(address, 0x101)<<8);
                    155:        }
                    156: 
                    157:        flash_command(address, 0xf0);
                    158:        udelay(20);
                    159: 
                    160:        spin_unlock_irqrestore(&bios_lock, flags);
                    161: 
                    162:        if (flash_id==testflash) return 0; /* Nothing found :-( */
                    163: 
                    164:        while (flashchips[flashnum].id!=0) {
                    165:                if (flash_id==flashchips[flashnum].id) 
                    166:                        break;
                    167:                flashnum++;
                    168:        }
                    169: 
                    170:        while (manufacturers[manufnum].id!=0) {
                    171:                if ((flash_id&0xff)==manufacturers[manufnum].id) 
                    172:                        break;
                    173:                manufnum++;
                    174:        }
                    175:        
                    176:        if (flashchips[flashnum].id) {
                    177:                while (flashchips[flashnum].sectors[sectors]<flashchips[flashnum].size)
                    178:                        sectors++;
                    179:        }
                    180: 
                    181:        if (flashcount >= BIOS_MAXDEV) {
                    182:                printk(KERN_DEBUG "BIOS: Too many flash devices found.\n");
                    183:                return -1;
                    184:        }
                    185: 
                    186:        CFLASH.flashnum = flashnum;
                    187:        CFLASH.manufnum = manufnum;
                    188:        CFLASH.id       = flash_id;
                    189:        CFLASH.size     = (flashchips[flashnum].size<<10);
                    190:        CFLASH.sectors  = sectors;
                    191:        CFLASH.open_mode= 0;
                    192:        CFLASH.open_cnt = 0;
                    193: 
                    194:        return 1;
                    195: }
                    196: 
                    197: void flash_probe_area(unsigned long romaddr, unsigned long romsize, 
                    198:                int map_always)
                    199: {
                    200:        unsigned long probeaddr;
                    201:        unsigned char *mapped;
                    202: 
                    203:        mapped=ioremap(romaddr, romsize);
                    204:        
                    205:        devices[flashdevices[currflash].idx].activate();
                    206:        
                    207:        probeaddr=(unsigned long)mapped;
                    208:        
                    209:        while ( probeaddr < (unsigned long)mapped + romsize - 0x5555 ) {
                    210:                if ( flash_probe_address ((void *)probeaddr) != 1) {
                    211:                        probeaddr += 4*1024;
                    212:                        continue;
                    213:                }
                    214:                
                    215:                CFLASH.offset   = probeaddr-(unsigned long)mapped;
                    216:                CFLASH.mapped   = (unsigned long)mapped;
                    217:                CFLASH.physical = romaddr+CFLASH.offset;
                    218:                
                    219:                printk( KERN_INFO "BIOS: flash device with size "
                    220:                                "%dk (ID 0x%04x) found.\n", 
                    221:                                CFLASH.size >> 10, CFLASH.id);
                    222:                
                    223:                printk( KERN_INFO "BIOS:   physical address "
                    224:                                "0x%08lx (va=0x%08lx+0x%lx).\n",
                    225:                                CFLASH.physical, (unsigned long)CFLASH.mapped,
                    226:                                CFLASH.offset);
                    227: 
                    228:                if (flashchips[CFLASH.flashnum].flags&f_fwh_compl) {
                    229:                        unsigned long t_lk;
                    230:                        unsigned int i=7;
                    231:                        printk(KERN_INFO "BIOS:   FWH compliant "
                    232:                                                        "chip detected.\n");
                    233:                        for (t_lk=0xffb80002; t_lk<=0xffbf0002; t_lk+=0x10000) 
                    234:                        {
                    235:                                printk(KERN_INFO "Lock register %d "
                    236:                                                 "(0x%08lx): 0x%x\n",
                    237:                                                i, t_lk, (unsigned int)
                    238:                                                (readb(phys_to_virt(t_lk))));
                    239:                                i--;
                    240:                        }
                    241:                }
                    242:                flashcount++;
                    243:                currflash++;
                    244: #ifdef MULTIPLE_FLASH
                    245:                probeaddr += flashdevices[flashcount-1].size;
                    246:                flashdevices[flashcount].mapped=flashdevices[flashcount-1].mapped;
                    247:                flashdevices[flashcount].data=flashdevices[flashcount-1].data;
                    248:                continue;
                    249: #else
                    250:                break;
                    251: #endif
                    252:        }
                    253: 
                    254:        /* We might want to always map the memory
                    255:         * region in certain cases
                    256:         */
                    257: 
                    258:        if (map_always) {
                    259:                CFLASH.flashnum = 0;
                    260:                CFLASH.manufnum = 0;
                    261:                CFLASH.id       = 0;
                    262:                CFLASH.size     = romsize;
                    263:                CFLASH.sectors  = 0;
                    264:                CFLASH.open_mode= 0;
                    265:                CFLASH.open_cnt = 0;
                    266:                CFLASH.offset   = 0;
                    267:                CFLASH.mapped   = (unsigned long)mapped;
                    268:                CFLASH.physical = romaddr;
                    269:                printk( KERN_INFO "BIOS: rom device with size "
                    270:                                "%dk registered.\n", CFLASH.size >> 10);
                    271:                flashcount++; currflash++;
                    272:                return;
                    273:        }
                    274:        
                    275:        /* We found nothing in this area, so let's unmap it again */
                    276:        
                    277:        if (flashcount && flashdevices[flashcount-1].mapped != (unsigned long)mapped)
                    278:                iounmap(mapped);
                    279: 
                    280:        devices[flashdevices[currflash].idx].deactivate();
                    281: }
                    282: 
                    283: #undef CFLASH
                    284: 
                    285: void flash_program (unsigned char *addr)
                    286: {
                    287:        flash_command(addr, 0xa0);
                    288: }
                    289: 
                    290: void flash_program_atmel (unsigned char *addr)
                    291: {
                    292:        flash_command(addr, 0x80);
                    293:        flash_command(addr, 0x20);
                    294: }
                    295: 
                    296: int flash_erase (unsigned char *addr, unsigned int flashnum) 
                    297: {
                    298:        flash_command(addr, 0x80);
                    299:        flash_command(addr, 0x10);
                    300:        udelay(80);
                    301:        return flash_ready_toggle(addr, 0);
                    302: }
                    303: 
                    304: int flash_erase_sectors (unsigned char *addr, unsigned int flashnum, unsigned int startsec, unsigned int endsec) 
                    305: {
                    306:        unsigned int sector;
                    307:   
                    308:        if (!(flashchips[flashnum].flags & f_slow_sector_erase)) {
                    309:                flash_command(addr, 0x80);
                    310: 
                    311:                if (flashchips[flashnum].flags&f_fwh_compl) {
                    312:                        flash_writeb(addr, 0x75555,0xaa);
                    313:                        flash_writeb(addr, 0x72aaa,0x55);
                    314:                } else {
                    315:                        flash_writeb(addr, 0x5555,0xaa);
                    316:                        flash_writeb(addr, 0x2aaa,0x55);
                    317:                }
                    318:     
                    319:                for (sector=startsec; sector <= endsec; sector++) {
                    320:                        flash_writeb (addr, flashchips[flashnum].sectors[sector]*1024, 0x30);
                    321:                }
                    322:     
                    323:                udelay(150); // 80 max normally, wait 150usec to be sure
                    324: #if 0
                    325:                if (flashchips[flashnum].flags&f_fwh_compl)
                    326: #endif
                    327:                        return flash_ready_toggle(addr, flashchips[flashnum].sectors[sector-1]*1024);
                    328: #if 0
                    329:                else
                    330:                        return flash_ready_poll(addr, flashchips[flashnum].sectors[sector-1]*1024, 0xff);
                    331: #endif
                    332:        }
                    333:   
                    334:        /* sectors must be sent the sector erase command for every sector */
                    335:        for (sector=startsec; sector <= endsec; sector++) {
                    336:                flash_command(addr, 0x80);
                    337:                if (flashchips[flashnum].flags&f_fwh_compl) {
                    338:                        flash_writeb(addr, 0x75555,0xaa);
                    339:                        flash_writeb(addr, 0x72aaa,0x55);
                    340:                } else {
                    341:                        flash_writeb(addr, 0x5555,0xaa);
                    342:                        flash_writeb(addr, 0x2aaa,0x55);
                    343:                }
                    344:     
                    345:                flash_writeb(addr, flashchips[flashnum].sectors[sector]*1024, 0x30);
                    346:                udelay(150);
                    347: #if 0
                    348:                if (flashchips[flashnum].flags&f_fwh_compl)
                    349: #endif
                    350:                        flash_ready_toggle(addr, flashchips[flashnum].sectors[sector] *1024);
                    351: #if 0
                    352:                else
                    353:                        flash_ready_poll(addr, flashchips[flashnum].sectors[sector]*1024, 0xff);
                    354: #endif
                    355:        }
                    356: 
                    357:        return 0;
                    358: 
                    359: }
                    360: 
                    361: /* waiting for the end of programming/erasure by using the toggle method.
                    362:  * As long as there is a programming procedure going on, bit 6 of the last
                    363:  * written byte is toggling it's state with each consecutive read. 
                    364:  * The toggling stops as soon as the procedure is completed.
                    365:  * This function returns 0 if everything is ok, 1 if an error occured
                    366:  * while programming was in progress.
                    367:  */ 
                    368: 
                    369: int flash_ready_toggle (unsigned char *addr, unsigned int offset)
                    370: {
                    371:        unsigned long int timeout=0;
                    372:        unsigned char oldflag, flag;
                    373:        int loop=1;
                    374: 
                    375:        oldflag=flash_readb(addr, offset) & 0x40;
                    376: 
                    377:        while (loop && (timeout<0x7fffffff)) {
                    378:                flag=flash_readb(addr, offset) & 0x40;
                    379: 
                    380:                if (flag == oldflag)
                    381:                        loop=0;
                    382:                
                    383:                oldflag=flag;
                    384:                timeout++;
                    385:        }
                    386: 
                    387:        if (loop) {
                    388:                printk(KERN_DEBUG "BIOS: operation timed out (Toggle)\n");
                    389:                return 1;
                    390:        }
                    391:        
                    392:        return 0;
                    393: }
                    394: 
                    395: /* This functions is similar to the above one. While a programming
                    396:  * procedure is going on, bit 7 of the last written data byte is
                    397:  * inverted. When the procedure is completed, bit 7 contains the
                    398:  * correct data value
                    399:  */
                    400: 
                    401: int flash_ready_poll (unsigned char *addr, unsigned int offset, unsigned char data)
                    402: {
                    403:        unsigned long int timeout=0;
                    404:        unsigned char flag;
                    405: 
                    406:        flag=flash_readb(addr, offset);
                    407: 
                    408:        while ( ( flag & 0x80) != ( data & 0x80)) {
                    409:                if ( ( flag & 0x80 ) == ( data & 0x80 ) ) {
                    410: #ifdef DBGTIMEOUT
                    411:                        printk(KERN_DEBUG "BIOS: Timeout value (EOT Polling) %ld\n",timeout);
                    412: #endif
                    413:                        return 0;
                    414:                }                       
                    415:                flag=flash_readb(addr, offset);
                    416:                if (timeout++>12800) {  // 10 times more than usual.
                    417:                        printk(KERN_ERR "BIOS: EOT Polling timed out at 0x%08x."
                    418:                                " Try again or increase max. timeout.\n",offset);
                    419:                        return 1;
                    420:                }
                    421:                if ((flag & 0x80) == ( data & 0x80)) {
                    422:                  flag=flash_readb(addr, offset);
                    423:                }
                    424:        }
                    425: #ifdef DBGTIMEOUT
                    426:        printk(KERN_DEBUG "BIOS: Timeout value (EOT Polling) %ld\n",timeout);
                    427: #endif
                    428: 
                    429:        flag=flash_readb(addr, offset);
                    430:        if ( ( flag & 0x80 ) == ( data & 0x80 ) ) return 0; else return 1;
                    431: }
                    432: 
                    433: 
                    434: 
                    435: void iflash_program_byte (unsigned char *addr, unsigned int offset, unsigned char data)
                    436: {
                    437:        unsigned long int timeout=0;
                    438:        unsigned char flag;
                    439: 
                    440:        flash_writeb (addr, offset, 0x40);
                    441:        flash_writeb (addr, offset, data);
                    442: 
                    443:        flash_writeb (addr, offset, 0x70);      /* Read Status */
                    444:        do {
                    445:                flag=flash_readb (addr, offset);
                    446:                if (timeout++>100) { // usually 2 or 3 :-)
                    447:                        printk(KERN_ERR "BIOS: Intel programming timed out at"
                    448:                                "0x%08x. Try again or increase max. timeout.\n",offset);
                    449:                        return;
                    450:                }
                    451:        } while ((flag&0x80) != 0x80);
                    452: 
                    453: #ifdef DBGTIMEOUT
                    454:        printk (KERN_DEBUG"BIOS: Timeout value (Intel byte program) %ld\n",timeout);
                    455: #endif
                    456: 
                    457:        if (flag&0x18) {
                    458:                flash_writeb (addr, offset, 0x50);      /* Reset Status Register */
                    459:                printk (KERN_ERR "BIOS: Error occured, please repeat write operation. (intel)\n");
                    460:        }
                    461: 
                    462:        flash_writeb (addr, offset, 0xff);
                    463: }
                    464: 
                    465: 
                    466: 
                    467: int  iflash_erase_sectors (unsigned char *addr, unsigned int flashnum, unsigned int startsec, unsigned int endsec)
                    468: {
                    469:        unsigned long int timeout;
                    470:        unsigned int sector, offset=0;
                    471:        unsigned char flag;
                    472: 
                    473:        for (sector=startsec; sector<=endsec; sector++) {
                    474:                offset=(flashchips[flashnum].sectors[sector]*1024);
                    475:                flash_writeb (addr, offset, 0x20);
                    476:                flash_writeb (addr, offset, 0xd0);
                    477: 
                    478:                flash_writeb (addr, offset, 0x70);      /* Read Status */
                    479:                timeout=0;
                    480:                do {
                    481:                        flag=flash_readb (addr, offset);
                    482:                        if (timeout++>1440000) { // usually 144000
                    483:                                printk(KERN_ERR "BIOS: Intel sector erase timed out at 0x%08x. Try again or increase max. timeout.\n",offset);
                    484:                                return 1;
                    485:                        }
                    486:                } while ((flag&0x80) != 0x80);
                    487: 
                    488: #ifdef DBGTIMEOUT
                    489:                printk (KERN_DEBUG "BIOS: Timeout value (Intel sector erase) %ld\n",timeout);
                    490: #endif
                    491: 
                    492:                if (flag&0x28) {
                    493:                        flash_writeb (addr, offset, 0x50);
                    494:                        flash_writeb (addr, offset, 0xff);
                    495:                        return 1; /* Error! */
                    496:                }
                    497:        }
                    498: 
                    499:        flash_writeb (addr, offset, 0xff);
                    500:        return 0;       
                    501: }
                    502: 
                    503: 
                    504: 
                    505: unsigned char flash_readb(unsigned char *addr, unsigned int offset)
                    506: {
                    507: #if defined(__alpha__)
                    508:        if (flashdevices[currflash].data==(void *)0xfff80000) {
                    509:                if (offset<0x80000)
                    510:                        outb(0x00,0x800);
                    511:                else {
                    512:                        outb(0x01, 0x800);
                    513:                        offset-=0x80000;
                    514:                }
                    515:        }
                    516: #endif 
                    517:        return readb(addr+offset);
                    518: }
                    519: 
                    520: 
                    521: 
                    522: void flash_writeb(unsigned char *addr, unsigned int offset, unsigned char data) 
                    523: {
                    524: #if defined(__alpha__)
                    525:        if (flashdevices[currflash].data==(void *)0xfff80000) {
                    526:                if (offset<0x80000)
                    527:                        outb(0x00,0x800);
                    528:                else {
                    529:                        outb(0x01, 0x800);
                    530:                        offset-=0x80000;
                    531:                }
                    532:        }
                    533: #endif 
                    534: /* 
                    535:        printk(KERN_DEBUG "BIOS: writing 0x%02x to 0x%lx+0x%x\n",
                    536:                                                        data,bios,offset);
                    537:  */
                    538:        writeb(data,addr+offset);
                    539: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.