On Fri, May 08, 2009 at 01:41:32PM +0200, Uwe Hermann wrote: > The attached draft (non-compiling patch) uses a struct and functions to > solve the issue, then each programmer can have it's own file where it > provides the required API functions (read, write, init, shutdown, etc). > E.g. we then have paraflasher.c, usbprog.c, etc.
Forgot the patch. Uwe. -- http://www.hermann-uwe.de | http://www.holsham-traders.de http://www.crazy-hacks.org | http://www.unmaintained-free-software.org
Draft for external flasher support. Signed-off-by: Uwe Hermann <[email protected]> Index: flash.h =================================================================== --- flash.h (Revision 472) +++ flash.h (Arbeitskopie) @@ -76,34 +76,79 @@ #endif #endif -static inline void chip_writeb(uint8_t b, volatile void *addr) -{ - *(volatile uint8_t *) addr = b; -} +extern int programmer; +#define PROGRAMMER_INTERNAL 0x00 +#define PROGRAMMER_USBPROG 0x01 -static inline void chip_writew(uint16_t b, volatile void *addr) -{ - *(volatile uint16_t *) addr = b; -} +/* lpc.c */ +uint8_t lpc_read_nibble(void); +void lpc_write_nibble(uint8_t nibble); +uint8_t lpc_read_byte(uint32_t address); +int lpc_write_byte(uint32_t address, uint8_t data); +void lpc_reset(void); -static inline void chip_writel(uint32_t b, volatile void *addr) -{ - *(volatile uint32_t *) addr = b; -} +/* TODO */ +int internal_init(void); +int internal_shutdown(void); +void internal_lclk_high(void); +void internal_lclk_low(void); +void internal_lframe_high(void); +void internal_lframe_low(void); +void internal_lrst_high(void); +void internal_lrst_low(void); +uint8_t internal_get_lad(void); +void internal_set_lad(uint8_t b); +uint8_t internal_chip_readb(const volatile void *addr); +void internal_chip_writeb(uint8_t b, volatile void *addr); -static inline uint8_t chip_readb(const volatile void *addr) -{ - return *(volatile uint8_t *) addr; -} +/* usbprog.c */ +int usbprog_init(void); +int usbprog_shutdown(void); +void usbprog_lclk_high(void); +void usbprog_lclk_low(void); +void usbprog_lframe_high(void); +void usbprog_lframe_low(void); +void usbprog_lrst_high(void); +void usbprog_lrst_low(void); +uint8_t usbprog_get_lad(void); +void usbprog_set_lad(uint8_t b); +void usbprog_chip_writeb(uint8_t b, volatile void *addr); +uint8_t usbprog_chip_readb(const volatile void *addr); -static inline uint16_t chip_readw(const volatile void *addr) +void usbprog_float_lad(void); +void usbprog_unfloat_lad(void); + +struct programmer { + // const char *vendor; + const char *name; + + int (*init) (void); + int (*shutdown) (void); + + void (*lpc_lclk_high) (void); + void (*lpc_lclk_low) (void); + void (*lpc_lframe_high) (void); + void (*lpc_lframe_low) (void); + void (*lpc_lrst_high) (void); + void (*lpc_lrst_low) (void); + + uint8_t (*lpc_get_lad) (void); + void (*lpc_set_lad) (uint8_t b); + + void (*chip_writeb) (uint8_t b, volatile void *addr); + uint8_t (*chip_readb) (const volatile void *addr); +}; + +extern const struct programmer programmer_table[]; + +static inline void chip_writeb(uint8_t b, volatile void *addr) { - return *(volatile uint16_t *) addr; + programmer_table[programmer].chip_writeb(b, addr); } -static inline uint32_t chip_readl(const volatile void *addr) +static inline uint8_t chip_readb(const volatile void *addr) { - return *(volatile uint32_t *) addr; + return programmer_table[programmer].chip_readb(addr); } #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) Index: flashrom.c =================================================================== --- flashrom.c (Revision 472) +++ flashrom.c (Arbeitskopie) @@ -36,6 +36,7 @@ struct pci_access *pacc; /* For board and chipset_enable */ int exclude_start_page, exclude_end_page; int verbose = 0; +int programmer = PROGRAMMER_INTERNAL; struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device) { @@ -145,7 +146,7 @@ int idx; int total_size = flash->total_size * 1024; uint8_t *buf2 = (uint8_t *) calloc(total_size, sizeof(char)); - if (flash->read == NULL) + if (flash->read == NULL) /* FIXME: external programmer support? */ memcpy(buf2, (const char *)flash->virtual_memory, total_size); else flash->read(flash, buf2); @@ -191,7 +192,7 @@ exit(1); } printf("Reading flash... "); - if (flash->read == NULL) + if (flash->read == NULL) /* FIXME: external programmer support? */ memcpy(buf, (const char *)flash->virtual_memory, size); else flash->read(flash, buf); @@ -220,7 +221,7 @@ return 1; } flash->erase(flash); - if (NULL == flash->read) + if (NULL == flash->read) /* FIXME: external programmer support? */ memcpy(buf, (const char *)flash->virtual_memory, size); else flash->read(flash, buf); @@ -329,6 +330,55 @@ printf("flashrom v%s\n", FLASHROM_VERSION); } +int internal_init(void) { return 0; }; +int internal_shutdown(void) { return 0; }; +void internal_lclk_high(void) {}; +void internal_lclk_low(void) {}; +void internal_lframe_high(void) {}; +void internal_lframe_low(void) {}; +void internal_lrst_high(void) {}; +void internal_lrst_low(void) {}; +uint8_t internal_get_lad(void) { return 0; }; +void internal_set_lad(uint8_t b) {}; +uint8_t internal_chip_readb(const volatile void *addr) { return *(volatile uint8_t *) addr; }; +void internal_chip_writeb(uint8_t b, volatile void *addr) { *(volatile uint8_t *) addr = b; }; + +const struct programmer programmer_table[] = { + { + .init = internal_init, + .shutdown = internal_shutdown, + /* TODO: Replace with generic set_pin/get_pin functions, passing #defines for LFRAME# etc? */ + .lpc_lclk_high = internal_lclk_high, + .lpc_lclk_low = internal_lclk_low, + .lpc_lframe_high= internal_lframe_high, + .lpc_lframe_low = internal_lframe_low, + .lpc_lrst_high = internal_lrst_high, + .lpc_lrst_low = internal_lrst_low, + .lpc_get_lad = internal_get_lad, + .lpc_set_lad = internal_set_lad, + .chip_readb = internal_chip_readb, + .chip_writeb = internal_chip_writeb, + }, + + { + .init = usbprog_init, + .shutdown = usbprog_shutdown, + /* TODO: Replace with generic set_pin/get_pin functions, passing #defines for LFRAME# etc? */ + .lpc_lclk_high = usbprog_lclk_high, + .lpc_lclk_low = usbprog_lclk_low, + .lpc_lframe_high= usbprog_lframe_high, + .lpc_lframe_low = usbprog_lframe_low, + .lpc_lrst_high = usbprog_lrst_high, + .lpc_lrst_low = usbprog_lrst_low, + .lpc_get_lad = usbprog_get_lad, + .lpc_set_lad = usbprog_set_lad, + .chip_readb = usbprog_chip_readb, + .chip_writeb = usbprog_chip_writeb, + }, + + {}, +}; + int main(int argc, char *argv[]) { uint8_t *buf; @@ -359,6 +409,7 @@ {"layout", 1, 0, 'l'}, {"image", 1, 0, 'i'}, {"list-supported", 0, 0, 'L'}, + {"programmer", 1, 0, 'p'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'R'}, {0, 0, 0, 0} @@ -380,7 +431,7 @@ } setbuf(stdout, NULL); - while ((opt = getopt_long(argc, argv, "rRwvVEfc:s:e:m:l:i:Lh", + while ((opt = getopt_long(argc, argv, "rRwvVEfc:s:e:m:l:i:p:Lh", long_options, &option_index)) != EOF) { switch (opt) { case 'r': @@ -439,6 +490,16 @@ print_supported_boards(); exit(0); break; + case 'p': + if (strncmp(optarg, "internal", 8) == 0) { + programmer = PROGRAMMER_INTERNAL; + } else if (strncmp(optarg, "usbprog", 7) == 0) { + programmer = PROGRAMMER_USBPROG; + } else { + printf("Error: Unknown programmer.\n"); + exit(1); + } + break; case 'R': /* print_version() is always called during startup. */ exit(0); @@ -458,6 +519,8 @@ if (optind < argc) filename = argv[optind++]; + programmer_table[programmer].init(); + /* First get full io access */ #if defined (__sun) && (defined(__i386) || defined(__amd64)) if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) { @@ -537,7 +600,7 @@ exit(1); } printf("Force reading flash... "); - if (!flashes[0]->read) + if (!flashes[0]->read) /* FIXME: external programmer support? */ memcpy(buf, (const char *)flashes[0]->virtual_memory, size); else flashes[0]->read(flashes[0], buf); @@ -681,5 +744,8 @@ #ifdef __FreeBSD__ close(io_fd); #endif + + programmer_table[programmer].shutdown(); + return ret; }
-- coreboot mailing list: [email protected] http://www.coreboot.org/mailman/listinfo/coreboot

