1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2011 Carl-Daniel Hailfinger
5 * Copyright (C) 2012 Kyösti Mälkki <[email protected]>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17 #include <stdlib.h>
18 #include "flash.h"
19 #include "programmer.h"
20 #include "hwaccess_physmap.h"
21 #include "platform/pci.h"
22
23 struct it8212_data {
24 struct pci_dev *dev;
25 uint8_t *bar;
26 uint32_t decode_access;
27 };
28
29 #define PCI_VENDOR_ID_ITE 0x1283
30
31 static const struct dev_entry devs_it8212[] = {
32 {PCI_VENDOR_ID_ITE, 0x8212, NT, "ITE", "8212F PATA RAID"},
33
34 {0},
35 };
36
37 #define IT8212_MEMMAP_SIZE (128 * 1024)
38 #define IT8212_MEMMAP_MASK (IT8212_MEMMAP_SIZE - 1)
39
it8212_chip_writeb(const struct flashctx * flash,uint8_t val,chipaddr addr)40 static void it8212_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
41 {
42 const struct it8212_data *data = flash->mst->par.data;
43
44 pci_mmio_writeb(val, data->bar + (addr & IT8212_MEMMAP_MASK));
45 }
46
it8212_chip_readb(const struct flashctx * flash,const chipaddr addr)47 static uint8_t it8212_chip_readb(const struct flashctx *flash, const chipaddr addr)
48 {
49 const struct it8212_data *data = flash->mst->par.data;
50
51 return pci_mmio_readb(data->bar + (addr & IT8212_MEMMAP_MASK));
52 }
53
it8212_shutdown(void * par_data)54 static int it8212_shutdown(void *par_data)
55 {
56 struct it8212_data *data = par_data;
57
58 /* Restore ROM BAR decode state. */
59 pci_write_long(data->dev, PCI_ROM_ADDRESS, data->decode_access);
60
61 free(par_data);
62 return 0;
63 }
64
65 static const struct par_master par_master_it8212 = {
66 .chip_readb = it8212_chip_readb,
67 .chip_writeb = it8212_chip_writeb,
68 .shutdown = it8212_shutdown,
69 };
70
it8212_init(const struct programmer_cfg * cfg)71 static int it8212_init(const struct programmer_cfg *cfg)
72 {
73 uint8_t *bar;
74
75 struct pci_dev *dev = pcidev_init(cfg, devs_it8212, PCI_ROM_ADDRESS);
76 if (!dev)
77 return 1;
78
79 /* Bit 0 is address decode enable, 17-31 the base address, everything else reserved/zero. */
80 uint32_t io_base_addr = pcidev_readbar(dev, PCI_ROM_ADDRESS) & 0xFFFFFFFE;
81 if (!io_base_addr)
82 return 1;
83
84 bar = rphysmap("IT8212F flash", io_base_addr, IT8212_MEMMAP_SIZE);
85 if (bar == ERROR_PTR)
86 return 1;
87
88 struct it8212_data *data = calloc(1, sizeof(*data));
89 if (!data) {
90 msg_perr("Unable to allocate space for PAR master data\n");
91 return 1;
92 }
93 data->dev = dev;
94 data->bar = bar;
95
96 /* Enable ROM BAR decoding. */
97 data->decode_access = pci_read_long(dev, PCI_ROM_ADDRESS);
98 pci_write_long(dev, PCI_ROM_ADDRESS, io_base_addr | 0x01);
99
100 max_rom_decode.parallel = IT8212_MEMMAP_SIZE;
101 return register_par_master(&par_master_it8212, BUS_PARALLEL, data);
102 }
103 const struct programmer_entry programmer_it8212 = {
104 .name = "it8212",
105 .type = PCI,
106 .devs.dev = devs_it8212,
107 .init = it8212_init,
108 };
109