解析用ツール類

QEMU用のPT1エミュレータ部分を追加しました。
以下の機能があります。
I2C部分に関して0x10に書き込むと0x10以外に書き込む迄の1ブロックを
"/tmp/reg_all_%03d.data(ブロック番号)"として作成されます。

作成されたファイルの内容として、

FIFO COUNT(082:88)
0000: 0000 0000 2002 0000 2403 0000 2c04 0000
0010: 2c05 0000 2406 0000 2c07 0000 2c08 0000
0020: 2409 0000 2c0a 0000 280b 0000 200c 0000

と作成されます。

FIFO COUNTが何ブロック目かと最大アドレスとなります。
表示された内容として、
PCIのwriteされた上位16ビットをアドレスとし、値が下位16ビットとなります。

例えば
0000: 0000 0000 2002 0000 2403 0000 2004 0000
の場合、
00000000
00042002
00082002
000C2002
とかかれた事になります。

/tmp/isdb-sにファイルを作成した場合 ISDB-Sのチャネルスキャンで正常な値が返る様になります。

:

  1. /*
  2. */
  3. #include "hw.h"
  4. #include "pci.h"
  5. #include "pc.h"
  6. #define DEBUG_PT1
  7. /* lspci -xxx の結果
  8. Multimedia controller: Xilinx Corporation Device 211a (rev 01)
  9. 00: ee 10 1a 21 06 00 00 02 01 00 80 04 00 20 00 00
  10. 10: 00 c0 5f fd 00 00 00 00 00 00 00 00 00 00 00 00
  11. 20: 00 00 00 00 00 00 00 00 00 00 00 00 11 ef e5 de
  12. 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  13. 40: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
  14. 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  15. 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  16. 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  17. 80: ee 10 1a 21 06 00 00 02 01 00 80 04 00 20 00 00
  18. 90: 00 c0 5f fd 00 00 00 00 00 00 00 00 00 00 00 00
  19. a0: 00 00 00 00 00 00 00 00 00 00 00 00 11 ef e5 de
  20. b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  21. c0: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
  22. d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  23. e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  24. f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  25. */
  26. // lspci結果の情報
  27. char pci_copy [256] = {
  28. 0xee ,0x10 ,0x1a ,0x21 ,0x06 ,0x00 ,0x00 ,0x02 ,0x01 ,0x00 ,0x80 ,0x04 ,0x00 ,0x20 ,0x00 ,0x00
  29. ,0x00 ,0xc0 ,0x5f ,0xfd ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  30. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x11 ,0xef ,0xe5 ,0xde
  31. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  32. ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  33. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  34. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  35. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  36. ,0xee ,0x10 ,0x1a ,0x21 ,0x06 ,0x00 ,0x00 ,0x02 ,0x01 ,0x00 ,0x80 ,0x04 ,0x00 ,0x20 ,0x00 ,0x00
  37. ,0x00 ,0xc0 ,0x5f ,0xfd ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  38. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x11 ,0xef ,0xe5 ,0xde
  39. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  40. ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  41. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  42. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  43. ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  44. };
  45. /* PCI PT1 definitions */
  46. /***********************************************************/
  47. static FILE *fp = NULL; // FIFOに書いたデータ
  48. typedef struct PT1State {
  49. PCIDevice dev;
  50. char buf[(1024 * 4)];
  51. int mmio_index ;
  52. uint32_t region[3];
  53. }PT1State;
  54. uint16_t fifo_data[(64 * 1024)]; // FIFOに書くもの
  55. static int fifo_max_addr = 0 ; // FIFOに書いた最大アドレス
  56. static int reg_count = 0 ; // Scan時に書いた個数
  57. static int reg_pos_count = 0 ; // FIFOに書いた個数
  58. static int fifo_write_count = 1 ; // FIFOに書いて実行した個数
  59. typedef struct PCIPT1State {
  60. PCIDevice dev;
  61. PT1State state ;
  62. } PCIPT1State;
  63. /***********************************************************/
  64. void DumpWords(FILE *fp, int reg_pos_count)
  65. {
  66. int lp ;
  67. if(fp == NULL){
  68. return ;
  69. }
  70. fprintf(fp, "\n========= FIFO COUNT(%03d:%d) =========\n", fifo_write_count,
  71. reg_pos_count);
  72. // 初期化時のバカ避け
  73. if(fifo_max_addr >= 1024){
  74. fifo_max_addr = 256 ;
  75. }
  76. for(lp = 0 ; lp < (fifo_max_addr / 2) ; lp++){
  77. if((lp) && (!(lp % 8))){
  78. fprintf(fp, "\n");
  79. }
  80. if((!(lp % 8))){
  81. fprintf(fp, "%04x: ", (lp * 2));
  82. }
  83. fprintf(fp, "%04x ", fifo_data[lp]);
  84. }
  85. fflush(fp);
  86. fifo_write_count += 1 ;
  87. }
  88. static void pt1_save(QEMUFile* f,void* opaque)
  89. {
  90. printf("%s: \n", __FUNCTION__);
  91. }
  92. static int pt1_load(QEMUFile* f,void* opaque,int version_id)
  93. {
  94. printf("%s: \n", __FUNCTION__);
  95. return 0;
  96. }
  97. /***********************************************************/
  98. static void PT1pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  99. {
  100. PT1State *s = opaque;
  101. addr -= s->region[0];
  102. printf("%s: addr=%08lx value=%lx\n", __FUNCTION__, addr, val);
  103. }
  104. static void PT1pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  105. {
  106. PT1State *s = opaque;
  107. addr -= s->region[0];
  108. printf("%s: addr=%08lx value=%lx\n", __FUNCTION__, addr, val);
  109. }
  110. static void PT1pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  111. {
  112. PT1State *s = opaque;
  113. static int rc = 0;
  114. static int fifo_cnt = 0;
  115. uint32_t *ptr = (uint32_t *)s->buf ;
  116. char fname[256];
  117. union{
  118. struct {
  119. uint16_t value ;
  120. uint16_t offset ;
  121. }ui;
  122. uint32_t value ;
  123. }ui;
  124. addr -= s->region[0];
  125. if(addr == 0x10){
  126. if(fp == NULL){
  127. memset(fname, '\0', sizeof(fname));
  128. sprintf(fname, "/tmp/reg_all_%03d.data", fifo_write_count);
  129. fp = fopen(fname, "w+");
  130. fifo_max_addr = 0 ;
  131. }
  132. //オフセットを求める。
  133. reg_pos_count += 1 ;
  134. ui.value = val;
  135. if(fifo_data[(ui.ui.offset / 2)] != ui.ui.value){
  136. if(fp != NULL){
  137. fprintf(fp, "Addr:%04x Change %04x To %04x\n",
  138. ui.ui.offset, fifo_data[(ui.ui.offset / 2)], ui.ui.value);
  139. }
  140. fifo_data[(ui.ui.offset / 2)] = ui.ui.value ;
  141. }
  142. if(fifo_max_addr < ui.ui.offset){
  143. fifo_max_addr = ui.ui.offset;
  144. }
  145. }else{
  146. if(reg_pos_count){
  147. DumpWords(fp, reg_pos_count);
  148. fclose(fp);
  149. fp = NULL ;
  150. }
  151. reg_pos_count = 0 ;
  152. printf("%s: addr=%08lx value=%lx\n", __FUNCTION__, addr, val);
  153. }
  154. if(access("/tmp/isdb-s", 0) == F_OK){
  155. if(rc == 0){
  156. if(fp != NULL){
  157. fprintf(fp, "Scan Channels\n");
  158. }
  159. rc += 1 ;
  160. }
  161. if(addr != 0x10){
  162. reg_count += 1 ;
  163. }
  164. }
  165. ptr[(addr % sizeof(uint32_t))] = val ;
  166. // printf("%s: addr=%08lx value=%lx\n", __FUNCTION__, addr, val);
  167. }
  168. static uint32_t PT1pci_mmio_readb(void *opaque, target_phys_addr_t addr)
  169. {
  170. PT1State *s = opaque;
  171. addr -= s->region[0];
  172. printf("%s: addr=%08lx \n", __FUNCTION__, addr);
  173. return 0 ;
  174. }
  175. static uint32_t PT1pci_mmio_readw(void *opaque, target_phys_addr_t addr)
  176. {
  177. PT1State *s = opaque;
  178. addr -= s->region[0];
  179. printf("%s: addr=%08lx \n", __FUNCTION__, addr);
  180. return 0 ;
  181. }
  182. static uint32_t PT1pci_mmio_readl(void *opaque, target_phys_addr_t addr)
  183. {
  184. static uint32_t rc = 0;
  185. static int f_f_f = 0;
  186. static int f = 0;
  187. #define MAX_CNT 16
  188. static uint32_t rc_rec[MAX_CNT] ={
  189. // LOCK TMCCのはず。正常な値って何?
  190. 0xff414100, 0xe0208871, 0x40024001,
  191. // ↑ここの値が判らない。TMCCのリトライ時に取る値
  192. // TSID TSID TSID TSID
  193. 0x40024001, 0xFFFFFFFF, 0XFFFFFFFF, 0xFFFFFFFF,
  194. // CN? CN? AGC(下8BIT)
  195. 0x00110022, 0x00330044, 0x00000066,
  196. // 各TS情報
  197. // 取得したTSID
  198. // Mode Slot
  199. // 上位2バイト:モード
  200. // 高層モード、低層モード
  201. // 下位2バイト:スロット数
  202. // 高層モード、低層モード
  203. 0x4002, 0x0403110D,
  204. 0x4001, 0x0403110D,
  205. // ここがクロック周波数誤差とキャリア周波数誤差?
  206. // 正常な値が判らない
  207. 10, 11
  208. };
  209. PT1State *s = opaque;
  210. uint32_t *ptr = (uint32_t *)s->buf ;
  211. addr -= s->region[0];
  212. if(access("/tmp/isdb-s", 0) == F_OK){
  213. printf("Scan Channels\n");
  214. if(addr == 0x08){
  215. printf("Data ?(%d)\n", f_f_f);
  216. rc = rc_rec[(f_f_f % MAX_CNT)] ;
  217. if(!(f_f_f % MAX_CNT)){
  218. if(fp != NULL){
  219. fprintf(fp, "Line Scan Start\n");
  220. }
  221. }
  222. f_f_f += 1 ;
  223. }else{
  224. rc = 0x00000041;
  225. }
  226. }else{
  227. if(ptr[(addr % sizeof(uint32_t))] == 0){
  228. rc = 0x20;
  229. }else if(ptr[(addr % sizeof(uint32_t))] == 0x08){
  230. rc = 0x80000020;
  231. }else if(ptr[(addr % sizeof(uint32_t))] == 0x1000000){
  232. rc = 0x80000021;
  233. }else if(ptr[(addr % sizeof(uint32_t))] == 0x2000000){
  234. rc = 0x80000023;
  235. }else if(ptr[(addr % sizeof(uint32_t))] == 0x02){
  236. if(f != 0){
  237. rc = 0x80000027;
  238. f = 0 ;
  239. }else{
  240. f += 1 ;
  241. rc = 0x80000023;
  242. }
  243. }else{
  244. if(addr == 8){
  245. rc = 0x00000041;
  246. f = 0 ;
  247. }
  248. }
  249. }
  250. return rc;
  251. }
  252. /***********************************************************/
  253. static CPUWriteMemoryFunc *pt1_pci_mmio_write[] = {
  254. PT1pci_mmio_writeb,
  255. PT1pci_mmio_writew,
  256. PT1pci_mmio_writel
  257. };
  258. static CPUWriteMemoryFunc *pt1_pci_mmio_read[] = {
  259. PT1pci_mmio_readb,
  260. PT1pci_mmio_readw,
  261. PT1pci_mmio_readl
  262. };
  263. /***********************************************************/
  264. static void pt1_map(PCIDevice *pci_dev, int region_num,
  265. uint32_t addr, uint32_t size, int type)
  266. {
  267. PCIPT1State *d = (PCIPT1State *) pci_dev;
  268. uint8_t *pci_conf;
  269. int lp ;
  270. printf("pt1_map: region_num=%d addr=%x size = %d type=%d\n",
  271. region_num, addr, size, type);
  272. pci_conf = d->dev.config;
  273. // Dump PCI Config
  274. printf(" Dump PCI Config\n");
  275. printf("00: ");
  276. for(lp = 0 ; lp < 64 ; lp++){
  277. if((!(lp % 16)) && (lp > 0)){
  278. printf("\n");
  279. printf("%02x: ", lp);
  280. }
  281. printf("%02x ", pci_conf[lp]);
  282. }
  283. printf("\n");
  284. if(region_num == 0) {
  285. cpu_register_physical_memory(addr, size, d->state.mmio_index);
  286. d->state.region[region_num] = addr;
  287. }
  288. }
  289. void pci_pt1_init(PCIBus *bus, int devfn)
  290. {
  291. PCIPT1State *d;
  292. PT1State *s ;
  293. uint8_t *pci_conf;
  294. printf("pci_pt1_init: Start\n");
  295. d = (PCIPT1State *)pci_register_device(bus,
  296. "PT1_DEV", sizeof(PCIPT1State),
  297. devfn,
  298. NULL, NULL);
  299. printf("pci_pt1_init: pci_register_device End\n");
  300. pci_conf = d->dev.config;
  301. memcpy(pci_conf, pci_copy, 256);
  302. s = &d->state;
  303. printf("pci_pt1_init: cpu_register_io_memory Start\n");
  304. d->state.mmio_index =
  305. cpu_register_io_memory(0, pt1_pci_mmio_read, pt1_pci_mmio_write,s);
  306. printf("pci_pt1_init: cpu_register_io_memory\n");
  307. pci_register_io_region(&d->dev, 0, 0x1000,
  308. PCI_ADDRESS_SPACE_MEM, pt1_map);
  309. printf("pci_pt1_init: pci_register_io_region\n");
  310. /*
  311. s = &d->pt1;
  312. s->irq = d->dev.irq[0];
  313. s->pci_dev = (PCIDevice *)d;
  314. pt1_reset(s);
  315. */
  316. register_savevm("pt1", 0, 3, pt1_save, pt1_load, d);
  317. printf("pci_pt1_init: End\n");
  318. }