2 * This file is part of the flashrom project.
4 * Copyright (C) 2008 coresystems GmbH
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.
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.
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
24 int probe_winbond_fwhub(struct flashchip *flash)
26 volatile uint8_t *bios = flash->virtual_memory;
29 /* Product Identification Entry */
30 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
31 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
32 *(volatile uint8_t *)(bios + 0x5555) = 0x90;
36 vid = *(volatile uint8_t *)bios;
37 did = *(volatile uint8_t *)(bios + 0x01);
39 /* Product Identifixation Exit */
40 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
41 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
42 *(volatile uint8_t *)(bios + 0x5555) = 0xF0;
45 printf_debug("%s: vid 0x%x, did 0x%x\n", __FUNCTION__, vid, did);
47 if (vid != flash->manufacture_id || did != flash->model_id)
50 map_flash_registers(flash);
55 static int unlock_block_winbond_fwhub(struct flashchip *flash, int offset)
57 volatile uint8_t *wrprotect = flash->virtual_registers + offset + 2;
60 printf_debug("Trying to unlock block @0x%08x = 0x%02x\n", offset, *wrprotect);
63 switch (locking & 0x7 ) {
65 printf_debug("Full Access.\n");
68 printf_debug("Write Lock (Default State).\n");
72 printf_debug("Locked Open (Full Access, Lock Down).\n");
75 fprintf(stderr, "Error: Write Lock, Locked Down.\n");
78 printf_debug("Read Lock.\n");
82 printf_debug("Read/Write Lock.\n");
86 fprintf(stderr, "Error: Read Lock, Locked Down.\n");
89 fprintf(stderr, "Error: Read/Write Lock, Locked Down.\n");
93 /* We will never reach this point, but GCC doesn't know */
97 int unlock_winbond_fwhub(struct flashchip *flash)
99 int i, total_size = flash->total_size * 1024;
100 volatile uint8_t *bios = flash->virtual_memory;
103 /* Are there any hardware restrictions that we can't overcome?
104 * If flashrom fail here, someone's got to check all those GPIOs.
107 /* Product Identification Entry */
108 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
109 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
110 *(volatile uint8_t *)(bios + 0x5555) = 0x90;
113 /* Read Hardware Lock Bits */
114 locking = *(volatile uint8_t *)(bios + 0xffff2);
116 /* Product Identification Exit */
117 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
118 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
119 *(volatile uint8_t *)(bios + 0x5555) = 0xF0;
122 printf_debug("Lockout bits:\n");
124 if (locking & (1<<2))
125 fprintf(stderr, "Error: hardware bootblock locking (#TBL).\n");
127 printf_debug("No hardware bootblock locking (good!)\n");
129 if (locking & (1<<3))
130 fprintf(stderr, "Error: hardware block locking (#WP).\n");
132 printf_debug("No hardware block locking (good!)\n");
134 if (locking & ((1<<2) | (1<<3)))
137 /* Unlock the complete chip */
138 for (i = 0; i < total_size; i += flash->page_size)
139 if (unlock_block_winbond_fwhub(flash, i))
145 static int erase_sector_winbond_fwhub(volatile uint8_t *bios, unsigned int sector)
147 /* Remember: too much sleep can waste your day. */
149 printf("0x%08x\b\b\b\b\b\b\b\b\b\b", sector);
152 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
153 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
154 *(volatile uint8_t *)(bios + 0x5555) = 0x80;
156 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
157 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
158 *(volatile uint8_t *)(bios + sector) = 0x30;
160 /* wait for Toggle bit ready */
161 toggle_ready_jedec(bios);
166 int erase_winbond_fwhub(struct flashchip *flash)
168 int i, total_size = flash->total_size * 1024;
169 volatile uint8_t *bios = flash->virtual_memory;
171 unlock_winbond_fwhub(flash);
175 for (i = 0; i < total_size; i += flash->page_size)
176 erase_sector_winbond_fwhub(bios, i);
180 for (i = 0; i < total_size; i++) {
181 if (bios[i] != 0xff) {
182 fprintf(stderr, "Error: Flash chip erase failed at 0x%08x(0x%02x)\n", i, bios[i]);
190 int write_winbond_fwhub(struct flashchip *flash, uint8_t *buf)
193 int total_size = flash->total_size * 1024;
194 volatile uint8_t *bios = flash->virtual_memory;
196 if (erase_winbond_fwhub(flash))
199 printf("Programming: ");
200 for (i = 0; i < total_size; i+=flash->page_size) {
201 printf("0x%08x\b\b\b\b\b\b\b\b\b\b", i);
202 write_sector_jedec(bios, buf + i, bios + i, flash->page_size);