nicnatsemi.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * This file is part of the flashrom project.
  3. *
  4. * Copyright (C) 2010 Andrew Morgan <ziltro@ziltro.com>
  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. #if defined(__i386__) || defined(__x86_64__)
  21. #include <stdlib.h>
  22. #include "flash.h"
  23. #include "programmer.h"
  24. #include "hwaccess.h"
  25. #define PCI_VENDOR_ID_NATSEMI 0x100b
  26. #define BOOT_ROM_ADDR 0x50
  27. #define BOOT_ROM_DATA 0x54
  28. static uint32_t io_base_addr = 0;
  29. const struct dev_entry nics_natsemi[] = {
  30. {0x100b, 0x0020, NT, "National Semiconductor", "DP83815/DP83816"},
  31. {0x100b, 0x0022, NT, "National Semiconductor", "DP83820"},
  32. {0},
  33. };
  34. static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
  35. chipaddr addr);
  36. static uint8_t nicnatsemi_chip_readb(const struct flashctx *flash,
  37. const chipaddr addr);
  38. static const struct par_master par_master_nicnatsemi = {
  39. .chip_readb = nicnatsemi_chip_readb,
  40. .chip_readw = fallback_chip_readw,
  41. .chip_readl = fallback_chip_readl,
  42. .chip_readn = fallback_chip_readn,
  43. .chip_writeb = nicnatsemi_chip_writeb,
  44. .chip_writew = fallback_chip_writew,
  45. .chip_writel = fallback_chip_writel,
  46. .chip_writen = fallback_chip_writen,
  47. };
  48. int nicnatsemi_init(void)
  49. {
  50. struct pci_dev *dev = NULL;
  51. if (rget_io_perms())
  52. return 1;
  53. dev = pcidev_init(nics_natsemi, PCI_BASE_ADDRESS_0);
  54. if (!dev)
  55. return 1;
  56. io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
  57. if (!io_base_addr)
  58. return 1;
  59. /* The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
  60. * in another. My NIC has MA16 connected to A16 on the boot ROM socket
  61. * so I'm assuming it is accessible. If not then next line wants to be
  62. * max_rom_decode.parallel = 65536; and the mask in the read/write
  63. * functions below wants to be 0x0000FFFF.
  64. */
  65. max_rom_decode.parallel = 131072;
  66. register_par_master(&par_master_nicnatsemi, BUS_PARALLEL);
  67. return 0;
  68. }
  69. static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
  70. chipaddr addr)
  71. {
  72. OUTL((uint32_t)addr & 0x0001FFFF, io_base_addr + BOOT_ROM_ADDR);
  73. /*
  74. * The datasheet requires 32 bit accesses to this register, but it seems
  75. * that requirement might only apply if the register is memory mapped.
  76. * Bits 8-31 of this register are apparently don't care, and if this
  77. * register is I/O port mapped, 8 bit accesses to the lowest byte of the
  78. * register seem to work fine. Due to that, we ignore the advice in the
  79. * data sheet.
  80. */
  81. OUTB(val, io_base_addr + BOOT_ROM_DATA);
  82. }
  83. static uint8_t nicnatsemi_chip_readb(const struct flashctx *flash,
  84. const chipaddr addr)
  85. {
  86. OUTL(((uint32_t)addr & 0x0001FFFF), io_base_addr + BOOT_ROM_ADDR);
  87. /*
  88. * The datasheet requires 32 bit accesses to this register, but it seems
  89. * that requirement might only apply if the register is memory mapped.
  90. * Bits 8-31 of this register are apparently don't care, and if this
  91. * register is I/O port mapped, 8 bit accesses to the lowest byte of the
  92. * register seem to work fine. Due to that, we ignore the advice in the
  93. * data sheet.
  94. */
  95. return INB(io_base_addr + BOOT_ROM_DATA);
  96. }
  97. #else
  98. #error PCI port I/O access is not supported on this architecture yet.
  99. #endif