i8259.c 12 KB

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