i8259.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. /*
  2. * QEMU 8259 interrupt controller emulation
  3. *
  4. * Copyright (c) 2003-2004 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 "qemu/osdep.h"
  25. #include "hw/i386/pc.h"
  26. #include "hw/irq.h"
  27. #include "hw/isa/isa.h"
  28. #include "qemu/timer.h"
  29. #include "qemu/log.h"
  30. #include "hw/isa/i8259_internal.h"
  31. #include "trace.h"
  32. /* debug PIC */
  33. //#define DEBUG_PIC
  34. //#define DEBUG_IRQ_LATENCY
  35. #define TYPE_I8259 "isa-i8259"
  36. #define PIC_CLASS(class) OBJECT_CLASS_CHECK(PICClass, (class), TYPE_I8259)
  37. #define PIC_GET_CLASS(obj) OBJECT_GET_CLASS(PICClass, (obj), TYPE_I8259)
  38. /**
  39. * PICClass:
  40. * @parent_realize: The parent's realizefn.
  41. */
  42. typedef struct PICClass {
  43. PICCommonClass parent_class;
  44. DeviceRealize parent_realize;
  45. } PICClass;
  46. #ifdef DEBUG_IRQ_LATENCY
  47. static int64_t irq_time[16];
  48. #endif
  49. DeviceState *isa_pic;
  50. static PICCommonState *slave_pic;
  51. /* return the highest priority found in mask (highest = smallest
  52. number). Return 8 if no irq */
  53. static int get_priority(PICCommonState *s, int mask)
  54. {
  55. int priority;
  56. if (mask == 0) {
  57. return 8;
  58. }
  59. priority = 0;
  60. while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) {
  61. priority++;
  62. }
  63. return priority;
  64. }
  65. /* return the pic wanted interrupt. return -1 if none */
  66. static int pic_get_irq(PICCommonState *s)
  67. {
  68. int mask, cur_priority, priority;
  69. mask = s->irr & ~s->imr;
  70. priority = get_priority(s, mask);
  71. if (priority == 8) {
  72. return -1;
  73. }
  74. /* compute current priority. If special fully nested mode on the
  75. master, the IRQ coming from the slave is not taken into account
  76. for the priority computation. */
  77. mask = s->isr;
  78. if (s->special_mask) {
  79. mask &= ~s->imr;
  80. }
  81. if (s->special_fully_nested_mode && s->master) {
  82. mask &= ~(1 << 2);
  83. }
  84. cur_priority = get_priority(s, mask);
  85. if (priority < cur_priority) {
  86. /* higher priority found: an irq should be generated */
  87. return (priority + s->priority_add) & 7;
  88. } else {
  89. return -1;
  90. }
  91. }
  92. /* Update INT output. Must be called every time the output may have changed. */
  93. static void pic_update_irq(PICCommonState *s)
  94. {
  95. int irq;
  96. irq = pic_get_irq(s);
  97. if (irq >= 0) {
  98. trace_pic_update_irq(s->master, s->imr, s->irr, s->priority_add);
  99. qemu_irq_raise(s->int_out[0]);
  100. } else {
  101. qemu_irq_lower(s->int_out[0]);
  102. }
  103. }
  104. /* set irq level. If an edge is detected, then the IRR is set to 1 */
  105. static void pic_set_irq(void *opaque, int irq, int level)
  106. {
  107. PICCommonState *s = opaque;
  108. int mask = 1 << irq;
  109. int irq_index = s->master ? irq : irq + 8;
  110. trace_pic_set_irq(s->master, irq, level);
  111. pic_stat_update_irq(irq_index, level);
  112. #ifdef DEBUG_IRQ_LATENCY
  113. if (level) {
  114. irq_time[irq_index] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
  115. }
  116. #endif
  117. if (s->elcr & mask) {
  118. /* level triggered */
  119. if (level) {
  120. s->irr |= mask;
  121. s->last_irr |= mask;
  122. } else {
  123. s->irr &= ~mask;
  124. s->last_irr &= ~mask;
  125. }
  126. } else {
  127. /* edge triggered */
  128. if (level) {
  129. if ((s->last_irr & mask) == 0) {
  130. s->irr |= mask;
  131. }
  132. s->last_irr |= mask;
  133. } else {
  134. s->last_irr &= ~mask;
  135. }
  136. }
  137. pic_update_irq(s);
  138. }
  139. /* acknowledge interrupt 'irq' */
  140. static void pic_intack(PICCommonState *s, int irq)
  141. {
  142. if (s->auto_eoi) {
  143. if (s->rotate_on_auto_eoi) {
  144. s->priority_add = (irq + 1) & 7;
  145. }
  146. } else {
  147. s->isr |= (1 << irq);
  148. }
  149. /* We don't clear a level sensitive interrupt here */
  150. if (!(s->elcr & (1 << irq))) {
  151. s->irr &= ~(1 << irq);
  152. }
  153. pic_update_irq(s);
  154. }
  155. int pic_read_irq(DeviceState *d)
  156. {
  157. PICCommonState *s = PIC_COMMON(d);
  158. int irq, irq2, intno;
  159. irq = pic_get_irq(s);
  160. if (irq >= 0) {
  161. if (irq == 2) {
  162. irq2 = pic_get_irq(slave_pic);
  163. if (irq2 >= 0) {
  164. pic_intack(slave_pic, irq2);
  165. } else {
  166. /* spurious IRQ on slave controller */
  167. irq2 = 7;
  168. }
  169. intno = slave_pic->irq_base + irq2;
  170. } else {
  171. intno = s->irq_base + irq;
  172. }
  173. pic_intack(s, irq);
  174. } else {
  175. /* spurious IRQ on host controller */
  176. irq = 7;
  177. intno = s->irq_base + irq;
  178. }
  179. if (irq == 2) {
  180. irq = irq2 + 8;
  181. }
  182. #ifdef DEBUG_IRQ_LATENCY
  183. printf("IRQ%d latency=%0.3fus\n",
  184. irq,
  185. (double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
  186. irq_time[irq]) * 1000000.0 / NANOSECONDS_PER_SECOND);
  187. #endif
  188. trace_pic_interrupt(irq, intno);
  189. return intno;
  190. }
  191. static void pic_init_reset(PICCommonState *s)
  192. {
  193. pic_reset_common(s);
  194. pic_update_irq(s);
  195. }
  196. static void pic_reset(DeviceState *dev)
  197. {
  198. PICCommonState *s = PIC_COMMON(dev);
  199. s->elcr = 0;
  200. pic_init_reset(s);
  201. }
  202. static void pic_ioport_write(void *opaque, hwaddr addr64,
  203. uint64_t val64, unsigned size)
  204. {
  205. PICCommonState *s = opaque;
  206. uint32_t addr = addr64;
  207. uint32_t val = val64;
  208. int priority, cmd, irq;
  209. trace_pic_ioport_write(s->master, addr, val);
  210. if (addr == 0) {
  211. if (val & 0x10) {
  212. pic_init_reset(s);
  213. s->init_state = 1;
  214. s->init4 = val & 1;
  215. s->single_mode = val & 2;
  216. if (val & 0x08) {
  217. qemu_log_mask(LOG_UNIMP,
  218. "i8259: level sensitive irq not supported\n");
  219. }
  220. } else if (val & 0x08) {
  221. if (val & 0x04) {
  222. s->poll = 1;
  223. }
  224. if (val & 0x02) {
  225. s->read_reg_select = val & 1;
  226. }
  227. if (val & 0x40) {
  228. s->special_mask = (val >> 5) & 1;
  229. }
  230. } else {
  231. cmd = val >> 5;
  232. switch (cmd) {
  233. case 0:
  234. case 4:
  235. s->rotate_on_auto_eoi = cmd >> 2;
  236. break;
  237. case 1: /* end of interrupt */
  238. case 5:
  239. priority = get_priority(s, s->isr);
  240. if (priority != 8) {
  241. irq = (priority + s->priority_add) & 7;
  242. s->isr &= ~(1 << irq);
  243. if (cmd == 5) {
  244. s->priority_add = (irq + 1) & 7;
  245. }
  246. pic_update_irq(s);
  247. }
  248. break;
  249. case 3:
  250. irq = val & 7;
  251. s->isr &= ~(1 << irq);
  252. pic_update_irq(s);
  253. break;
  254. case 6:
  255. s->priority_add = (val + 1) & 7;
  256. pic_update_irq(s);
  257. break;
  258. case 7:
  259. irq = val & 7;
  260. s->isr &= ~(1 << irq);
  261. s->priority_add = (irq + 1) & 7;
  262. pic_update_irq(s);
  263. break;
  264. default:
  265. /* no operation */
  266. break;
  267. }
  268. }
  269. } else {
  270. switch (s->init_state) {
  271. case 0:
  272. /* normal mode */
  273. s->imr = val;
  274. pic_update_irq(s);
  275. break;
  276. case 1:
  277. s->irq_base = val & 0xf8;
  278. s->init_state = s->single_mode ? (s->init4 ? 3 : 0) : 2;
  279. break;
  280. case 2:
  281. if (s->init4) {
  282. s->init_state = 3;
  283. } else {
  284. s->init_state = 0;
  285. }
  286. break;
  287. case 3:
  288. s->special_fully_nested_mode = (val >> 4) & 1;
  289. s->auto_eoi = (val >> 1) & 1;
  290. s->init_state = 0;
  291. break;
  292. }
  293. }
  294. }
  295. static uint64_t pic_ioport_read(void *opaque, hwaddr addr,
  296. unsigned size)
  297. {
  298. PICCommonState *s = opaque;
  299. int ret;
  300. if (s->poll) {
  301. ret = pic_get_irq(s);
  302. if (ret >= 0) {
  303. pic_intack(s, ret);
  304. ret |= 0x80;
  305. } else {
  306. ret = 0;
  307. }
  308. s->poll = 0;
  309. } else {
  310. if (addr == 0) {
  311. if (s->read_reg_select) {
  312. ret = s->isr;
  313. } else {
  314. ret = s->irr;
  315. }
  316. } else {
  317. ret = s->imr;
  318. }
  319. }
  320. trace_pic_ioport_read(s->master, addr, ret);
  321. return ret;
  322. }
  323. int pic_get_output(DeviceState *d)
  324. {
  325. PICCommonState *s = PIC_COMMON(d);
  326. return (pic_get_irq(s) >= 0);
  327. }
  328. static void elcr_ioport_write(void *opaque, hwaddr addr,
  329. uint64_t val, unsigned size)
  330. {
  331. PICCommonState *s = opaque;
  332. s->elcr = val & s->elcr_mask;
  333. }
  334. static uint64_t elcr_ioport_read(void *opaque, hwaddr addr,
  335. unsigned size)
  336. {
  337. PICCommonState *s = opaque;
  338. return s->elcr;
  339. }
  340. static const MemoryRegionOps pic_base_ioport_ops = {
  341. .read = pic_ioport_read,
  342. .write = pic_ioport_write,
  343. .impl = {
  344. .min_access_size = 1,
  345. .max_access_size = 1,
  346. },
  347. };
  348. static const MemoryRegionOps pic_elcr_ioport_ops = {
  349. .read = elcr_ioport_read,
  350. .write = elcr_ioport_write,
  351. .impl = {
  352. .min_access_size = 1,
  353. .max_access_size = 1,
  354. },
  355. };
  356. static void pic_realize(DeviceState *dev, Error **errp)
  357. {
  358. PICCommonState *s = PIC_COMMON(dev);
  359. PICClass *pc = PIC_GET_CLASS(dev);
  360. memory_region_init_io(&s->base_io, OBJECT(s), &pic_base_ioport_ops, s,
  361. "pic", 2);
  362. memory_region_init_io(&s->elcr_io, OBJECT(s), &pic_elcr_ioport_ops, s,
  363. "elcr", 1);
  364. qdev_init_gpio_out(dev, s->int_out, ARRAY_SIZE(s->int_out));
  365. qdev_init_gpio_in(dev, pic_set_irq, 8);
  366. pc->parent_realize(dev, errp);
  367. }
  368. qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
  369. {
  370. qemu_irq *irq_set;
  371. DeviceState *dev;
  372. ISADevice *isadev;
  373. int i;
  374. irq_set = g_new0(qemu_irq, ISA_NUM_IRQS);
  375. isadev = i8259_init_chip(TYPE_I8259, bus, true);
  376. dev = DEVICE(isadev);
  377. qdev_connect_gpio_out(dev, 0, parent_irq);
  378. for (i = 0 ; i < 8; i++) {
  379. irq_set[i] = qdev_get_gpio_in(dev, i);
  380. }
  381. isa_pic = dev;
  382. isadev = i8259_init_chip(TYPE_I8259, bus, false);
  383. dev = DEVICE(isadev);
  384. qdev_connect_gpio_out(dev, 0, irq_set[2]);
  385. for (i = 0 ; i < 8; i++) {
  386. irq_set[i + 8] = qdev_get_gpio_in(dev, i);
  387. }
  388. slave_pic = PIC_COMMON(dev);
  389. return irq_set;
  390. }
  391. static void i8259_class_init(ObjectClass *klass, void *data)
  392. {
  393. PICClass *k = PIC_CLASS(klass);
  394. DeviceClass *dc = DEVICE_CLASS(klass);
  395. device_class_set_parent_realize(dc, pic_realize, &k->parent_realize);
  396. dc->reset = pic_reset;
  397. }
  398. static const TypeInfo i8259_info = {
  399. .name = TYPE_I8259,
  400. .instance_size = sizeof(PICCommonState),
  401. .parent = TYPE_PIC_COMMON,
  402. .class_init = i8259_class_init,
  403. .class_size = sizeof(PICClass),
  404. };
  405. static void pic_register_types(void)
  406. {
  407. type_register_static(&i8259_info);
  408. }
  409. type_init(pic_register_types)