You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bromutil.c 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * readutil.c - perform various control ops on the 3c509b bios rom
  3. *
  4. */
  5. #ifndef __i386__
  6. # error "This program can't compile or run on non-intel computers"
  7. #else
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #ifdef __FreeBSD__
  12. #include <fcntl.h>
  13. #include <machine/cpufunc.h>
  14. #define OUTB(data, port) outb(port, data)
  15. #define OUTW(data, port) outw(port, data)
  16. #define OUTL(data, port) outl(port, data)
  17. #else
  18. #include <sys/io.h>
  19. #define OUTB(data, port) outb(data, port)
  20. #define OUTW(data, port) outw(data, port)
  21. #define OUTL(data, port) outl(data, port)
  22. #endif
  23. int main(int argc, char **argv)
  24. {
  25. unsigned int i, j, n;
  26. unsigned int ioaddr;
  27. unsigned long recvrstat;
  28. unsigned char buf[128];
  29. unsigned char b;
  30. if (argc != 3) {
  31. printf("Usage: romid ioaddr [erase|protect|unprotect|id|read >file|prog <file]\n");
  32. exit(-1);
  33. }
  34. #ifdef __FreeBSD__
  35. /* get permissions for in/out{blw} */
  36. open("/dev/io",O_RDONLY,0);
  37. #else
  38. setuid(0); /* if we're setuid, do it really */
  39. if (iopl(3)) {
  40. perror("iopl()");
  41. exit(1);
  42. }
  43. #endif
  44. sscanf(argv[1],"%x",&ioaddr);
  45. /* Set the register window to 3 for the 3c905b */
  46. OUTW(0x803, ioaddr+0xe);
  47. recvrstat = inl(ioaddr); /* save the receiver status */
  48. /* set the receiver type to MII so the full bios rom address space
  49. can be accessed */
  50. OUTL((recvrstat & 0xf00fffff)|0x00600000, ioaddr);
  51. /* Set the register window to 0 for the 3c905b */
  52. OUTW(0x800, ioaddr+0xe);
  53. if (strcmp(argv[2], "erase") == 0) {
  54. /* do the funky chicken to erase the rom contents */
  55. OUTL(0x5555, ioaddr+0x4);
  56. OUTB(0xaa, ioaddr+0x8);
  57. OUTL(0x2aaa, ioaddr+0x4);
  58. OUTB(0x55, ioaddr+0x8);
  59. OUTL(0x5555, ioaddr+0x4);
  60. OUTB(0x80, ioaddr+0x8);
  61. OUTL(0x5555, ioaddr+0x4);
  62. OUTB(0xaa, ioaddr+0x8);
  63. OUTL(0x2aaa, ioaddr+0x4);
  64. OUTB(0x55, ioaddr+0x8);
  65. OUTL(0x5555, ioaddr+0x4);
  66. OUTB(0x10, ioaddr+0x8);
  67. printf("Bios ROM at %04x has been erased\n", ioaddr);
  68. } else if (strcmp(argv[2], "protect") == 0) {
  69. OUTL(0x5555, ioaddr+0x4);
  70. OUTB(0xaa, ioaddr+0x8);
  71. OUTL(0x2aaa, ioaddr+0x4);
  72. OUTB(0x55, ioaddr+0x8);
  73. OUTL(0x5555, ioaddr+0x4);
  74. OUTB(0xa0, ioaddr+0x8);
  75. printf("Software Data Protection for Bios ROM at %04x has been enabled\n",
  76. ioaddr);
  77. } else if (strcmp(argv[2], "unprotect") == 0) {
  78. OUTL(0x5555, ioaddr+0x4);
  79. OUTB(0xaa, ioaddr+0x8);
  80. OUTL(0x2aaa, ioaddr+0x4);
  81. OUTB(0x55, ioaddr+0x8);
  82. OUTL(0x5555, ioaddr+0x4);
  83. OUTB(0x80, ioaddr+0x8);
  84. OUTL(0x5555, ioaddr+0x4);
  85. OUTB(0xaa, ioaddr+0x8);
  86. OUTL(0x2aaa, ioaddr+0x4);
  87. OUTB(0x55, ioaddr+0x8);
  88. OUTL(0x5555, ioaddr+0x4);
  89. OUTB(0x20, ioaddr+0x8);
  90. printf("Software Data Protection for Bios ROM at %04x has been disabled\n",
  91. ioaddr);
  92. } else if (strcmp(argv[2], "id") == 0) {
  93. OUTL(0x5555, ioaddr+0x4);
  94. OUTB(0xaa, ioaddr+0x8);
  95. OUTL(0x2aaa, ioaddr+0x4);
  96. OUTB(0x55, ioaddr+0x8);
  97. OUTL(0x5555, ioaddr+0x4);
  98. OUTB(0x90, ioaddr+0x8);
  99. /* 10ms delay needed */
  100. printf("Manufacturer ID - ");
  101. /* manuf. id */
  102. OUTL(0x0000, ioaddr+0x4);
  103. printf("%02x\n", inb(ioaddr+0x8));
  104. /* device id */
  105. OUTL(0x0001, ioaddr+0x4);
  106. printf("Device ID - %02x\n", inb(ioaddr+0x8));
  107. /* undo the funky chicken */
  108. OUTL(0x5555, ioaddr+0x4);
  109. OUTB(0xaa, ioaddr+0x8);
  110. OUTL(0x2aaa, ioaddr+0x4);
  111. OUTB(0x55, ioaddr+0x8);
  112. OUTL(0x5555, ioaddr+0x4);
  113. OUTB(0xf0, ioaddr+0x8);
  114. } else if (strcmp(argv[2], "read") == 0) {
  115. for (i = 0; i < 65536; i++) {
  116. OUTL(i, ioaddr+0x4);
  117. b = inb(ioaddr+0x8);
  118. write(1, &b, 1);
  119. }
  120. } else if (strcmp(argv[2], "prog") == 0) {
  121. /* program the rom in 128 bute chunks */
  122. for (i = 0, n = 0; i < 65536; i += n) {
  123. n = read(0, buf, 128);
  124. if (n == 0)
  125. break;
  126. if (n < 0) {
  127. perror("File Error");
  128. exit(-3);
  129. }
  130. /* disable SDP temporarily for programming a sector */
  131. OUTL(0x5555, ioaddr+0x4);
  132. OUTB(0xaa, ioaddr+0x8);
  133. OUTL(0x2aaa, ioaddr+0x4);
  134. OUTB(0x55, ioaddr+0x8);
  135. OUTL(0x5555, ioaddr+0x4);
  136. OUTB(0xa0, ioaddr+0x8);
  137. for (j = 0; j < n; j++) {
  138. OUTL(i+j, ioaddr+0x4);
  139. OUTB(buf[j], ioaddr+0x8);
  140. }
  141. /* wait for the programming of this sector to coomplete */
  142. while (inb(ioaddr+0x8) != buf[j-1])
  143. ;
  144. }
  145. }
  146. /* Set the register window to 3 for the 3c905b */
  147. OUTW(0x803, ioaddr+0xe);
  148. /* restore the receiver status */
  149. OUTL(recvrstat, ioaddr);
  150. return 0;
  151. }
  152. #endif /* __i386__ */