Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * MTD map driver for BIOS Flash on Intel SCB2 boards
0004  * Copyright (C) 2002 Sun Microsystems, Inc.
0005  * Tim Hockin <thockin@sun.com>
0006  *
0007  * A few notes on this MTD map:
0008  *
0009  * This was developed with a small number of SCB2 boards to test on.
0010  * Hopefully, Intel has not introducted too many unaccounted variables in the
0011  * making of this board.
0012  *
0013  * The BIOS marks its own memory region as 'reserved' in the e820 map.  We
0014  * try to request it here, but if it fails, we carry on anyway.
0015  *
0016  * This is how the chip is attached, so said the schematic:
0017  * * a 4 MiB (32 Mib) 16 bit chip
0018  * * a 1 MiB memory region
0019  * * A20 and A21 pulled up
0020  * * D8-D15 ignored
0021  * What this means is that, while we are addressing bytes linearly, we are
0022  * really addressing words, and discarding the other byte.  This means that
0023  * the chip MUST BE at least 2 MiB.  This also means that every block is
0024  * actually half as big as the chip reports.  It also means that accesses of
0025  * logical address 0 hit higher-address sections of the chip, not physical 0.
0026  * One can only hope that these 4MiB x16 chips were a lot cheaper than 1MiB x8
0027  * chips.
0028  *
0029  * This driver assumes the chip is not write-protected by an external signal.
0030  * As of the this writing, that is true, but may change, just to spite me.
0031  *
0032  * The actual BIOS layout has been mostly reverse engineered.  Intel BIOS
0033  * updates for this board include 10 related (*.bio - &.bi9) binary files and
0034  * another separate (*.bbo) binary file.  The 10 files are 64k of data + a
0035  * small header.  If the headers are stripped off, the 10 64k files can be
0036  * concatenated into a 640k image.  This is your BIOS image, proper.  The
0037  * separate .bbo file also has a small header.  It is the 'Boot Block'
0038  * recovery BIOS.  Once the header is stripped, no further prep is needed.
0039  * As best I can tell, the BIOS is arranged as such:
0040  * offset 0x00000 to 0x4ffff (320k):  unknown - SCSI BIOS, etc?
0041  * offset 0x50000 to 0xeffff (640k):  BIOS proper
0042  * offset 0xf0000 ty 0xfffff (64k):   Boot Block region
0043  *
0044  * Intel's BIOS update program flashes the BIOS and Boot Block in separate
0045  * steps.  Probably a wise thing to do.
0046  */
0047 
0048 #include <linux/module.h>
0049 #include <linux/types.h>
0050 #include <linux/kernel.h>
0051 #include <asm/io.h>
0052 #include <linux/mtd/mtd.h>
0053 #include <linux/mtd/map.h>
0054 #include <linux/mtd/cfi.h>
0055 #include <linux/pci.h>
0056 #include <linux/pci_ids.h>
0057 
0058 #define MODNAME     "scb2_flash"
0059 #define SCB2_ADDR   0xfff00000
0060 #define SCB2_WINDOW 0x00100000
0061 
0062 
0063 static void __iomem *scb2_ioaddr;
0064 static struct mtd_info *scb2_mtd;
0065 static struct map_info scb2_map = {
0066     .name =      "SCB2 BIOS Flash",
0067     .size =      0,
0068     .bankwidth =  1,
0069 };
0070 static int region_fail;
0071 
0072 static int scb2_fixup_mtd(struct mtd_info *mtd)
0073 {
0074     int i;
0075     int done = 0;
0076     struct map_info *map = mtd->priv;
0077     struct cfi_private *cfi = map->fldrv_priv;
0078 
0079     /* barf if this doesn't look right */
0080     if (cfi->cfiq->InterfaceDesc != CFI_INTERFACE_X16_ASYNC) {
0081         printk(KERN_ERR MODNAME ": unsupported InterfaceDesc: %#x\n",
0082             cfi->cfiq->InterfaceDesc);
0083         return -1;
0084     }
0085 
0086     /* I wasn't here. I didn't see. dwmw2. */
0087 
0088     /* the chip is sometimes bigger than the map - what a waste */
0089     mtd->size = map->size;
0090 
0091     /*
0092      * We only REALLY get half the chip, due to the way it is
0093      * wired up - D8-D15 are tossed away.  We read linear bytes,
0094      * but in reality we are getting 1/2 of each 16-bit read,
0095      * which LOOKS linear to us.  Because CFI code accounts for
0096      * things like lock/unlock/erase by eraseregions, we need to
0097      * fudge them to reflect this.  Erases go like this:
0098      *   * send an erase to an address
0099      *   * the chip samples the address and erases the block
0100      *   * add the block erasesize to the address and repeat
0101      *   -- the problem is that addresses are 16-bit addressable
0102      *   -- we end up erasing every-other block
0103      */
0104     mtd->erasesize /= 2;
0105     for (i = 0; i < mtd->numeraseregions; i++) {
0106         struct mtd_erase_region_info *region = &mtd->eraseregions[i];
0107         region->erasesize /= 2;
0108     }
0109 
0110     /*
0111      * If the chip is bigger than the map, it is wired with the high
0112      * address lines pulled up.  This makes us access the top portion of
0113      * the chip, so all our erase-region info is wrong.  Start cutting from
0114      * the bottom.
0115      */
0116     for (i = 0; !done && i < mtd->numeraseregions; i++) {
0117         struct mtd_erase_region_info *region = &mtd->eraseregions[i];
0118 
0119         if (region->numblocks * region->erasesize > mtd->size) {
0120             region->numblocks = ((unsigned long)mtd->size /
0121                         region->erasesize);
0122             done = 1;
0123         } else {
0124             region->numblocks = 0;
0125         }
0126         region->offset = 0;
0127     }
0128 
0129     return 0;
0130 }
0131 
0132 /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */
0133 #define CSB5_FCR    0x41
0134 #define CSB5_FCR_DECODE_ALL 0x0e
0135 static int scb2_flash_probe(struct pci_dev *dev,
0136                 const struct pci_device_id *ent)
0137 {
0138     u8 reg;
0139 
0140     /* enable decoding of the flash region in the south bridge */
0141     pci_read_config_byte(dev, CSB5_FCR, &reg);
0142     pci_write_config_byte(dev, CSB5_FCR, reg | CSB5_FCR_DECODE_ALL);
0143 
0144     if (!request_mem_region(SCB2_ADDR, SCB2_WINDOW, scb2_map.name)) {
0145         /*
0146          * The BIOS seems to mark the flash region as 'reserved'
0147          * in the e820 map.  Warn and go about our business.
0148          */
0149         printk(KERN_WARNING MODNAME
0150             ": warning - can't reserve rom window, continuing\n");
0151         region_fail = 1;
0152     }
0153 
0154     /* remap the IO window (w/o caching) */
0155     scb2_ioaddr = ioremap(SCB2_ADDR, SCB2_WINDOW);
0156     if (!scb2_ioaddr) {
0157         printk(KERN_ERR MODNAME ": Failed to ioremap window!\n");
0158         if (!region_fail)
0159             release_mem_region(SCB2_ADDR, SCB2_WINDOW);
0160         return -ENOMEM;
0161     }
0162 
0163     scb2_map.phys = SCB2_ADDR;
0164     scb2_map.virt = scb2_ioaddr;
0165     scb2_map.size = SCB2_WINDOW;
0166 
0167     simple_map_init(&scb2_map);
0168 
0169     /* try to find a chip */
0170     scb2_mtd = do_map_probe("cfi_probe", &scb2_map);
0171 
0172     if (!scb2_mtd) {
0173         printk(KERN_ERR MODNAME ": flash probe failed!\n");
0174         iounmap(scb2_ioaddr);
0175         if (!region_fail)
0176             release_mem_region(SCB2_ADDR, SCB2_WINDOW);
0177         return -ENODEV;
0178     }
0179 
0180     scb2_mtd->owner = THIS_MODULE;
0181     if (scb2_fixup_mtd(scb2_mtd) < 0) {
0182         mtd_device_unregister(scb2_mtd);
0183         map_destroy(scb2_mtd);
0184         iounmap(scb2_ioaddr);
0185         if (!region_fail)
0186             release_mem_region(SCB2_ADDR, SCB2_WINDOW);
0187         return -ENODEV;
0188     }
0189 
0190     printk(KERN_NOTICE MODNAME ": chip size 0x%llx at offset 0x%llx\n",
0191            (unsigned long long)scb2_mtd->size,
0192            (unsigned long long)(SCB2_WINDOW - scb2_mtd->size));
0193 
0194     mtd_device_register(scb2_mtd, NULL, 0);
0195 
0196     return 0;
0197 }
0198 
0199 static void scb2_flash_remove(struct pci_dev *dev)
0200 {
0201     if (!scb2_mtd)
0202         return;
0203 
0204     /* disable flash writes */
0205     mtd_lock(scb2_mtd, 0, scb2_mtd->size);
0206 
0207     mtd_device_unregister(scb2_mtd);
0208     map_destroy(scb2_mtd);
0209 
0210     iounmap(scb2_ioaddr);
0211     scb2_ioaddr = NULL;
0212 
0213     if (!region_fail)
0214         release_mem_region(SCB2_ADDR, SCB2_WINDOW);
0215 }
0216 
0217 static struct pci_device_id scb2_flash_pci_ids[] = {
0218     {
0219       .vendor = PCI_VENDOR_ID_SERVERWORKS,
0220       .device = PCI_DEVICE_ID_SERVERWORKS_CSB5,
0221       .subvendor = PCI_ANY_ID,
0222       .subdevice = PCI_ANY_ID
0223     },
0224     { 0, }
0225 };
0226 
0227 static struct pci_driver scb2_flash_driver = {
0228     .name =     "Intel SCB2 BIOS Flash",
0229     .id_table = scb2_flash_pci_ids,
0230     .probe =    scb2_flash_probe,
0231     .remove =   scb2_flash_remove,
0232 };
0233 
0234 module_pci_driver(scb2_flash_driver);
0235 
0236 MODULE_LICENSE("GPL");
0237 MODULE_AUTHOR("Tim Hockin <thockin@sun.com>");
0238 MODULE_DESCRIPTION("MTD map driver for Intel SCB2 BIOS Flash");
0239 MODULE_DEVICE_TABLE(pci, scb2_flash_pci_ids);