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

Reply via email to