source: trunk/programmer.c @ 1475

Revision 1475, 4.2 KB checked in by hailfinger, 5 months ago (diff)

Have all programmer init functions register bus masters/programmers

All programmer types (Parallel, SPI, Opaque) now register themselves
into a generic programmer list and probing is now programmer-centric
instead of chip-centric.
Registering multiple SPI/... masters at the same time is now possible
without any problems. Handling multiple flash chips is still unchanged,
but now we have the infrastructure to deal with "dual BIOS" and "one
flash behind southbridge and one flash behind EC" sanely.

A nice side effect is that this patch kills quite a few global variables
and improves the situation for libflashrom.

Hint for developers:
struct {spi,par,opaque}_programmer now have a void *data pointer to
store any additional programmer-specific data, e.g. hardware
configuration info.

Note:
flashrom -f -c FOO -r forced_read.bin
does not work anymore. We have to find an architecturally clean way to
solve this.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>
Acked-by: Michael Karcher <flashrom@…>

Line 
1/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009,2010,2011 Carl-Daniel Hailfinger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19 */
20
21#include "flash.h"
22#include "programmer.h"
23
24/* No-op shutdown() for programmers which don't need special handling */
25int noop_shutdown(void)
26{
27        return 0;
28}
29
30/* Fallback map() for programmers which don't need special handling */
31void *fallback_map(const char *descr, unsigned long phys_addr, size_t len)
32{
33        /* FIXME: Should return phys_addr. */
34        return NULL;
35}
36
37/* No-op/fallback unmap() for programmers which don't need special handling */
38void fallback_unmap(void *virt_addr, size_t len)
39{
40}
41
42/* No-op chip_writeb() for parallel style drivers not supporting writes */
43void noop_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
44{
45}
46
47/* Little-endian fallback for drivers not supporting 16 bit accesses */
48void fallback_chip_writew(const struct flashctx *flash, uint16_t val,
49                          chipaddr addr)
50{
51        chip_writeb(flash, val & 0xff, addr);
52        chip_writeb(flash, (val >> 8) & 0xff, addr + 1);
53}
54
55/* Little-endian fallback for drivers not supporting 16 bit accesses */
56uint16_t fallback_chip_readw(const struct flashctx *flash, const chipaddr addr)
57{
58        uint16_t val;
59        val = chip_readb(flash, addr);
60        val |= chip_readb(flash, addr + 1) << 8;
61        return val;
62}
63
64/* Little-endian fallback for drivers not supporting 32 bit accesses */
65void fallback_chip_writel(const struct flashctx *flash, uint32_t val,
66                          chipaddr addr)
67{
68        chip_writew(flash, val & 0xffff, addr);
69        chip_writew(flash, (val >> 16) & 0xffff, addr + 2);
70}
71
72/* Little-endian fallback for drivers not supporting 32 bit accesses */
73uint32_t fallback_chip_readl(const struct flashctx *flash, const chipaddr addr)
74{
75        uint32_t val;
76        val = chip_readw(flash, addr);
77        val |= chip_readw(flash, addr + 2) << 16;
78        return val;
79}
80
81void fallback_chip_writen(const struct flashctx *flash, uint8_t *buf,
82                          chipaddr addr, size_t len)
83{
84        size_t i;
85        for (i = 0; i < len; i++)
86                chip_writeb(flash, buf[i], addr + i);
87        return;
88}
89
90void fallback_chip_readn(const struct flashctx *flash, uint8_t *buf,
91                         chipaddr addr, size_t len)
92{
93        size_t i;
94        for (i = 0; i < len; i++)
95                buf[i] = chip_readb(flash, addr + i);
96        return;
97}
98
99int register_par_programmer(const struct par_programmer *pgm,
100                            const enum chipbustype buses)
101{
102        struct registered_programmer rpgm;
103        if (!pgm->chip_writeb || !pgm->chip_writew || !pgm->chip_writel ||
104            !pgm->chip_writen || !pgm->chip_readb || !pgm->chip_readw ||
105            !pgm->chip_readl || !pgm->chip_readn) {
106                msg_perr("%s called with incomplete programmer definition. "
107                         "Please report a bug at flashrom@flashrom.org\n",
108                         __func__);
109                return ERROR_FLASHROM_BUG;
110        }
111
112        rpgm.buses_supported = buses;
113        rpgm.par = *pgm;
114        return register_programmer(&rpgm);
115}
116
117/* The limit of 4 is totally arbitrary. */
118#define PROGRAMMERS_MAX 4
119struct registered_programmer registered_programmers[PROGRAMMERS_MAX];
120int registered_programmer_count = 0;
121
122/* This function copies the struct registered_programmer parameter. */
123int register_programmer(struct registered_programmer *pgm)
124{
125        if (registered_programmer_count >= PROGRAMMERS_MAX) {
126                msg_perr("Tried to register more than %i programmer "
127                         "interfaces.\n", PROGRAMMERS_MAX);
128                return ERROR_FLASHROM_LIMIT;
129        }
130        registered_programmers[registered_programmer_count] = *pgm;
131        registered_programmer_count++;
132
133        return 0;
134}
135
136enum chipbustype get_buses_supported(void)
137{
138        int i;
139        enum chipbustype ret = BUS_NONE;
140
141        for (i = 0; i < registered_programmer_count; i++)
142                ret |= registered_programmers[i].buses_supported;
143
144        return ret;
145}
Note: See TracBrowser for help on using the repository browser.