From patchwork Thu Jan 3 01:35:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: Automatic programmer driver writer Date: Thu, 03 Jan 2013 01:35:47 -0000 From: Carl-Daniel Hailfinger X-Patchwork-Id: 3836 Message-Id: <50E4E073.3080606@gmx.net> To: flashrom@flashrom.org Am 13.08.2012 11:18 schrieb Stefan Tauner: > On Mon, 13 Aug 2012 04:25:16 +0200 > Carl-Daniel Hailfinger wrote: > >> +# Fill in all info in the block below, and don't touch anything else. >> +# The data provided here is just an example. > could be done with an include ("."/"source") instead, which would allow > to have multiple programmer-specific files and select it by a command > line parameter e.g.: > source "$1" Yes. There's a catch, though: We have to manage two files for one purpose, and I'm not sure if the code is better that way. What do you think? The patch below is audited and works against svn HEAD. Run ./build_new_driver.sh, move *.mine to their base names and recompile. You have a new driver, and it's linked in at the appropriate places. Tested, works. Signed-off-by: Carl-Daniel Hailfinger Index: flashrom-programmer_template/build_new_driver.sh =================================================================== --- flashrom-programmer_template/build_new_driver.sh (Revision 0) +++ flashrom-programmer_template/build_new_driver.sh (Revision 0) @@ -0,0 +1,372 @@ +#!/bin/bash +# flashrom programmer driver skeleton builder. +# Copyright 2012 Carl-Daniel Hailfinger +# Licensed under the GNU GPL v2 + +# Fill in all info in the block below, and don't touch anything else. +# The data provided here is just an example. +# Name of the programmer. Needs to be an all-lowercase valid C identifier +PROGRAMMERNAME=ezo +# Short description of the programmer. Please do not use / inside the name, it will break the sed expressions. +PROGRAMMERDESCR="EZo+Willem Programmer" +# Name of the programmer manufacturer. +PROGRAMMERMANUF="EZo and Willem" +# Website for the programmer. +PROGRAMMERURL="http://www.ezoflash.com/" +# Fill in your name here. +AUTHORNAME="Carl-Daniel Hailfinger" +# Does the programmer need a map/unmap function? +HAVE_MAP=no +# Does the programmer have its own delay function? +HAVE_DELAY=no +# Does the programmer need some sort of direct hardware access? +NEED_PCI=yes +# Does the programmer need some sort of serial port access? +NEED_SERIAL=no +# Is the programmer a PCI device, USB device, or something else? +# You have to specify exactly one of PCI, USB, OTHER +DEVICETYPE=USB +# Note: Usually a programmer only has one of NEED_PARLPCFWH, NEED_SPI or NEED_SPI_BITBANG set to yes. +# Does the programmer use Parallel/LPC/FWH functionality? +NEED_PARLPCFWH=yes +# Which of PARALLEL/LPC/FWH buses does the programer use? +BUS_PARLPCFWH=LPC +# Does the programmer use SPI functionality without bitbanging? +NEED_SPI=yes +# Does the programmer use the bitbanging SPI infrastructure? +NEED_SPI_BITBANG=yes + +# No user serviceable parts below. +if test $HAVE_MAP = yes; then MAPNAME=$PROGRAMMERNAME; else MAPNAME=fallback; fi +if test $HAVE_DELAY = yes; then DELAYNAME=$PROGRAMMERNAME; else DELAYNAME=internal; fi +PROGRAMMERNAMECAPS=$(echo -n $PROGRAMMERNAME|tr "[[:lower:]]" "[[:upper:]]") +CONFIGNAME=CONFIG_$PROGRAMMERNAMECAPS +ENUMNAME=PROGRAMMER_$PROGRAMMERNAMECAPS +SPI_CONTROLLERNAME=SPI_CONTROLLER_$PROGRAMMERNAMECAPS +BITBANG_SPI_ENUMNAME=BITBANG_SPI_MASTER_$PROGRAMMERNAMECAPS +if test $NEED_PCI = yes; then NEEDS="NEED_PCI := yes\n"; fi +if test $NEED_SERIAL = yes; then NEEDS+="NEED_SERIAL := yes\n"; fi + +sed "s-^//PLACEHOLDER_NEWPROG_PROGRAMMER_ARRAY-\ +#if ${CONFIGNAME} == 1\n\ + {\n\ + .name = \"${PROGRAMMERNAME}\",\n\ +\0-" flashrom.c >flashrom.c.mine +if test $DEVICETYPE = OTHER; then +sed "s-^//PLACEHOLDER_NEWPROG_PROGRAMMER_ARRAY-\ + .type = OTHER,\n\ + .devs.note = \"Textual list of usable devices\\\\n\",\n\ +\0-" flashrom.c.mine >flashrom.c.mine1 +mv flashrom.c.mine1 flashrom.c.mine +else +sed "s-^//PLACEHOLDER_NEWPROG_PROGRAMMER_ARRAY-\ + .type = ${DEVICETYPE},\n\ + .devs.dev = devs_${PROGRAMMERNAME},\n\ +\0-" flashrom.c.mine >flashrom.c.mine1 +mv flashrom.c.mine1 flashrom.c.mine +fi +sed "s-^//PLACEHOLDER_NEWPROG_PROGRAMMER_ARRAY-\ + .init = ${PROGRAMMERNAME}_init,\n\ + .map_flash_region = ${MAPNAME}_map,\n\ + .unmap_flash_region = ${MAPNAME}_unmap,\n\ + .delay = ${DELAYNAME}_delay,\n\ + },\n\ +#endif\n\ +\n\0-" flashrom.c.mine >flashrom.c.mine1 +mv flashrom.c.mine1 flashrom.c.mine + +sed -e "s/^#PLACEHOLDER_NEWPROG_DEFAULTCONFIG/\ +# Enable ${PROGRAMMERDESCR} for now.\n\ +${CONFIGNAME} ?= yes\n\ +\n\0/" \ +-e "s/^#PLACEHOLDER_NEWPROG_COMPILERULE/\ +ifeq (\$(${CONFIGNAME}), yes)\n\ +FEATURE_CFLAGS += -D'${CONFIGNAME}=1'\n\ +PROGRAMMER_OBJS += ${PROGRAMMERNAME}.o\n\ +${NEEDS}\ +endif\n\ +\n\0/" Makefile >Makefile.mine + +if test $NEED_SPI_BITBANG = yes; then +sed -e "s/^#PLACEHOLDER_NEWPROG_BITBANGSPICONFIG1/\ +ifeq (\$(${CONFIGNAME}), yes)\n\ +override CONFIG_BITBANG_SPI = yes\n\ +else\n\ +\0/" \ +-e "s/^#PLACEHOLDER_NEWPROG_BITBANGSPICONFIG2/\ +\0\n\ +endif/;" Makefile.mine >Makefile.mine1 +mv Makefile.mine1 Makefile.mine +fi + +sed -e "s-^//PLACEHOLDER_NEWPROG_PROGRAMMER_ENUM-\ +#if ${CONFIGNAME} == 1\n\ + ${ENUMNAME},\n\ +#endif\n\ +\0-" \ +-e "s-^//PLACEHOLDER_NEWPROG_PUBLICFUNCTIONS-\ +/* ${PROGRAMMERNAME}.c */\n\ +#if ${CONFIGNAME} == 1\n\ +int ${PROGRAMMERNAME}_init(void);\n\ +\0-" programmer.h >programmer.h.mine + +if test $DEVICETYPE = PCI -o $DEVICETYPE = USB; then +sed -e "s-^//PLACEHOLDER_NEWPROG_PUBLICFUNCTIONS-\ +extern const struct dev_entry devs_${PROGRAMMERNAME}[];\n\ +\n\0-" programmer.h.mine >programmer.h.mine1 +mv programmer.h.mine1 programmer.h.mine +fi + +sed -e "s-^//PLACEHOLDER_NEWPROG_PUBLICFUNCTIONS-\ +#endif\n\ +\n\0-" programmer.h.mine >programmer.h.mine1 +mv programmer.h.mine1 programmer.h.mine + +if test $NEED_SPI_BITBANG = yes; then +sed -e "s-^//PLACEHOLDER_NEWPROG_PROGRAMMER_BITBANG_ENUM-\ +#if ${CONFIGNAME} == 1\n\ + ${BITBANG_SPI_ENUMNAME},\n\ +#endif\n\ +\0-" \ +-e "s-//PLACEHOLDER_NEWPROG_SELECT_SPI_BITBANG\$-\ +|| ${CONFIGNAME} == 1 \0-" programmer.h.mine >programmer.h.mine1 +mv programmer.h.mine1 programmer.h.mine +fi + +if test $NEED_SPI = yes; then +sed -e "s-^//PLACEHOLDER_NEWPROG_SPI_CONTROLLER_ENUM-\ +#if ${CONFIGNAME} == 1\n\ + ${SPI_CONTROLLERNAME},\n\ +#endif\n\ +\0-" programmer.h.mine >programmer.h.mine1 +mv programmer.h.mine1 programmer.h.mine +fi + +# No idea if roff supports hidden comments. Hook up to hopefully unchanged sequences. +sed -e "s/.*PLACEHOLDER_NEWPROG_MAN_SHORTDESCRIPTION/\ +.BR \"* ${PROGRAMMERNAME}\" \" (${PROGRAMMERDESCR})\"\n\ +.sp\n\ +\0/" \ +-e "s/.*PLACEHOLDER_NEWPROG_MAN_LONGDESCRIPTION/\ +.SS\n\ +.BR \"${PROGRAMMERNAME} \" programmer\n\ +Please describe the programmer parameters here.\n\ +\0/" \ +-e "s/.*PLACEHOLDER_NEWPROG_MAN_REQUIREMENTS/\ +.B ${PROGRAMMERNAME}\n\ +Please describe the programmer requirements here.\n\ +.sp\n\ +\0/" flashrom.8 > flashrom.8.mine + +cat >$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine < +static int ${PROGRAMMERNAME}_spi_send_command(struct flashctx *flash, + unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, + unsigned char *readarr) +{ + /* Send a SPI command to the flash chip. */ + /* Set readarr to 0xff to get the template to compile and run without segfaults. */ + memset(readarr, 0xff, readcnt); + + return 0; +} + +static const struct spi_programmer spi_programmer_${PROGRAMMERNAME} = { + .type = ${SPI_CONTROLLERNAME}, + .max_data_read = 64 * 1024, /* Maximum data read size in one go (excluding opcode+address). */ + .max_data_write = 256, /* Maximum data write size in one go (excluding opcode+address). */ + .command = ${PROGRAMMERNAME}_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = default_spi_read, + .write_256 = default_spi_write_256, +}; + +EOF +fi + +cat >>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <>$PROGRAMMERNAME.c.mine <