2
0

esp.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*
  2. * QEMU ESP/NCR53C9x emulation
  3. *
  4. * Copyright (c) 2005-2006 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "hw.h"
  25. #include "scsi-disk.h"
  26. #include "scsi.h"
  27. /* debug ESP card */
  28. //#define DEBUG_ESP
  29. /*
  30. * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
  31. * also produced as NCR89C100. See
  32. * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
  33. * and
  34. * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
  35. */
  36. #ifdef DEBUG_ESP
  37. #define DPRINTF(fmt, args...) \
  38. do { printf("ESP: " fmt , ##args); } while (0)
  39. #else
  40. #define DPRINTF(fmt, args...) do {} while (0)
  41. #endif
  42. #define ESP_ERROR(fmt, args...) \
  43. do { printf("ESP ERROR: %s: " fmt, __func__ , ##args); } while (0)
  44. #define ESP_REGS 16
  45. #define TI_BUFSZ 16
  46. typedef struct ESPState ESPState;
  47. struct ESPState {
  48. uint32_t it_shift;
  49. qemu_irq irq;
  50. uint8_t rregs[ESP_REGS];
  51. uint8_t wregs[ESP_REGS];
  52. int32_t ti_size;
  53. uint32_t ti_rptr, ti_wptr;
  54. uint8_t ti_buf[TI_BUFSZ];
  55. uint32_t sense;
  56. uint32_t dma;
  57. SCSIDevice *scsi_dev[ESP_MAX_DEVS];
  58. SCSIDevice *current_dev;
  59. uint8_t cmdbuf[TI_BUFSZ];
  60. uint32_t cmdlen;
  61. uint32_t do_cmd;
  62. /* The amount of data left in the current DMA transfer. */
  63. uint32_t dma_left;
  64. /* The size of the current DMA transfer. Zero if no transfer is in
  65. progress. */
  66. uint32_t dma_counter;
  67. uint8_t *async_buf;
  68. uint32_t async_len;
  69. espdma_memory_read_write dma_memory_read;
  70. espdma_memory_read_write dma_memory_write;
  71. void *dma_opaque;
  72. };
  73. #define ESP_TCLO 0x0
  74. #define ESP_TCMID 0x1
  75. #define ESP_FIFO 0x2
  76. #define ESP_CMD 0x3
  77. #define ESP_RSTAT 0x4
  78. #define ESP_WBUSID 0x4
  79. #define ESP_RINTR 0x5
  80. #define ESP_WSEL 0x5
  81. #define ESP_RSEQ 0x6
  82. #define ESP_WSYNTP 0x6
  83. #define ESP_RFLAGS 0x7
  84. #define ESP_WSYNO 0x7
  85. #define ESP_CFG1 0x8
  86. #define ESP_RRES1 0x9
  87. #define ESP_WCCF 0x9
  88. #define ESP_RRES2 0xa
  89. #define ESP_WTEST 0xa
  90. #define ESP_CFG2 0xb
  91. #define ESP_CFG3 0xc
  92. #define ESP_RES3 0xd
  93. #define ESP_TCHI 0xe
  94. #define ESP_RES4 0xf
  95. #define CMD_DMA 0x80
  96. #define CMD_CMD 0x7f
  97. #define CMD_NOP 0x00
  98. #define CMD_FLUSH 0x01
  99. #define CMD_RESET 0x02
  100. #define CMD_BUSRESET 0x03
  101. #define CMD_TI 0x10
  102. #define CMD_ICCS 0x11
  103. #define CMD_MSGACC 0x12
  104. #define CMD_SATN 0x1a
  105. #define CMD_SELATN 0x42
  106. #define CMD_SELATNS 0x43
  107. #define CMD_ENSEL 0x44
  108. #define STAT_DO 0x00
  109. #define STAT_DI 0x01
  110. #define STAT_CD 0x02
  111. #define STAT_ST 0x03
  112. #define STAT_MO 0x06
  113. #define STAT_MI 0x07
  114. #define STAT_PIO_MASK 0x06
  115. #define STAT_TC 0x10
  116. #define STAT_PE 0x20
  117. #define STAT_GE 0x40
  118. #define STAT_INT 0x80
  119. #define BUSID_DID 0x07
  120. #define INTR_FC 0x08
  121. #define INTR_BS 0x10
  122. #define INTR_DC 0x20
  123. #define INTR_RST 0x80
  124. #define SEQ_0 0x0
  125. #define SEQ_CD 0x4
  126. #define CFG1_RESREPT 0x40
  127. #define TCHI_FAS100A 0x4
  128. static void esp_raise_irq(ESPState *s)
  129. {
  130. if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
  131. s->rregs[ESP_RSTAT] |= STAT_INT;
  132. qemu_irq_raise(s->irq);
  133. }
  134. }
  135. static void esp_lower_irq(ESPState *s)
  136. {
  137. if (s->rregs[ESP_RSTAT] & STAT_INT) {
  138. s->rregs[ESP_RSTAT] &= ~STAT_INT;
  139. qemu_irq_lower(s->irq);
  140. }
  141. }
  142. static uint32_t get_cmd(ESPState *s, uint8_t *buf)
  143. {
  144. uint32_t dmalen;
  145. int target;
  146. target = s->wregs[ESP_WBUSID] & BUSID_DID;
  147. if (s->dma) {
  148. dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
  149. s->dma_memory_read(s->dma_opaque, buf, dmalen);
  150. } else {
  151. dmalen = s->ti_size;
  152. memcpy(buf, s->ti_buf, dmalen);
  153. buf[0] = 0;
  154. }
  155. DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
  156. s->ti_size = 0;
  157. s->ti_rptr = 0;
  158. s->ti_wptr = 0;
  159. if (s->current_dev) {
  160. /* Started a new command before the old one finished. Cancel it. */
  161. s->current_dev->cancel_io(s->current_dev, 0);
  162. s->async_len = 0;
  163. }
  164. if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) {
  165. // No such drive
  166. s->rregs[ESP_RSTAT] = 0;
  167. s->rregs[ESP_RINTR] = INTR_DC;
  168. s->rregs[ESP_RSEQ] = SEQ_0;
  169. esp_raise_irq(s);
  170. return 0;
  171. }
  172. s->current_dev = s->scsi_dev[target];
  173. return dmalen;
  174. }
  175. static void do_cmd(ESPState *s, uint8_t *buf)
  176. {
  177. int32_t datalen;
  178. int lun;
  179. DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
  180. lun = buf[0] & 7;
  181. datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun);
  182. s->ti_size = datalen;
  183. if (datalen != 0) {
  184. s->rregs[ESP_RSTAT] = STAT_TC;
  185. s->dma_left = 0;
  186. s->dma_counter = 0;
  187. if (datalen > 0) {
  188. s->rregs[ESP_RSTAT] |= STAT_DI;
  189. s->current_dev->read_data(s->current_dev, 0);
  190. } else {
  191. s->rregs[ESP_RSTAT] |= STAT_DO;
  192. s->current_dev->write_data(s->current_dev, 0);
  193. }
  194. }
  195. s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
  196. s->rregs[ESP_RSEQ] = SEQ_CD;
  197. esp_raise_irq(s);
  198. }
  199. static void handle_satn(ESPState *s)
  200. {
  201. uint8_t buf[32];
  202. int len;
  203. len = get_cmd(s, buf);
  204. if (len)
  205. do_cmd(s, buf);
  206. }
  207. static void handle_satn_stop(ESPState *s)
  208. {
  209. s->cmdlen = get_cmd(s, s->cmdbuf);
  210. if (s->cmdlen) {
  211. DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
  212. s->do_cmd = 1;
  213. s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
  214. s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
  215. s->rregs[ESP_RSEQ] = SEQ_CD;
  216. esp_raise_irq(s);
  217. }
  218. }
  219. static void write_response(ESPState *s)
  220. {
  221. DPRINTF("Transfer status (sense=%d)\n", s->sense);
  222. s->ti_buf[0] = s->sense;
  223. s->ti_buf[1] = 0;
  224. if (s->dma) {
  225. s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
  226. s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
  227. s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
  228. s->rregs[ESP_RSEQ] = SEQ_CD;
  229. } else {
  230. s->ti_size = 2;
  231. s->ti_rptr = 0;
  232. s->ti_wptr = 0;
  233. s->rregs[ESP_RFLAGS] = 2;
  234. }
  235. esp_raise_irq(s);
  236. }
  237. static void esp_dma_done(ESPState *s)
  238. {
  239. s->rregs[ESP_RSTAT] |= STAT_TC;
  240. s->rregs[ESP_RINTR] = INTR_BS;
  241. s->rregs[ESP_RSEQ] = 0;
  242. s->rregs[ESP_RFLAGS] = 0;
  243. s->rregs[ESP_TCLO] = 0;
  244. s->rregs[ESP_TCMID] = 0;
  245. esp_raise_irq(s);
  246. }
  247. static void esp_do_dma(ESPState *s)
  248. {
  249. uint32_t len;
  250. int to_device;
  251. to_device = (s->ti_size < 0);
  252. len = s->dma_left;
  253. if (s->do_cmd) {
  254. DPRINTF("command len %d + %d\n", s->cmdlen, len);
  255. s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
  256. s->ti_size = 0;
  257. s->cmdlen = 0;
  258. s->do_cmd = 0;
  259. do_cmd(s, s->cmdbuf);
  260. return;
  261. }
  262. if (s->async_len == 0) {
  263. /* Defer until data is available. */
  264. return;
  265. }
  266. if (len > s->async_len) {
  267. len = s->async_len;
  268. }
  269. if (to_device) {
  270. s->dma_memory_read(s->dma_opaque, s->async_buf, len);
  271. } else {
  272. s->dma_memory_write(s->dma_opaque, s->async_buf, len);
  273. }
  274. s->dma_left -= len;
  275. s->async_buf += len;
  276. s->async_len -= len;
  277. if (to_device)
  278. s->ti_size += len;
  279. else
  280. s->ti_size -= len;
  281. if (s->async_len == 0) {
  282. if (to_device) {
  283. // ti_size is negative
  284. s->current_dev->write_data(s->current_dev, 0);
  285. } else {
  286. s->current_dev->read_data(s->current_dev, 0);
  287. /* If there is still data to be read from the device then
  288. complete the DMA operation immediately. Otherwise defer
  289. until the scsi layer has completed. */
  290. if (s->dma_left == 0 && s->ti_size > 0) {
  291. esp_dma_done(s);
  292. }
  293. }
  294. } else {
  295. /* Partially filled a scsi buffer. Complete immediately. */
  296. esp_dma_done(s);
  297. }
  298. }
  299. static void esp_command_complete(void *opaque, int reason, uint32_t tag,
  300. uint32_t arg)
  301. {
  302. ESPState *s = (ESPState *)opaque;
  303. if (reason == SCSI_REASON_DONE) {
  304. DPRINTF("SCSI Command complete\n");
  305. if (s->ti_size != 0)
  306. DPRINTF("SCSI command completed unexpectedly\n");
  307. s->ti_size = 0;
  308. s->dma_left = 0;
  309. s->async_len = 0;
  310. if (arg)
  311. DPRINTF("Command failed\n");
  312. s->sense = arg;
  313. s->rregs[ESP_RSTAT] = STAT_ST;
  314. esp_dma_done(s);
  315. s->current_dev = NULL;
  316. } else {
  317. DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
  318. s->async_len = arg;
  319. s->async_buf = s->current_dev->get_buf(s->current_dev, 0);
  320. if (s->dma_left) {
  321. esp_do_dma(s);
  322. } else if (s->dma_counter != 0 && s->ti_size <= 0) {
  323. /* If this was the last part of a DMA transfer then the
  324. completion interrupt is deferred to here. */
  325. esp_dma_done(s);
  326. }
  327. }
  328. }
  329. static void handle_ti(ESPState *s)
  330. {
  331. uint32_t dmalen, minlen;
  332. dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
  333. if (dmalen==0) {
  334. dmalen=0x10000;
  335. }
  336. s->dma_counter = dmalen;
  337. if (s->do_cmd)
  338. minlen = (dmalen < 32) ? dmalen : 32;
  339. else if (s->ti_size < 0)
  340. minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
  341. else
  342. minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
  343. DPRINTF("Transfer Information len %d\n", minlen);
  344. if (s->dma) {
  345. s->dma_left = minlen;
  346. s->rregs[ESP_RSTAT] &= ~STAT_TC;
  347. esp_do_dma(s);
  348. } else if (s->do_cmd) {
  349. DPRINTF("command len %d\n", s->cmdlen);
  350. s->ti_size = 0;
  351. s->cmdlen = 0;
  352. s->do_cmd = 0;
  353. do_cmd(s, s->cmdbuf);
  354. return;
  355. }
  356. }
  357. static void esp_reset(void *opaque)
  358. {
  359. ESPState *s = opaque;
  360. esp_lower_irq(s);
  361. memset(s->rregs, 0, ESP_REGS);
  362. memset(s->wregs, 0, ESP_REGS);
  363. s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
  364. s->ti_size = 0;
  365. s->ti_rptr = 0;
  366. s->ti_wptr = 0;
  367. s->dma = 0;
  368. s->do_cmd = 0;
  369. s->rregs[ESP_CFG1] = 7;
  370. }
  371. static void parent_esp_reset(void *opaque, int irq, int level)
  372. {
  373. if (level)
  374. esp_reset(opaque);
  375. }
  376. static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
  377. {
  378. ESPState *s = opaque;
  379. uint32_t saddr;
  380. saddr = addr >> s->it_shift;
  381. DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
  382. switch (saddr) {
  383. case ESP_FIFO:
  384. if (s->ti_size > 0) {
  385. s->ti_size--;
  386. if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
  387. /* Data out. */
  388. ESP_ERROR("PIO data read not implemented\n");
  389. s->rregs[ESP_FIFO] = 0;
  390. } else {
  391. s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
  392. }
  393. esp_raise_irq(s);
  394. }
  395. if (s->ti_size == 0) {
  396. s->ti_rptr = 0;
  397. s->ti_wptr = 0;
  398. }
  399. break;
  400. case ESP_RINTR:
  401. // Clear interrupt/error status bits
  402. s->rregs[ESP_RSTAT] &= ~(STAT_GE | STAT_PE);
  403. esp_lower_irq(s);
  404. break;
  405. default:
  406. break;
  407. }
  408. return s->rregs[saddr];
  409. }
  410. static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  411. {
  412. ESPState *s = opaque;
  413. uint32_t saddr;
  414. saddr = addr >> s->it_shift;
  415. DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
  416. val);
  417. switch (saddr) {
  418. case ESP_TCLO:
  419. case ESP_TCMID:
  420. s->rregs[ESP_RSTAT] &= ~STAT_TC;
  421. break;
  422. case ESP_FIFO:
  423. if (s->do_cmd) {
  424. s->cmdbuf[s->cmdlen++] = val & 0xff;
  425. } else if (s->ti_size == TI_BUFSZ - 1) {
  426. ESP_ERROR("fifo overrun\n");
  427. } else {
  428. s->ti_size++;
  429. s->ti_buf[s->ti_wptr++] = val & 0xff;
  430. }
  431. break;
  432. case ESP_CMD:
  433. s->rregs[saddr] = val;
  434. if (val & CMD_DMA) {
  435. s->dma = 1;
  436. /* Reload DMA counter. */
  437. s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
  438. s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
  439. } else {
  440. s->dma = 0;
  441. }
  442. switch(val & CMD_CMD) {
  443. case CMD_NOP:
  444. DPRINTF("NOP (%2.2x)\n", val);
  445. break;
  446. case CMD_FLUSH:
  447. DPRINTF("Flush FIFO (%2.2x)\n", val);
  448. //s->ti_size = 0;
  449. s->rregs[ESP_RINTR] = INTR_FC;
  450. s->rregs[ESP_RSEQ] = 0;
  451. s->rregs[ESP_RFLAGS] = 0;
  452. break;
  453. case CMD_RESET:
  454. DPRINTF("Chip reset (%2.2x)\n", val);
  455. esp_reset(s);
  456. break;
  457. case CMD_BUSRESET:
  458. DPRINTF("Bus reset (%2.2x)\n", val);
  459. s->rregs[ESP_RINTR] = INTR_RST;
  460. if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
  461. esp_raise_irq(s);
  462. }
  463. break;
  464. case CMD_TI:
  465. handle_ti(s);
  466. break;
  467. case CMD_ICCS:
  468. DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
  469. write_response(s);
  470. s->rregs[ESP_RINTR] = INTR_FC;
  471. s->rregs[ESP_RSTAT] |= STAT_MI;
  472. break;
  473. case CMD_MSGACC:
  474. DPRINTF("Message Accepted (%2.2x)\n", val);
  475. write_response(s);
  476. s->rregs[ESP_RINTR] = INTR_DC;
  477. s->rregs[ESP_RSEQ] = 0;
  478. break;
  479. case CMD_SATN:
  480. DPRINTF("Set ATN (%2.2x)\n", val);
  481. break;
  482. case CMD_SELATN:
  483. DPRINTF("Set ATN (%2.2x)\n", val);
  484. handle_satn(s);
  485. break;
  486. case CMD_SELATNS:
  487. DPRINTF("Set ATN & stop (%2.2x)\n", val);
  488. handle_satn_stop(s);
  489. break;
  490. case CMD_ENSEL:
  491. DPRINTF("Enable selection (%2.2x)\n", val);
  492. s->rregs[ESP_RINTR] = 0;
  493. break;
  494. default:
  495. ESP_ERROR("Unhandled ESP command (%2.2x)\n", val);
  496. break;
  497. }
  498. break;
  499. case ESP_WBUSID ... ESP_WSYNO:
  500. break;
  501. case ESP_CFG1:
  502. s->rregs[saddr] = val;
  503. break;
  504. case ESP_WCCF ... ESP_WTEST:
  505. break;
  506. case ESP_CFG2 ... ESP_RES4:
  507. s->rregs[saddr] = val;
  508. break;
  509. default:
  510. ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr);
  511. return;
  512. }
  513. s->wregs[saddr] = val;
  514. }
  515. static CPUReadMemoryFunc *esp_mem_read[3] = {
  516. esp_mem_readb,
  517. NULL,
  518. NULL,
  519. };
  520. static CPUWriteMemoryFunc *esp_mem_write[3] = {
  521. esp_mem_writeb,
  522. NULL,
  523. esp_mem_writeb,
  524. };
  525. static void esp_save(QEMUFile *f, void *opaque)
  526. {
  527. ESPState *s = opaque;
  528. qemu_put_buffer(f, s->rregs, ESP_REGS);
  529. qemu_put_buffer(f, s->wregs, ESP_REGS);
  530. qemu_put_sbe32s(f, &s->ti_size);
  531. qemu_put_be32s(f, &s->ti_rptr);
  532. qemu_put_be32s(f, &s->ti_wptr);
  533. qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
  534. qemu_put_be32s(f, &s->sense);
  535. qemu_put_be32s(f, &s->dma);
  536. qemu_put_buffer(f, s->cmdbuf, TI_BUFSZ);
  537. qemu_put_be32s(f, &s->cmdlen);
  538. qemu_put_be32s(f, &s->do_cmd);
  539. qemu_put_be32s(f, &s->dma_left);
  540. // There should be no transfers in progress, so dma_counter is not saved
  541. }
  542. static int esp_load(QEMUFile *f, void *opaque, int version_id)
  543. {
  544. ESPState *s = opaque;
  545. if (version_id != 3)
  546. return -EINVAL; // Cannot emulate 2
  547. qemu_get_buffer(f, s->rregs, ESP_REGS);
  548. qemu_get_buffer(f, s->wregs, ESP_REGS);
  549. qemu_get_sbe32s(f, &s->ti_size);
  550. qemu_get_be32s(f, &s->ti_rptr);
  551. qemu_get_be32s(f, &s->ti_wptr);
  552. qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
  553. qemu_get_be32s(f, &s->sense);
  554. qemu_get_be32s(f, &s->dma);
  555. qemu_get_buffer(f, s->cmdbuf, TI_BUFSZ);
  556. qemu_get_be32s(f, &s->cmdlen);
  557. qemu_get_be32s(f, &s->do_cmd);
  558. qemu_get_be32s(f, &s->dma_left);
  559. return 0;
  560. }
  561. void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id)
  562. {
  563. ESPState *s = (ESPState *)opaque;
  564. if (id < 0) {
  565. for (id = 0; id < ESP_MAX_DEVS; id++) {
  566. if (id == (s->rregs[ESP_CFG1] & 0x7))
  567. continue;
  568. if (s->scsi_dev[id] == NULL)
  569. break;
  570. }
  571. }
  572. if (id >= ESP_MAX_DEVS) {
  573. DPRINTF("Bad Device ID %d\n", id);
  574. return;
  575. }
  576. if (s->scsi_dev[id]) {
  577. DPRINTF("Destroying device %d\n", id);
  578. s->scsi_dev[id]->destroy(s->scsi_dev[id]);
  579. }
  580. DPRINTF("Attaching block device %d\n", id);
  581. /* Command queueing is not implemented. */
  582. s->scsi_dev[id] = scsi_generic_init(bd, 0, esp_command_complete, s);
  583. if (s->scsi_dev[id] == NULL)
  584. s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
  585. }
  586. void *esp_init(target_phys_addr_t espaddr, int it_shift,
  587. espdma_memory_read_write dma_memory_read,
  588. espdma_memory_read_write dma_memory_write,
  589. void *dma_opaque, qemu_irq irq, qemu_irq *reset)
  590. {
  591. ESPState *s;
  592. int esp_io_memory;
  593. s = qemu_mallocz(sizeof(ESPState));
  594. s->irq = irq;
  595. s->it_shift = it_shift;
  596. s->dma_memory_read = dma_memory_read;
  597. s->dma_memory_write = dma_memory_write;
  598. s->dma_opaque = dma_opaque;
  599. esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
  600. cpu_register_physical_memory(espaddr, ESP_REGS << it_shift, esp_io_memory);
  601. esp_reset(s);
  602. register_savevm("esp", espaddr, 3, esp_save, esp_load, s);
  603. qemu_register_reset(esp_reset, s);
  604. *reset = *qemu_allocate_irqs(parent_esp_reset, s, 1);
  605. return s;
  606. }