2
0

mac_dbdma.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. /*
  2. * PowerMac descriptor-based DMA emulation
  3. *
  4. * Copyright (c) 2005-2007 Fabrice Bellard
  5. * Copyright (c) 2007 Jocelyn Mayer
  6. * Copyright (c) 2009 Laurent Vivier
  7. *
  8. * some parts from linux-2.6.28, arch/powerpc/include/asm/dbdma.h
  9. *
  10. * Definitions for using the Apple Descriptor-Based DMA controller
  11. * in Power Macintosh computers.
  12. *
  13. * Copyright (C) 1996 Paul Mackerras.
  14. *
  15. * some parts from mol 0.9.71
  16. *
  17. * Descriptor based DMA emulation
  18. *
  19. * Copyright (C) 1998-2004 Samuel Rydh (samuel@ibrium.se)
  20. *
  21. * Permission is hereby granted, free of charge, to any person obtaining a copy
  22. * of this software and associated documentation files (the "Software"), to deal
  23. * in the Software without restriction, including without limitation the rights
  24. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  25. * copies of the Software, and to permit persons to whom the Software is
  26. * furnished to do so, subject to the following conditions:
  27. *
  28. * The above copyright notice and this permission notice shall be included in
  29. * all copies or substantial portions of the Software.
  30. *
  31. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  32. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  33. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  34. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  35. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  36. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  37. * THE SOFTWARE.
  38. */
  39. #include "hw.h"
  40. #include "isa.h"
  41. #include "mac_dbdma.h"
  42. /* debug DBDMA */
  43. //#define DEBUG_DBDMA
  44. #ifdef DEBUG_DBDMA
  45. #define DBDMA_DPRINTF(fmt, args...) \
  46. do { printf("DBDMA: " fmt , ##args); } while (0)
  47. #else
  48. #define DBDMA_DPRINTF(fmt, args...)
  49. #endif
  50. /*
  51. */
  52. /*
  53. * DBDMA control/status registers. All little-endian.
  54. */
  55. #define DBDMA_CONTROL 0x00
  56. #define DBDMA_STATUS 0x01
  57. #define DBDMA_CMDPTR_HI 0x02
  58. #define DBDMA_CMDPTR_LO 0x03
  59. #define DBDMA_INTR_SEL 0x04
  60. #define DBDMA_BRANCH_SEL 0x05
  61. #define DBDMA_WAIT_SEL 0x06
  62. #define DBDMA_XFER_MODE 0x07
  63. #define DBDMA_DATA2PTR_HI 0x08
  64. #define DBDMA_DATA2PTR_LO 0x09
  65. #define DBDMA_RES1 0x0A
  66. #define DBDMA_ADDRESS_HI 0x0B
  67. #define DBDMA_BRANCH_ADDR_HI 0x0C
  68. #define DBDMA_RES2 0x0D
  69. #define DBDMA_RES3 0x0E
  70. #define DBDMA_RES4 0x0F
  71. #define DBDMA_REGS 16
  72. #define DBDMA_SIZE (DBDMA_REGS * sizeof(uint32_t))
  73. #define DBDMA_CHANNEL_SHIFT 7
  74. #define DBDMA_CHANNEL_SIZE (1 << DBDMA_CHANNEL_SHIFT)
  75. #define DBDMA_CHANNELS (0x1000 >> DBDMA_CHANNEL_SHIFT)
  76. /* Bits in control and status registers */
  77. #define RUN 0x8000
  78. #define PAUSE 0x4000
  79. #define FLUSH 0x2000
  80. #define WAKE 0x1000
  81. #define DEAD 0x0800
  82. #define ACTIVE 0x0400
  83. #define BT 0x0100
  84. #define DEVSTAT 0x00ff
  85. /*
  86. * DBDMA command structure. These fields are all little-endian!
  87. */
  88. typedef struct dbdma_cmd {
  89. uint16_t req_count; /* requested byte transfer count */
  90. uint16_t command; /* command word (has bit-fields) */
  91. uint32_t phy_addr; /* physical data address */
  92. uint32_t cmd_dep; /* command-dependent field */
  93. uint16_t res_count; /* residual count after completion */
  94. uint16_t xfer_status; /* transfer status */
  95. } dbdma_cmd;
  96. /* DBDMA command values in command field */
  97. #define COMMAND_MASK 0xf000
  98. #define OUTPUT_MORE 0x0000 /* transfer memory data to stream */
  99. #define OUTPUT_LAST 0x1000 /* ditto followed by end marker */
  100. #define INPUT_MORE 0x2000 /* transfer stream data to memory */
  101. #define INPUT_LAST 0x3000 /* ditto, expect end marker */
  102. #define STORE_WORD 0x4000 /* write word (4 bytes) to device reg */
  103. #define LOAD_WORD 0x5000 /* read word (4 bytes) from device reg */
  104. #define DBDMA_NOP 0x6000 /* do nothing */
  105. #define DBDMA_STOP 0x7000 /* suspend processing */
  106. /* Key values in command field */
  107. #define KEY_MASK 0x0700
  108. #define KEY_STREAM0 0x0000 /* usual data stream */
  109. #define KEY_STREAM1 0x0100 /* control/status stream */
  110. #define KEY_STREAM2 0x0200 /* device-dependent stream */
  111. #define KEY_STREAM3 0x0300 /* device-dependent stream */
  112. #define KEY_STREAM4 0x0400 /* reserved */
  113. #define KEY_REGS 0x0500 /* device register space */
  114. #define KEY_SYSTEM 0x0600 /* system memory-mapped space */
  115. #define KEY_DEVICE 0x0700 /* device memory-mapped space */
  116. /* Interrupt control values in command field */
  117. #define INTR_MASK 0x0030
  118. #define INTR_NEVER 0x0000 /* don't interrupt */
  119. #define INTR_IFSET 0x0010 /* intr if condition bit is 1 */
  120. #define INTR_IFCLR 0x0020 /* intr if condition bit is 0 */
  121. #define INTR_ALWAYS 0x0030 /* always interrupt */
  122. /* Branch control values in command field */
  123. #define BR_MASK 0x000c
  124. #define BR_NEVER 0x0000 /* don't branch */
  125. #define BR_IFSET 0x0004 /* branch if condition bit is 1 */
  126. #define BR_IFCLR 0x0008 /* branch if condition bit is 0 */
  127. #define BR_ALWAYS 0x000c /* always branch */
  128. /* Wait control values in command field */
  129. #define WAIT_MASK 0x0003
  130. #define WAIT_NEVER 0x0000 /* don't wait */
  131. #define WAIT_IFSET 0x0001 /* wait if condition bit is 1 */
  132. #define WAIT_IFCLR 0x0002 /* wait if condition bit is 0 */
  133. #define WAIT_ALWAYS 0x0003 /* always wait */
  134. typedef struct DBDMA_channel {
  135. int channel;
  136. uint32_t regs[DBDMA_REGS];
  137. qemu_irq irq;
  138. DBDMA_io io;
  139. DBDMA_rw rw;
  140. DBDMA_flush flush;
  141. dbdma_cmd current;
  142. int processing;
  143. } DBDMA_channel;
  144. #ifdef DEBUG_DBDMA
  145. static void dump_dbdma_cmd(dbdma_cmd *cmd)
  146. {
  147. printf("dbdma_cmd %p\n", cmd);
  148. printf(" req_count 0x%04x\n", le16_to_cpu(cmd->req_count));
  149. printf(" command 0x%04x\n", le16_to_cpu(cmd->command));
  150. printf(" phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr));
  151. printf(" cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep));
  152. printf(" res_count 0x%04x\n", le16_to_cpu(cmd->res_count));
  153. printf(" xfer_status 0x%04x\n", le16_to_cpu(cmd->xfer_status));
  154. }
  155. #else
  156. static void dump_dbdma_cmd(dbdma_cmd *cmd)
  157. {
  158. }
  159. #endif
  160. static void dbdma_cmdptr_load(DBDMA_channel *ch)
  161. {
  162. DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
  163. be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
  164. cpu_physical_memory_read(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
  165. (uint8_t*)&ch->current, sizeof(dbdma_cmd));
  166. }
  167. static void dbdma_cmdptr_save(DBDMA_channel *ch)
  168. {
  169. DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n",
  170. be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
  171. DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n",
  172. le16_to_cpu(ch->current.xfer_status),
  173. le16_to_cpu(ch->current.res_count));
  174. cpu_physical_memory_write(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
  175. (uint8_t*)&ch->current, sizeof(dbdma_cmd));
  176. }
  177. static void kill_channel(DBDMA_channel *ch)
  178. {
  179. DBDMA_DPRINTF("kill_channel\n");
  180. ch->regs[DBDMA_STATUS] |= cpu_to_be32(DEAD);
  181. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~ACTIVE);
  182. qemu_irq_raise(ch->irq);
  183. }
  184. static void conditional_interrupt(DBDMA_channel *ch)
  185. {
  186. dbdma_cmd *current = &ch->current;
  187. uint16_t intr;
  188. uint16_t sel_mask, sel_value;
  189. uint32_t status;
  190. int cond;
  191. DBDMA_DPRINTF("conditional_interrupt\n");
  192. intr = le16_to_cpu(current->command) & INTR_MASK;
  193. switch(intr) {
  194. case INTR_NEVER: /* don't interrupt */
  195. return;
  196. case INTR_ALWAYS: /* always interrupt */
  197. qemu_irq_raise(ch->irq);
  198. return;
  199. }
  200. status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
  201. sel_mask = (be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) >> 16) & 0x0f;
  202. sel_value = be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) & 0x0f;
  203. cond = (status & sel_mask) == (sel_value & sel_mask);
  204. switch(intr) {
  205. case INTR_IFSET: /* intr if condition bit is 1 */
  206. if (cond)
  207. qemu_irq_raise(ch->irq);
  208. return;
  209. case INTR_IFCLR: /* intr if condition bit is 0 */
  210. if (!cond)
  211. qemu_irq_raise(ch->irq);
  212. return;
  213. }
  214. }
  215. static int conditional_wait(DBDMA_channel *ch)
  216. {
  217. dbdma_cmd *current = &ch->current;
  218. uint16_t wait;
  219. uint16_t sel_mask, sel_value;
  220. uint32_t status;
  221. int cond;
  222. DBDMA_DPRINTF("conditional_wait\n");
  223. wait = le16_to_cpu(current->command) & WAIT_MASK;
  224. switch(wait) {
  225. case WAIT_NEVER: /* don't wait */
  226. return 0;
  227. case WAIT_ALWAYS: /* always wait */
  228. return 1;
  229. }
  230. status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
  231. sel_mask = (be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) >> 16) & 0x0f;
  232. sel_value = be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) & 0x0f;
  233. cond = (status & sel_mask) == (sel_value & sel_mask);
  234. switch(wait) {
  235. case WAIT_IFSET: /* wait if condition bit is 1 */
  236. if (cond)
  237. return 1;
  238. return 0;
  239. case WAIT_IFCLR: /* wait if condition bit is 0 */
  240. if (!cond)
  241. return 1;
  242. return 0;
  243. }
  244. return 0;
  245. }
  246. static void next(DBDMA_channel *ch)
  247. {
  248. uint32_t cp;
  249. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~BT);
  250. cp = be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]);
  251. ch->regs[DBDMA_CMDPTR_LO] = cpu_to_be32(cp + sizeof(dbdma_cmd));
  252. dbdma_cmdptr_load(ch);
  253. }
  254. static void branch(DBDMA_channel *ch)
  255. {
  256. dbdma_cmd *current = &ch->current;
  257. ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;
  258. ch->regs[DBDMA_STATUS] |= cpu_to_be32(BT);
  259. dbdma_cmdptr_load(ch);
  260. }
  261. static void conditional_branch(DBDMA_channel *ch)
  262. {
  263. dbdma_cmd *current = &ch->current;
  264. uint16_t br;
  265. uint16_t sel_mask, sel_value;
  266. uint32_t status;
  267. int cond;
  268. DBDMA_DPRINTF("conditional_branch\n");
  269. /* check if we must branch */
  270. br = le16_to_cpu(current->command) & BR_MASK;
  271. switch(br) {
  272. case BR_NEVER: /* don't branch */
  273. next(ch);
  274. return;
  275. case BR_ALWAYS: /* always branch */
  276. branch(ch);
  277. return;
  278. }
  279. status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
  280. sel_mask = (be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) >> 16) & 0x0f;
  281. sel_value = be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) & 0x0f;
  282. cond = (status & sel_mask) == (sel_value & sel_mask);
  283. switch(br) {
  284. case BR_IFSET: /* branch if condition bit is 1 */
  285. if (cond)
  286. branch(ch);
  287. else
  288. next(ch);
  289. return;
  290. case BR_IFCLR: /* branch if condition bit is 0 */
  291. if (!cond)
  292. branch(ch);
  293. else
  294. next(ch);
  295. return;
  296. }
  297. }
  298. static QEMUBH *dbdma_bh;
  299. static void channel_run(DBDMA_channel *ch);
  300. static void dbdma_end(DBDMA_io *io)
  301. {
  302. DBDMA_channel *ch = io->channel;
  303. dbdma_cmd *current = &ch->current;
  304. if (conditional_wait(ch))
  305. goto wait;
  306. current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
  307. current->res_count = cpu_to_le16(be32_to_cpu(io->len));
  308. dbdma_cmdptr_save(ch);
  309. if (io->is_last)
  310. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
  311. conditional_interrupt(ch);
  312. conditional_branch(ch);
  313. wait:
  314. ch->processing = 0;
  315. if ((ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN)) &&
  316. (ch->regs[DBDMA_STATUS] & cpu_to_be32(ACTIVE)))
  317. channel_run(ch);
  318. }
  319. static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
  320. uint16_t req_count, int is_last)
  321. {
  322. DBDMA_DPRINTF("start_output\n");
  323. /* KEY_REGS, KEY_DEVICE and KEY_STREAM
  324. * are not implemented in the mac-io chip
  325. */
  326. DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
  327. if (!addr || key > KEY_STREAM3) {
  328. kill_channel(ch);
  329. return;
  330. }
  331. ch->io.addr = addr;
  332. ch->io.len = req_count;
  333. ch->io.is_last = is_last;
  334. ch->io.dma_end = dbdma_end;
  335. ch->io.is_dma_out = 1;
  336. ch->processing = 1;
  337. ch->rw(&ch->io);
  338. }
  339. static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
  340. uint16_t req_count, int is_last)
  341. {
  342. DBDMA_DPRINTF("start_input\n");
  343. /* KEY_REGS, KEY_DEVICE and KEY_STREAM
  344. * are not implemented in the mac-io chip
  345. */
  346. if (!addr || key > KEY_STREAM3) {
  347. kill_channel(ch);
  348. return;
  349. }
  350. ch->io.addr = addr;
  351. ch->io.len = req_count;
  352. ch->io.is_last = is_last;
  353. ch->io.dma_end = dbdma_end;
  354. ch->io.is_dma_out = 0;
  355. ch->processing = 1;
  356. ch->rw(&ch->io);
  357. }
  358. static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
  359. uint16_t len)
  360. {
  361. dbdma_cmd *current = &ch->current;
  362. uint32_t val;
  363. DBDMA_DPRINTF("load_word\n");
  364. /* only implements KEY_SYSTEM */
  365. if (key != KEY_SYSTEM) {
  366. printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key);
  367. kill_channel(ch);
  368. return;
  369. }
  370. cpu_physical_memory_read(addr, (uint8_t*)&val, len);
  371. if (len == 2)
  372. val = (val << 16) | (current->cmd_dep & 0x0000ffff);
  373. else if (len == 1)
  374. val = (val << 24) | (current->cmd_dep & 0x00ffffff);
  375. current->cmd_dep = val;
  376. if (conditional_wait(ch))
  377. goto wait;
  378. current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
  379. dbdma_cmdptr_save(ch);
  380. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
  381. conditional_interrupt(ch);
  382. next(ch);
  383. wait:
  384. qemu_bh_schedule(dbdma_bh);
  385. }
  386. static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
  387. uint16_t len)
  388. {
  389. dbdma_cmd *current = &ch->current;
  390. uint32_t val;
  391. DBDMA_DPRINTF("store_word\n");
  392. /* only implements KEY_SYSTEM */
  393. if (key != KEY_SYSTEM) {
  394. printf("DBDMA: STORE_WORD, unimplemented key %x\n", key);
  395. kill_channel(ch);
  396. return;
  397. }
  398. val = current->cmd_dep;
  399. if (len == 2)
  400. val >>= 16;
  401. else if (len == 1)
  402. val >>= 24;
  403. cpu_physical_memory_write(addr, (uint8_t*)&val, len);
  404. if (conditional_wait(ch))
  405. goto wait;
  406. current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
  407. dbdma_cmdptr_save(ch);
  408. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
  409. conditional_interrupt(ch);
  410. next(ch);
  411. wait:
  412. qemu_bh_schedule(dbdma_bh);
  413. }
  414. static void nop(DBDMA_channel *ch)
  415. {
  416. dbdma_cmd *current = &ch->current;
  417. if (conditional_wait(ch))
  418. goto wait;
  419. current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
  420. dbdma_cmdptr_save(ch);
  421. conditional_interrupt(ch);
  422. conditional_branch(ch);
  423. wait:
  424. qemu_bh_schedule(dbdma_bh);
  425. }
  426. static void stop(DBDMA_channel *ch)
  427. {
  428. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD|FLUSH));
  429. /* the stop command does not increment command pointer */
  430. }
  431. static void channel_run(DBDMA_channel *ch)
  432. {
  433. dbdma_cmd *current = &ch->current;
  434. uint16_t cmd, key;
  435. uint16_t req_count;
  436. uint32_t phy_addr;
  437. DBDMA_DPRINTF("channel_run\n");
  438. dump_dbdma_cmd(current);
  439. /* clear WAKE flag at command fetch */
  440. ch->regs[DBDMA_STATUS] &= cpu_to_be32(~WAKE);
  441. cmd = le16_to_cpu(current->command) & COMMAND_MASK;
  442. switch (cmd) {
  443. case DBDMA_NOP:
  444. nop(ch);
  445. return;
  446. case DBDMA_STOP:
  447. stop(ch);
  448. return;
  449. }
  450. key = le16_to_cpu(current->command) & 0x0700;
  451. req_count = le16_to_cpu(current->req_count);
  452. phy_addr = le32_to_cpu(current->phy_addr);
  453. if (key == KEY_STREAM4) {
  454. printf("command %x, invalid key 4\n", cmd);
  455. kill_channel(ch);
  456. return;
  457. }
  458. switch (cmd) {
  459. case OUTPUT_MORE:
  460. start_output(ch, key, phy_addr, req_count, 0);
  461. return;
  462. case OUTPUT_LAST:
  463. start_output(ch, key, phy_addr, req_count, 1);
  464. return;
  465. case INPUT_MORE:
  466. start_input(ch, key, phy_addr, req_count, 0);
  467. return;
  468. case INPUT_LAST:
  469. start_input(ch, key, phy_addr, req_count, 1);
  470. return;
  471. }
  472. if (key < KEY_REGS) {
  473. printf("command %x, invalid key %x\n", cmd, key);
  474. key = KEY_SYSTEM;
  475. }
  476. /* for LOAD_WORD and STORE_WORD, req_count is on 3 bits
  477. * and BRANCH is invalid
  478. */
  479. req_count = req_count & 0x0007;
  480. if (req_count & 0x4) {
  481. req_count = 4;
  482. phy_addr &= ~3;
  483. } else if (req_count & 0x2) {
  484. req_count = 2;
  485. phy_addr &= ~1;
  486. } else
  487. req_count = 1;
  488. switch (cmd) {
  489. case LOAD_WORD:
  490. load_word(ch, key, phy_addr, req_count);
  491. return;
  492. case STORE_WORD:
  493. store_word(ch, key, phy_addr, req_count);
  494. return;
  495. }
  496. }
  497. static void DBDMA_run (DBDMA_channel *ch)
  498. {
  499. int channel;
  500. for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
  501. uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
  502. if (!ch->processing && (status & RUN) && (status & ACTIVE))
  503. channel_run(ch);
  504. }
  505. }
  506. static void DBDMA_run_bh(void *opaque)
  507. {
  508. DBDMA_channel *ch = opaque;
  509. DBDMA_DPRINTF("DBDMA_run_bh\n");
  510. DBDMA_run(ch);
  511. }
  512. void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
  513. DBDMA_rw rw, DBDMA_flush flush,
  514. void *opaque)
  515. {
  516. DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan;
  517. DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
  518. ch->irq = irq;
  519. ch->channel = nchan;
  520. ch->rw = rw;
  521. ch->flush = flush;
  522. ch->io.opaque = opaque;
  523. ch->io.channel = ch;
  524. }
  525. void DBDMA_schedule(void)
  526. {
  527. CPUState *env = cpu_single_env;
  528. if (env)
  529. cpu_interrupt(env, CPU_INTERRUPT_EXIT);
  530. }
  531. static void
  532. dbdma_control_write(DBDMA_channel *ch)
  533. {
  534. uint16_t mask, value;
  535. uint32_t status;
  536. mask = (be32_to_cpu(ch->regs[DBDMA_CONTROL]) >> 16) & 0xffff;
  537. value = be32_to_cpu(ch->regs[DBDMA_CONTROL]) & 0xffff;
  538. value &= (RUN | PAUSE | FLUSH | WAKE | DEVSTAT);
  539. status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
  540. status = (value & mask) | (status & ~mask);
  541. if (status & WAKE)
  542. status |= ACTIVE;
  543. if (status & RUN) {
  544. status |= ACTIVE;
  545. status &= ~DEAD;
  546. }
  547. if (status & PAUSE)
  548. status &= ~ACTIVE;
  549. if ((be32_to_cpu(ch->regs[DBDMA_STATUS]) & RUN) && !(status & RUN)) {
  550. /* RUN is cleared */
  551. status &= ~(ACTIVE|DEAD);
  552. }
  553. DBDMA_DPRINTF(" status 0x%08x\n", status);
  554. ch->regs[DBDMA_STATUS] = cpu_to_be32(status);
  555. if (status & ACTIVE)
  556. qemu_bh_schedule(dbdma_bh);
  557. if (status & FLUSH)
  558. ch->flush(&ch->io);
  559. }
  560. static void dbdma_writel (void *opaque,
  561. target_phys_addr_t addr, uint32_t value)
  562. {
  563. int channel = addr >> DBDMA_CHANNEL_SHIFT;
  564. DBDMA_channel *ch = (DBDMA_channel *)opaque + channel;
  565. int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
  566. DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value);
  567. DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
  568. (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
  569. /* cmdptr cannot be modified if channel is RUN or ACTIVE */
  570. if (reg == DBDMA_CMDPTR_LO &&
  571. (ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN | ACTIVE)))
  572. return;
  573. ch->regs[reg] = value;
  574. switch(reg) {
  575. case DBDMA_CONTROL:
  576. dbdma_control_write(ch);
  577. break;
  578. case DBDMA_CMDPTR_LO:
  579. /* 16-byte aligned */
  580. ch->regs[DBDMA_CMDPTR_LO] &= cpu_to_be32(~0xf);
  581. dbdma_cmdptr_load(ch);
  582. break;
  583. case DBDMA_STATUS:
  584. case DBDMA_INTR_SEL:
  585. case DBDMA_BRANCH_SEL:
  586. case DBDMA_WAIT_SEL:
  587. /* nothing to do */
  588. break;
  589. case DBDMA_XFER_MODE:
  590. case DBDMA_CMDPTR_HI:
  591. case DBDMA_DATA2PTR_HI:
  592. case DBDMA_DATA2PTR_LO:
  593. case DBDMA_ADDRESS_HI:
  594. case DBDMA_BRANCH_ADDR_HI:
  595. case DBDMA_RES1:
  596. case DBDMA_RES2:
  597. case DBDMA_RES3:
  598. case DBDMA_RES4:
  599. /* unused */
  600. break;
  601. }
  602. }
  603. static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
  604. {
  605. uint32_t value;
  606. int channel = addr >> DBDMA_CHANNEL_SHIFT;
  607. DBDMA_channel *ch = (DBDMA_channel *)opaque + channel;
  608. int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
  609. value = ch->regs[reg];
  610. DBDMA_DPRINTF("readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
  611. DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
  612. (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
  613. switch(reg) {
  614. case DBDMA_CONTROL:
  615. value = 0;
  616. break;
  617. case DBDMA_STATUS:
  618. case DBDMA_CMDPTR_LO:
  619. case DBDMA_INTR_SEL:
  620. case DBDMA_BRANCH_SEL:
  621. case DBDMA_WAIT_SEL:
  622. /* nothing to do */
  623. break;
  624. case DBDMA_XFER_MODE:
  625. case DBDMA_CMDPTR_HI:
  626. case DBDMA_DATA2PTR_HI:
  627. case DBDMA_DATA2PTR_LO:
  628. case DBDMA_ADDRESS_HI:
  629. case DBDMA_BRANCH_ADDR_HI:
  630. /* unused */
  631. value = 0;
  632. break;
  633. case DBDMA_RES1:
  634. case DBDMA_RES2:
  635. case DBDMA_RES3:
  636. case DBDMA_RES4:
  637. /* reserved */
  638. break;
  639. }
  640. return value;
  641. }
  642. static CPUWriteMemoryFunc *dbdma_write[] = {
  643. NULL,
  644. NULL,
  645. dbdma_writel,
  646. };
  647. static CPUReadMemoryFunc *dbdma_read[] = {
  648. NULL,
  649. NULL,
  650. dbdma_readl,
  651. };
  652. static void dbdma_save(QEMUFile *f, void *opaque)
  653. {
  654. DBDMA_channel *s = opaque;
  655. unsigned int i, j;
  656. for (i = 0; i < DBDMA_CHANNELS; i++)
  657. for (j = 0; j < DBDMA_REGS; j++)
  658. qemu_put_be32s(f, &s[i].regs[j]);
  659. }
  660. static int dbdma_load(QEMUFile *f, void *opaque, int version_id)
  661. {
  662. DBDMA_channel *s = opaque;
  663. unsigned int i, j;
  664. if (version_id != 2)
  665. return -EINVAL;
  666. for (i = 0; i < DBDMA_CHANNELS; i++)
  667. for (j = 0; j < DBDMA_REGS; j++)
  668. qemu_get_be32s(f, &s[i].regs[j]);
  669. return 0;
  670. }
  671. static void dbdma_reset(void *opaque)
  672. {
  673. DBDMA_channel *s = opaque;
  674. int i;
  675. for (i = 0; i < DBDMA_CHANNELS; i++)
  676. memset(s[i].regs, 0, DBDMA_SIZE);
  677. }
  678. void* DBDMA_init (int *dbdma_mem_index)
  679. {
  680. DBDMA_channel *s;
  681. s = qemu_mallocz(sizeof(DBDMA_channel) * DBDMA_CHANNELS);
  682. *dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, s);
  683. register_savevm("dbdma", -1, 1, dbdma_save, dbdma_load, s);
  684. qemu_register_reset(dbdma_reset, s);
  685. dbdma_reset(s);
  686. dbdma_bh = qemu_bh_new(DBDMA_run_bh, s);
  687. return s;
  688. }