82802ab.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. * Datasheet:
  22. * - Name: Intel 82802AB/82802AC Firmware Hub (FWH)
  23. * - URL: http://www.intel.com/design/chipsets/datashts/290658.htm
  24. * - PDF: http://download.intel.com/design/chipsets/datashts/29065804.pdf
  25. * - Order number: 290658-004
  26. */
  27. #include "flash.h"
  28. #include "chipdrivers.h"
  29. void print_status_82802ab(uint8_t status)
  30. {
  31. msg_cdbg("%s", status & 0x80 ? "Ready:" : "Busy:");
  32. msg_cdbg("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
  33. msg_cdbg("%s", status & 0x20 ? "BE ERROR:" : "BE OK:");
  34. msg_cdbg("%s", status & 0x10 ? "PROG ERR:" : "PROG OK:");
  35. msg_cdbg("%s", status & 0x8 ? "VP ERR:" : "VPP OK:");
  36. msg_cdbg("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:");
  37. msg_cdbg("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:");
  38. }
  39. int probe_82802ab(struct flashctx *flash)
  40. {
  41. chipaddr bios = flash->virtual_memory;
  42. uint8_t id1, id2, flashcontent1, flashcontent2;
  43. int shifted = (flash->feature_bits & FEATURE_ADDR_SHIFTED) != 0;
  44. /* Reset to get a clean state */
  45. chip_writeb(flash, 0xFF, bios);
  46. programmer_delay(10);
  47. /* Enter ID mode */
  48. chip_writeb(flash, 0x90, bios);
  49. programmer_delay(10);
  50. id1 = chip_readb(flash, bios + (0x00 << shifted));
  51. id2 = chip_readb(flash, bios + (0x01 << shifted));
  52. /* Leave ID mode */
  53. chip_writeb(flash, 0xFF, bios);
  54. programmer_delay(10);
  55. msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, id1, id2);
  56. if (!oddparity(id1))
  57. msg_cdbg(", id1 parity violation");
  58. /*
  59. * Read the product ID location again. We should now see normal
  60. * flash contents.
  61. */
  62. flashcontent1 = chip_readb(flash, bios + (0x00 << shifted));
  63. flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
  64. if (id1 == flashcontent1)
  65. msg_cdbg(", id1 is normal flash content");
  66. if (id2 == flashcontent2)
  67. msg_cdbg(", id2 is normal flash content");
  68. msg_cdbg("\n");
  69. if (id1 != flash->manufacture_id || id2 != flash->model_id)
  70. return 0;
  71. if (flash->feature_bits & FEATURE_REGISTERMAP)
  72. map_flash_registers(flash);
  73. return 1;
  74. }
  75. uint8_t wait_82802ab(struct flashctx *flash)
  76. {
  77. uint8_t status;
  78. chipaddr bios = flash->virtual_memory;
  79. chip_writeb(flash, 0x70, bios);
  80. if ((chip_readb(flash, bios) & 0x80) == 0) { // it's busy
  81. while ((chip_readb(flash, bios) & 0x80) == 0) ;
  82. }
  83. status = chip_readb(flash, bios);
  84. /* Reset to get a clean state */
  85. chip_writeb(flash, 0xFF, bios);
  86. return status;
  87. }
  88. int unlock_82802ab(struct flashctx *flash)
  89. {
  90. int i;
  91. //chipaddr wrprotect = flash->virtual_registers + page + 2;
  92. for (i = 0; i < flash->total_size * 1024; i+= flash->page_size)
  93. chip_writeb(flash, 0, flash->virtual_registers + i + 2);
  94. return 0;
  95. }
  96. int erase_block_82802ab(struct flashctx *flash, unsigned int page,
  97. unsigned int pagesize)
  98. {
  99. chipaddr bios = flash->virtual_memory;
  100. uint8_t status;
  101. // clear status register
  102. chip_writeb(flash, 0x50, bios + page);
  103. // now start it
  104. chip_writeb(flash, 0x20, bios + page);
  105. chip_writeb(flash, 0xd0, bios + page);
  106. programmer_delay(10);
  107. // now let's see what the register is
  108. status = wait_82802ab(flash);
  109. print_status_82802ab(status);
  110. /* FIXME: Check the status register for errors. */
  111. return 0;
  112. }
  113. /* chunksize is 1 */
  114. int write_82802ab(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int len)
  115. {
  116. int i;
  117. chipaddr dst = flash->virtual_memory + start;
  118. for (i = 0; i < len; i++) {
  119. /* transfer data from source to destination */
  120. chip_writeb(flash, 0x40, dst);
  121. chip_writeb(flash, *src++, dst++);
  122. wait_82802ab(flash);
  123. }
  124. /* FIXME: Ignore errors for now. */
  125. return 0;
  126. }
  127. int unlock_28f004s5(struct flashctx *flash)
  128. {
  129. chipaddr bios = flash->virtual_memory;
  130. uint8_t mcfg, bcfg, need_unlock = 0, can_unlock = 0;
  131. int i;
  132. /* Clear status register */
  133. chip_writeb(flash, 0x50, bios);
  134. /* Read identifier codes */
  135. chip_writeb(flash, 0x90, bios);
  136. /* Read master lock-bit */
  137. mcfg = chip_readb(flash, bios + 0x3);
  138. msg_cdbg("master lock is ");
  139. if (mcfg) {
  140. msg_cdbg("locked!\n");
  141. } else {
  142. msg_cdbg("unlocked!\n");
  143. can_unlock = 1;
  144. }
  145. /* Read block lock-bits */
  146. for (i = 0; i < flash->total_size * 1024; i+= (64 * 1024)) {
  147. bcfg = chip_readb(flash, bios + i + 2); // read block lock config
  148. msg_cdbg("block lock at %06x is %slocked!\n", i, bcfg ? "" : "un");
  149. if (bcfg) {
  150. need_unlock = 1;
  151. }
  152. }
  153. /* Reset chip */
  154. chip_writeb(flash, 0xFF, bios);
  155. /* Unlock: clear block lock-bits, if needed */
  156. if (can_unlock && need_unlock) {
  157. msg_cdbg("Unlock: ");
  158. chip_writeb(flash, 0x60, bios);
  159. chip_writeb(flash, 0xD0, bios);
  160. chip_writeb(flash, 0xFF, bios);
  161. msg_cdbg("Done!\n");
  162. }
  163. /* Error: master locked or a block is locked */
  164. if (!can_unlock && need_unlock) {
  165. msg_cerr("At least one block is locked and lockdown is active!\n");
  166. return -1;
  167. }
  168. return 0;
  169. }
  170. int unlock_lh28f008bjt(struct flashctx *flash)
  171. {
  172. chipaddr bios = flash->virtual_memory;
  173. uint8_t mcfg, bcfg;
  174. uint8_t need_unlock = 0, can_unlock = 0;
  175. int i;
  176. /* Wait if chip is busy */
  177. wait_82802ab(flash);
  178. /* Read identifier codes */
  179. chip_writeb(flash, 0x90, bios);
  180. /* Read master lock-bit */
  181. mcfg = chip_readb(flash, bios + 0x3);
  182. msg_cdbg("master lock is ");
  183. if (mcfg) {
  184. msg_cdbg("locked!\n");
  185. } else {
  186. msg_cdbg("unlocked!\n");
  187. can_unlock = 1;
  188. }
  189. /* Read block lock-bits, 8 * 8 KB + 15 * 64 KB */
  190. for (i = 0; i < flash->total_size * 1024;
  191. i += (i >= (64 * 1024) ? 64 * 1024 : 8 * 1024)) {
  192. bcfg = chip_readb(flash, bios + i + 2); /* read block lock config */
  193. msg_cdbg("block lock at %06x is %slocked!\n", i,
  194. bcfg ? "" : "un");
  195. if (bcfg)
  196. need_unlock = 1;
  197. }
  198. /* Reset chip */
  199. chip_writeb(flash, 0xFF, bios);
  200. /* Unlock: clear block lock-bits, if needed */
  201. if (can_unlock && need_unlock) {
  202. msg_cdbg("Unlock: ");
  203. chip_writeb(flash, 0x60, bios);
  204. chip_writeb(flash, 0xD0, bios);
  205. chip_writeb(flash, 0xFF, bios);
  206. wait_82802ab(flash);
  207. msg_cdbg("Done!\n");
  208. }
  209. /* Error: master locked or a block is locked */
  210. if (!can_unlock && need_unlock) {
  211. msg_cerr("At least one block is locked and lockdown is active!\n");
  212. return -1;
  213. }
  214. return 0;
  215. }