for some reasons the externals did not get committed.
[coreboot.git] / util / flashrom / m29f400bt.c
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2000 Silicon Integrated System Corporation
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "flash.h"
22
23 void protect_m29f400bt(volatile uint8_t *bios)
24 {
25         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
26         *(volatile uint8_t *)(bios + 0x555) = 0x55;
27         *(volatile uint8_t *)(bios + 0xAAA) = 0xA0;
28
29         usleep(200);
30 }
31
32 void write_page_m29f400bt(volatile uint8_t *bios, uint8_t *src,
33                           volatile uint8_t *dst, int page_size)
34 {
35         int i;
36
37         for (i = 0; i < page_size; i++) {
38                 *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
39                 *(volatile uint8_t *)(bios + 0x555) = 0x55;
40                 *(volatile uint8_t *)(bios + 0xAAA) = 0xA0;
41
42                 /* transfer data from source to destination */
43                 *dst = *src;
44                 //*(volatile char *) (bios) = 0xF0;
45                 //usleep(5);
46                 toggle_ready_jedec(dst);
47                 printf
48                     ("Value in the flash at address %p = %#x, want %#x\n",
49                      (uint8_t *) (dst - bios), *dst, *src);
50                 dst++;
51                 src++;
52         }
53 }
54
55 int probe_m29f400bt(struct flashchip *flash)
56 {
57         volatile uint8_t *bios = flash->virtual_memory;
58         uint8_t id1, id2;
59
60         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
61         *(volatile uint8_t *)(bios + 0x555) = 0x55;
62         *(volatile uint8_t *)(bios + 0xAAA) = 0x90;
63
64         myusec_delay(10);
65
66         id1 = *(volatile uint8_t *)bios;
67         /* The data sheet says id2 is at (bios + 0x01) and id2 listed in
68          * flash.h does not match. It should be possible to use JEDEC probe.
69          */
70         id2 = *(volatile uint8_t *)(bios + 0x02);
71
72         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
73         *(volatile uint8_t *)(bios + 0x555) = 0x55;
74         *(volatile uint8_t *)(bios + 0xAAA) = 0xF0;
75
76         myusec_delay(10);
77
78         printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
79
80         if (id1 == flash->manufacture_id && id2 == flash->model_id)
81                 return 1;
82
83         return 0;
84 }
85
86 int erase_m29f400bt(struct flashchip *flash)
87 {
88         volatile uint8_t *bios = flash->virtual_memory;
89
90         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
91         *(volatile uint8_t *)(bios + 0x555) = 0x55;
92         *(volatile uint8_t *)(bios + 0xAAA) = 0x80;
93
94         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
95         *(volatile uint8_t *)(bios + 0x555) = 0x55;
96         *(volatile uint8_t *)(bios + 0xAAA) = 0x10;
97
98         myusec_delay(10);
99         toggle_ready_jedec(bios);
100
101         return 0;
102 }
103
104 int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst)
105 {
106
107         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
108         *(volatile uint8_t *)(bios + 0x555) = 0x55;
109         *(volatile uint8_t *)(bios + 0xAAA) = 0x80;
110
111         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
112         *(volatile uint8_t *)(bios + 0x555) = 0x55;
113         //*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
114         *dst = 0x30;
115
116         myusec_delay(10);
117         toggle_ready_jedec(bios);
118
119         return 0;
120 }
121
122 int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
123 {
124         int i;
125         int total_size = flash->total_size * 1024;
126         int page_size = flash->page_size;
127         volatile uint8_t *bios = flash->virtual_memory;
128
129         //erase_m29f400bt (flash);
130         printf("Programming page:\n ");
131         /*********************************
132         *Pages for M29F400BT:
133         * 16    0x7c000         0x7ffff         TOP
134         *  8    0x7a000         0x7bfff
135         *  8    0x78000         0x79fff
136         * 32    0x70000         0x77fff
137         * 64    0x60000         0x6ffff
138         * 64    0x50000         0x5ffff
139         * 64    0x40000         0x4ffff
140         *---------------------------------
141         * 64    0x30000         0x3ffff
142         * 64    0x20000         0x2ffff
143         * 64    0x10000         0x1ffff
144         * 64    0x00000         0x0ffff         BOTTOM
145         *********************************/
146         printf("total_size/page_size = %d\n", total_size / page_size);
147         for (i = 0; i < (total_size / page_size) - 1; i++) {
148                 printf("%04d at address: 0x%08x\n", i, i * page_size);
149                 block_erase_m29f400bt(bios, bios + i * page_size);
150                 write_page_m29f400bt(bios, buf + i * page_size,
151                                      bios + i * page_size, page_size);
152                 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");
153         }
154
155         printf("%04d at address: 0x%08x\n", 7, 0x70000);
156         block_erase_m29f400bt(bios, bios + 0x70000);
157         write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
158
159         printf("%04d at address: 0x%08x\n", 8, 0x78000);
160         block_erase_m29f400bt(bios, bios + 0x78000);
161         write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
162
163         printf("%04d at address: 0x%08x\n", 9, 0x7a000);
164         block_erase_m29f400bt(bios, bios + 0x7a000);
165         write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
166
167         printf("%04d at address: 0x%08x\n", 10, 0x7c000);
168         block_erase_m29f400bt(bios, bios + 0x7c000);
169         write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
170
171         printf("\n");
172         //protect_m29f400bt (bios);
173
174         return 0;
175 }
176
177 int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf)
178 {
179         volatile uint8_t *bios = flash->virtual_memory;
180
181         printf("Programming page:\n ");
182         /*********************************
183         *Pages for M29F400BT:
184         * 16    0x7c000         0x7ffff         TOP
185         *  8    0x7a000         0x7bfff
186         *  8    0x78000         0x79fff
187         * 32    0x70000         0x77fff
188         * 64    0x60000         0x6ffff
189         * 64    0x50000         0x5ffff
190         * 64    0x40000         0x4ffff
191         *---------------------------------
192         * 64    0x30000         0x3ffff
193         * 64    0x20000         0x2ffff
194         * 64    0x10000         0x1ffff
195         * 64    0x00000         0x0ffff         BOTTOM
196         *********************************/
197         printf("%04d at address: 0x%08x\n", 7, 0x00000);
198         block_erase_m29f400bt(bios, bios + 0x00000);
199         write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024);
200
201         printf("%04d at address: 0x%08x\n", 7, 0x10000);
202         block_erase_m29f400bt(bios, bios + 0x10000);
203         write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024);
204
205         printf("%04d at address: 0x%08x\n", 7, 0x20000);
206         block_erase_m29f400bt(bios, bios + 0x20000);
207         write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024);
208
209         printf("%04d at address: 0x%08x\n", 7, 0x30000);
210         block_erase_m29f400bt(bios, bios + 0x30000);
211         write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
212
213         printf("\n");
214         //protect_m29f400bt (bios);
215
216         return 0;
217 }