flashsvf.pl 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #!/usr/bin/perl
  2. use strict;
  3. use integer;
  4. our %consts;
  5. require '../../common/iodevs.conf';
  6. my $ramaddr = $consts{'SDRAM_ADDR'};
  7. my $flashcmd = 0xabc80046;
  8. my $flashpfx = 0xabc80fed;
  9. my $maxdatalen = 16 << 20;
  10. my($svfload, $rptfile, $binfile, $svffile) = @ARGV;
  11. open(my $in, '<', $rptfile)
  12. or die "$0: $rptfile: $!\n";
  13. my @vjif;
  14. while (defined(my $l = <$in>)) {
  15. my @lf = split(/\s*\;\s*/, $l);
  16. if ($lf[8] =~ /\|vjtag\:vjtag\|/) {
  17. @vjif = @lf;
  18. }
  19. }
  20. close($in);
  21. # [0] - blank
  22. # [1] - instance index
  23. # [2] - auto index
  24. # [3] - index changed
  25. # [4] - IR width
  26. # [5] - VIR base address
  27. # [6] - USER1 DR length
  28. # [7] - VIR capture command
  29. # [8] - hierarchial entity name
  30. my $virbits = $vjif[6];
  31. my $virbase = hex $vjif[5];
  32. my $vircap = hex $vjif[7];
  33. open(my $bin, '<', $binfile)
  34. or die "$0: $binfile: $!\n";
  35. binmode($bin);
  36. my $bindata;
  37. my $binlen = read($bin, $bindata, $maxdatalen);
  38. close($bin);
  39. open(my $svf, '>', $svffile)
  40. or die "$0: $svffile: $!\n";
  41. # SVF file for the transient load image
  42. open(my $in, '<', $svfload)
  43. or die "$0: $svfload: $!\n";
  44. while (defined(my $l = <$in>)) {
  45. print $svf $l;
  46. }
  47. close($in);
  48. sub print_bitstring($$$) {
  49. my($svf, $len, $data) = @_;
  50. my $lenbytes = ($len+7) >> 3;
  51. if (length($data) < $lenbytes) {
  52. $data = ("\0" x ($len - $lenbytes)) . $data;
  53. }
  54. my $b = -1 - (length($data)-$lenbytes);
  55. my $bytes = 0;
  56. while ($len > 7) {
  57. printf $svf "%02X", unpack("C", substr($data, $b--, 1));
  58. if (!(++$bytes & 63)) {
  59. print $svf "\n\t";
  60. }
  61. $len -= 8;
  62. }
  63. if ($len) {
  64. my $lb = unpack("C", substr($data, $b--, 1));
  65. $lb &= (1 << $len)-1;
  66. printf $svf "%0".(($len+3)>>2)."X", $lb;
  67. }
  68. }
  69. sub virt_sir($$) {
  70. my($svf, $cmd) = @_;
  71. print $svf "SIR 10 TDI (00E);\n";
  72. printf $svf "SDR %d TDI (", $virbits;
  73. print_bitstring($svf, $virbits, pack("V", $virbase | $cmd));
  74. print $svf ");\n";
  75. print $svf "SIR 10 TDI (00C);\n";
  76. }
  77. # Set address command
  78. my $ramaddr = 0x40000000;
  79. virt_sir($svf, 0x12);
  80. printf $svf "SDR 32 TDI (%08X);\n", $ramaddr;
  81. # Write data to SDRAM
  82. virt_sir($svf, 0x16);
  83. # Prepend ABC80FED synchronization word
  84. $bindata = pack("V", $flashpfx) . $bindata;
  85. # Pad to a full 32-bit word (the JTAG command writes full 32-bit words only)
  86. $bindata .= "\0" x ((4 - (length($bindata) & 3)) & 3);
  87. my $binbits = length($bindata) << 3;
  88. printf $svf "SDR %d\n TDI (", $binbits;
  89. print_bitstring($svf, $binbits, $bindata);
  90. print $svf ");\n";
  91. # Trigger flash command to firmware
  92. virt_sir($svf, 0x1a);
  93. printf $svf "SDR 32 TDI (%08X);\n", $flashcmd;
  94. # Idle JTAG
  95. print $svf "SIR 10 TDI (3FF);\n";
  96. print $svf "STATE IDLE;\n";