2 * This file is part of the flashrom project.
4 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2005-2007 coresystems GmbH
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #define SECTOR_ERASE 0x30
32 #define BLOCK_ERASE 0x20
34 #define AUTO_PGRM 0x10
37 #define READ_STATUS 0x70
38 #define CLEAR_STATUS 0x50
40 #define STATUS_BPS (1 << 1)
41 #define STATUS_ESS (1 << 6)
42 #define STATUS_WSMS (1 << 7)
44 static __inline__ int write_lockbits_49lfxxxc(volatile uint8_t *bios, int size,
48 unsigned long address;
50 //printf("bios=0x%08lx\n", (unsigned long)bios);
51 for (i = 0; left > 65536; i++, left -= 65536) {
52 //printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFC00000 - size + (i * 65536) + 2, *(bios + (i * 65536) + 2) );
53 *(bios + (i * 65536) + 2) = bits;
56 //printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
57 *(bios + address + 2) = bits;
59 //printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
60 *(bios + address + 2) = bits;
62 //printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
63 *(bios + address + 2) = bits;
65 //printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
66 *(bios + address + 2) = bits;
71 static __inline__ int erase_sector_49lfxxxc(volatile uint8_t *bios,
72 unsigned long address)
77 *(bios + address) = ERASE;
81 if (status & (STATUS_ESS | STATUS_BPS)) {
82 printf("sector erase FAILED at address=0x%08lx status=0x%01x\n", (unsigned long)bios + address, status);
86 } while (!(status & STATUS_WSMS));
91 static __inline__ int write_sector_49lfxxxc(volatile uint8_t *bios,
93 volatile uint8_t *dst,
94 unsigned int page_size)
100 for (i = 0; i < page_size; i++) {
101 /* transfer data from source to destination */
104 /* If the data is 0xFF, don't program it */
107 /*issue AUTO PROGRAM command */
113 if (status & (STATUS_ESS | STATUS_BPS)) {
114 printf("sector write FAILED at address=0x%08lx status=0x%01x\n", (unsigned long)dst, status);
115 *bios = CLEAR_STATUS;
118 } while (!(status & STATUS_WSMS));
124 int probe_49lfxxxc(struct flashchip *flash)
126 volatile uint8_t *bios = flash->virtual_memory;
133 id1 = *(volatile uint8_t *)bios;
134 id2 = *(volatile uint8_t *)(bios + 0x01);
138 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
140 if (!(id1 == flash->manufacture_id && id2 == flash->model_id))
143 map_flash_registers(flash);
148 int erase_49lfxxxc(struct flashchip *flash)
150 volatile uint8_t *bios = flash->virtual_memory;
151 volatile uint8_t *registers = flash->virtual_registers;
153 unsigned int total_size = flash->total_size * 1024;
155 write_lockbits_49lfxxxc(registers, total_size, 0);
156 for (i = 0; i < total_size; i += flash->page_size)
157 if (erase_sector_49lfxxxc(bios, i) != 0)
165 int write_49lfxxxc(struct flashchip *flash, uint8_t *buf)
168 int total_size = flash->total_size * 1024;
169 int page_size = flash->page_size;
170 volatile uint8_t *bios = flash->virtual_memory;
172 write_lockbits_49lfxxxc(flash->virtual_registers, total_size, 0);
173 printf("Programming page: ");
174 for (i = 0; i < total_size / page_size; i++) {
175 /* erase the page before programming */
176 erase_sector_49lfxxxc(bios, i * page_size);
178 /* write to the sector */
179 printf("%04d at address: 0x%08x", i, i * page_size);
180 write_sector_49lfxxxc(bios, buf + i * page_size,
181 bios + i * page_size, page_size);
182 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");