xics.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. /*
  2. * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
  3. *
  4. * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
  5. *
  6. * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. *
  26. */
  27. #include "hw/hw.h"
  28. #include "trace.h"
  29. #include "qemu/timer.h"
  30. #include "hw/ppc/spapr.h"
  31. #include "hw/ppc/xics.h"
  32. #include "qemu/error-report.h"
  33. #include "qapi/visitor.h"
  34. static int get_cpu_index_by_dt_id(int cpu_dt_id)
  35. {
  36. PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
  37. if (cpu) {
  38. return cpu->parent_obj.cpu_index;
  39. }
  40. return -1;
  41. }
  42. void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
  43. {
  44. CPUState *cs = CPU(cpu);
  45. CPUPPCState *env = &cpu->env;
  46. ICPState *ss = &icp->ss[cs->cpu_index];
  47. XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
  48. assert(cs->cpu_index < icp->nr_servers);
  49. if (info->cpu_setup) {
  50. info->cpu_setup(icp, cpu);
  51. }
  52. switch (PPC_INPUT(env)) {
  53. case PPC_FLAGS_INPUT_POWER7:
  54. ss->output = env->irq_inputs[POWER7_INPUT_INT];
  55. break;
  56. case PPC_FLAGS_INPUT_970:
  57. ss->output = env->irq_inputs[PPC970_INPUT_INT];
  58. break;
  59. default:
  60. error_report("XICS interrupt controller does not support this CPU "
  61. "bus model");
  62. abort();
  63. }
  64. }
  65. /*
  66. * XICS Common class - parent for emulated XICS and KVM-XICS
  67. */
  68. static void xics_common_reset(DeviceState *d)
  69. {
  70. XICSState *icp = XICS_COMMON(d);
  71. int i;
  72. for (i = 0; i < icp->nr_servers; i++) {
  73. device_reset(DEVICE(&icp->ss[i]));
  74. }
  75. device_reset(DEVICE(icp->ics));
  76. }
  77. static void xics_prop_get_nr_irqs(Object *obj, Visitor *v,
  78. void *opaque, const char *name, Error **errp)
  79. {
  80. XICSState *icp = XICS_COMMON(obj);
  81. int64_t value = icp->nr_irqs;
  82. visit_type_int(v, &value, name, errp);
  83. }
  84. static void xics_prop_set_nr_irqs(Object *obj, Visitor *v,
  85. void *opaque, const char *name, Error **errp)
  86. {
  87. XICSState *icp = XICS_COMMON(obj);
  88. XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
  89. Error *error = NULL;
  90. int64_t value;
  91. visit_type_int(v, &value, name, &error);
  92. if (error) {
  93. error_propagate(errp, error);
  94. return;
  95. }
  96. if (icp->nr_irqs) {
  97. error_setg(errp, "Number of interrupts is already set to %u",
  98. icp->nr_irqs);
  99. return;
  100. }
  101. assert(info->set_nr_irqs);
  102. assert(icp->ics);
  103. info->set_nr_irqs(icp, value, errp);
  104. }
  105. static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
  106. void *opaque, const char *name,
  107. Error **errp)
  108. {
  109. XICSState *icp = XICS_COMMON(obj);
  110. int64_t value = icp->nr_servers;
  111. visit_type_int(v, &value, name, errp);
  112. }
  113. static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
  114. void *opaque, const char *name,
  115. Error **errp)
  116. {
  117. XICSState *icp = XICS_COMMON(obj);
  118. XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
  119. Error *error = NULL;
  120. int64_t value;
  121. visit_type_int(v, &value, name, &error);
  122. if (error) {
  123. error_propagate(errp, error);
  124. return;
  125. }
  126. if (icp->nr_servers) {
  127. error_setg(errp, "Number of servers is already set to %u",
  128. icp->nr_servers);
  129. return;
  130. }
  131. assert(info->set_nr_servers);
  132. info->set_nr_servers(icp, value, errp);
  133. }
  134. static void xics_common_initfn(Object *obj)
  135. {
  136. object_property_add(obj, "nr_irqs", "int",
  137. xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
  138. NULL, NULL, NULL);
  139. object_property_add(obj, "nr_servers", "int",
  140. xics_prop_get_nr_servers, xics_prop_set_nr_servers,
  141. NULL, NULL, NULL);
  142. }
  143. static void xics_common_class_init(ObjectClass *oc, void *data)
  144. {
  145. DeviceClass *dc = DEVICE_CLASS(oc);
  146. dc->reset = xics_common_reset;
  147. }
  148. static const TypeInfo xics_common_info = {
  149. .name = TYPE_XICS_COMMON,
  150. .parent = TYPE_SYS_BUS_DEVICE,
  151. .instance_size = sizeof(XICSState),
  152. .class_size = sizeof(XICSStateClass),
  153. .instance_init = xics_common_initfn,
  154. .class_init = xics_common_class_init,
  155. };
  156. /*
  157. * ICP: Presentation layer
  158. */
  159. #define XISR_MASK 0x00ffffff
  160. #define CPPR_MASK 0xff000000
  161. #define XISR(ss) (((ss)->xirr) & XISR_MASK)
  162. #define CPPR(ss) (((ss)->xirr) >> 24)
  163. static void ics_reject(ICSState *ics, int nr);
  164. static void ics_resend(ICSState *ics);
  165. static void ics_eoi(ICSState *ics, int nr);
  166. static void icp_check_ipi(XICSState *icp, int server)
  167. {
  168. ICPState *ss = icp->ss + server;
  169. if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
  170. return;
  171. }
  172. trace_xics_icp_check_ipi(server, ss->mfrr);
  173. if (XISR(ss)) {
  174. ics_reject(icp->ics, XISR(ss));
  175. }
  176. ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
  177. ss->pending_priority = ss->mfrr;
  178. qemu_irq_raise(ss->output);
  179. }
  180. static void icp_resend(XICSState *icp, int server)
  181. {
  182. ICPState *ss = icp->ss + server;
  183. if (ss->mfrr < CPPR(ss)) {
  184. icp_check_ipi(icp, server);
  185. }
  186. ics_resend(icp->ics);
  187. }
  188. static void icp_set_cppr(XICSState *icp, int server, uint8_t cppr)
  189. {
  190. ICPState *ss = icp->ss + server;
  191. uint8_t old_cppr;
  192. uint32_t old_xisr;
  193. old_cppr = CPPR(ss);
  194. ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
  195. if (cppr < old_cppr) {
  196. if (XISR(ss) && (cppr <= ss->pending_priority)) {
  197. old_xisr = XISR(ss);
  198. ss->xirr &= ~XISR_MASK; /* Clear XISR */
  199. ss->pending_priority = 0xff;
  200. qemu_irq_lower(ss->output);
  201. ics_reject(icp->ics, old_xisr);
  202. }
  203. } else {
  204. if (!XISR(ss)) {
  205. icp_resend(icp, server);
  206. }
  207. }
  208. }
  209. static void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr)
  210. {
  211. ICPState *ss = icp->ss + server;
  212. ss->mfrr = mfrr;
  213. if (mfrr < CPPR(ss)) {
  214. icp_check_ipi(icp, server);
  215. }
  216. }
  217. static uint32_t icp_accept(ICPState *ss)
  218. {
  219. uint32_t xirr = ss->xirr;
  220. qemu_irq_lower(ss->output);
  221. ss->xirr = ss->pending_priority << 24;
  222. ss->pending_priority = 0xff;
  223. trace_xics_icp_accept(xirr, ss->xirr);
  224. return xirr;
  225. }
  226. static void icp_eoi(XICSState *icp, int server, uint32_t xirr)
  227. {
  228. ICPState *ss = icp->ss + server;
  229. /* Send EOI -> ICS */
  230. ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
  231. trace_xics_icp_eoi(server, xirr, ss->xirr);
  232. ics_eoi(icp->ics, xirr & XISR_MASK);
  233. if (!XISR(ss)) {
  234. icp_resend(icp, server);
  235. }
  236. }
  237. static void icp_irq(XICSState *icp, int server, int nr, uint8_t priority)
  238. {
  239. ICPState *ss = icp->ss + server;
  240. trace_xics_icp_irq(server, nr, priority);
  241. if ((priority >= CPPR(ss))
  242. || (XISR(ss) && (ss->pending_priority <= priority))) {
  243. ics_reject(icp->ics, nr);
  244. } else {
  245. if (XISR(ss)) {
  246. ics_reject(icp->ics, XISR(ss));
  247. }
  248. ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
  249. ss->pending_priority = priority;
  250. trace_xics_icp_raise(ss->xirr, ss->pending_priority);
  251. qemu_irq_raise(ss->output);
  252. }
  253. }
  254. static void icp_dispatch_pre_save(void *opaque)
  255. {
  256. ICPState *ss = opaque;
  257. ICPStateClass *info = ICP_GET_CLASS(ss);
  258. if (info->pre_save) {
  259. info->pre_save(ss);
  260. }
  261. }
  262. static int icp_dispatch_post_load(void *opaque, int version_id)
  263. {
  264. ICPState *ss = opaque;
  265. ICPStateClass *info = ICP_GET_CLASS(ss);
  266. if (info->post_load) {
  267. return info->post_load(ss, version_id);
  268. }
  269. return 0;
  270. }
  271. static const VMStateDescription vmstate_icp_server = {
  272. .name = "icp/server",
  273. .version_id = 1,
  274. .minimum_version_id = 1,
  275. .pre_save = icp_dispatch_pre_save,
  276. .post_load = icp_dispatch_post_load,
  277. .fields = (VMStateField[]) {
  278. /* Sanity check */
  279. VMSTATE_UINT32(xirr, ICPState),
  280. VMSTATE_UINT8(pending_priority, ICPState),
  281. VMSTATE_UINT8(mfrr, ICPState),
  282. VMSTATE_END_OF_LIST()
  283. },
  284. };
  285. static void icp_reset(DeviceState *dev)
  286. {
  287. ICPState *icp = ICP(dev);
  288. icp->xirr = 0;
  289. icp->pending_priority = 0xff;
  290. icp->mfrr = 0xff;
  291. /* Make all outputs are deasserted */
  292. qemu_set_irq(icp->output, 0);
  293. }
  294. static void icp_class_init(ObjectClass *klass, void *data)
  295. {
  296. DeviceClass *dc = DEVICE_CLASS(klass);
  297. dc->reset = icp_reset;
  298. dc->vmsd = &vmstate_icp_server;
  299. }
  300. static const TypeInfo icp_info = {
  301. .name = TYPE_ICP,
  302. .parent = TYPE_DEVICE,
  303. .instance_size = sizeof(ICPState),
  304. .class_init = icp_class_init,
  305. .class_size = sizeof(ICPStateClass),
  306. };
  307. /*
  308. * ICS: Source layer
  309. */
  310. static int ics_valid_irq(ICSState *ics, uint32_t nr)
  311. {
  312. return (nr >= ics->offset)
  313. && (nr < (ics->offset + ics->nr_irqs));
  314. }
  315. static void resend_msi(ICSState *ics, int srcno)
  316. {
  317. ICSIRQState *irq = ics->irqs + srcno;
  318. /* FIXME: filter by server#? */
  319. if (irq->status & XICS_STATUS_REJECTED) {
  320. irq->status &= ~XICS_STATUS_REJECTED;
  321. if (irq->priority != 0xff) {
  322. icp_irq(ics->icp, irq->server, srcno + ics->offset,
  323. irq->priority);
  324. }
  325. }
  326. }
  327. static void resend_lsi(ICSState *ics, int srcno)
  328. {
  329. ICSIRQState *irq = ics->irqs + srcno;
  330. if ((irq->priority != 0xff)
  331. && (irq->status & XICS_STATUS_ASSERTED)
  332. && !(irq->status & XICS_STATUS_SENT)) {
  333. irq->status |= XICS_STATUS_SENT;
  334. icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
  335. }
  336. }
  337. static void set_irq_msi(ICSState *ics, int srcno, int val)
  338. {
  339. ICSIRQState *irq = ics->irqs + srcno;
  340. trace_xics_set_irq_msi(srcno, srcno + ics->offset);
  341. if (val) {
  342. if (irq->priority == 0xff) {
  343. irq->status |= XICS_STATUS_MASKED_PENDING;
  344. trace_xics_masked_pending();
  345. } else {
  346. icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
  347. }
  348. }
  349. }
  350. static void set_irq_lsi(ICSState *ics, int srcno, int val)
  351. {
  352. ICSIRQState *irq = ics->irqs + srcno;
  353. trace_xics_set_irq_lsi(srcno, srcno + ics->offset);
  354. if (val) {
  355. irq->status |= XICS_STATUS_ASSERTED;
  356. } else {
  357. irq->status &= ~XICS_STATUS_ASSERTED;
  358. }
  359. resend_lsi(ics, srcno);
  360. }
  361. static void ics_set_irq(void *opaque, int srcno, int val)
  362. {
  363. ICSState *ics = (ICSState *)opaque;
  364. if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
  365. set_irq_lsi(ics, srcno, val);
  366. } else {
  367. set_irq_msi(ics, srcno, val);
  368. }
  369. }
  370. static void write_xive_msi(ICSState *ics, int srcno)
  371. {
  372. ICSIRQState *irq = ics->irqs + srcno;
  373. if (!(irq->status & XICS_STATUS_MASKED_PENDING)
  374. || (irq->priority == 0xff)) {
  375. return;
  376. }
  377. irq->status &= ~XICS_STATUS_MASKED_PENDING;
  378. icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
  379. }
  380. static void write_xive_lsi(ICSState *ics, int srcno)
  381. {
  382. resend_lsi(ics, srcno);
  383. }
  384. static void ics_write_xive(ICSState *ics, int nr, int server,
  385. uint8_t priority, uint8_t saved_priority)
  386. {
  387. int srcno = nr - ics->offset;
  388. ICSIRQState *irq = ics->irqs + srcno;
  389. irq->server = server;
  390. irq->priority = priority;
  391. irq->saved_priority = saved_priority;
  392. trace_xics_ics_write_xive(nr, srcno, server, priority);
  393. if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
  394. write_xive_lsi(ics, srcno);
  395. } else {
  396. write_xive_msi(ics, srcno);
  397. }
  398. }
  399. static void ics_reject(ICSState *ics, int nr)
  400. {
  401. ICSIRQState *irq = ics->irqs + nr - ics->offset;
  402. trace_xics_ics_reject(nr, nr - ics->offset);
  403. irq->status |= XICS_STATUS_REJECTED; /* Irrelevant but harmless for LSI */
  404. irq->status &= ~XICS_STATUS_SENT; /* Irrelevant but harmless for MSI */
  405. }
  406. static void ics_resend(ICSState *ics)
  407. {
  408. int i;
  409. for (i = 0; i < ics->nr_irqs; i++) {
  410. /* FIXME: filter by server#? */
  411. if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
  412. resend_lsi(ics, i);
  413. } else {
  414. resend_msi(ics, i);
  415. }
  416. }
  417. }
  418. static void ics_eoi(ICSState *ics, int nr)
  419. {
  420. int srcno = nr - ics->offset;
  421. ICSIRQState *irq = ics->irqs + srcno;
  422. trace_xics_ics_eoi(nr);
  423. if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
  424. irq->status &= ~XICS_STATUS_SENT;
  425. }
  426. }
  427. static void ics_reset(DeviceState *dev)
  428. {
  429. ICSState *ics = ICS(dev);
  430. int i;
  431. uint8_t flags[ics->nr_irqs];
  432. for (i = 0; i < ics->nr_irqs; i++) {
  433. flags[i] = ics->irqs[i].flags;
  434. }
  435. memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
  436. for (i = 0; i < ics->nr_irqs; i++) {
  437. ics->irqs[i].priority = 0xff;
  438. ics->irqs[i].saved_priority = 0xff;
  439. ics->irqs[i].flags = flags[i];
  440. }
  441. }
  442. static int ics_post_load(ICSState *ics, int version_id)
  443. {
  444. int i;
  445. for (i = 0; i < ics->icp->nr_servers; i++) {
  446. icp_resend(ics->icp, i);
  447. }
  448. return 0;
  449. }
  450. static void ics_dispatch_pre_save(void *opaque)
  451. {
  452. ICSState *ics = opaque;
  453. ICSStateClass *info = ICS_GET_CLASS(ics);
  454. if (info->pre_save) {
  455. info->pre_save(ics);
  456. }
  457. }
  458. static int ics_dispatch_post_load(void *opaque, int version_id)
  459. {
  460. ICSState *ics = opaque;
  461. ICSStateClass *info = ICS_GET_CLASS(ics);
  462. if (info->post_load) {
  463. return info->post_load(ics, version_id);
  464. }
  465. return 0;
  466. }
  467. static const VMStateDescription vmstate_ics_irq = {
  468. .name = "ics/irq",
  469. .version_id = 2,
  470. .minimum_version_id = 1,
  471. .fields = (VMStateField[]) {
  472. VMSTATE_UINT32(server, ICSIRQState),
  473. VMSTATE_UINT8(priority, ICSIRQState),
  474. VMSTATE_UINT8(saved_priority, ICSIRQState),
  475. VMSTATE_UINT8(status, ICSIRQState),
  476. VMSTATE_UINT8(flags, ICSIRQState),
  477. VMSTATE_END_OF_LIST()
  478. },
  479. };
  480. static const VMStateDescription vmstate_ics = {
  481. .name = "ics",
  482. .version_id = 1,
  483. .minimum_version_id = 1,
  484. .pre_save = ics_dispatch_pre_save,
  485. .post_load = ics_dispatch_post_load,
  486. .fields = (VMStateField[]) {
  487. /* Sanity check */
  488. VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
  489. VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
  490. vmstate_ics_irq, ICSIRQState),
  491. VMSTATE_END_OF_LIST()
  492. },
  493. };
  494. static void ics_initfn(Object *obj)
  495. {
  496. ICSState *ics = ICS(obj);
  497. ics->offset = XICS_IRQ_BASE;
  498. }
  499. static void ics_realize(DeviceState *dev, Error **errp)
  500. {
  501. ICSState *ics = ICS(dev);
  502. if (!ics->nr_irqs) {
  503. error_setg(errp, "Number of interrupts needs to be greater 0");
  504. return;
  505. }
  506. ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
  507. ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
  508. }
  509. static void ics_class_init(ObjectClass *klass, void *data)
  510. {
  511. DeviceClass *dc = DEVICE_CLASS(klass);
  512. ICSStateClass *isc = ICS_CLASS(klass);
  513. dc->realize = ics_realize;
  514. dc->vmsd = &vmstate_ics;
  515. dc->reset = ics_reset;
  516. isc->post_load = ics_post_load;
  517. }
  518. static const TypeInfo ics_info = {
  519. .name = TYPE_ICS,
  520. .parent = TYPE_DEVICE,
  521. .instance_size = sizeof(ICSState),
  522. .class_init = ics_class_init,
  523. .class_size = sizeof(ICSStateClass),
  524. .instance_init = ics_initfn,
  525. };
  526. /*
  527. * Exported functions
  528. */
  529. static int xics_find_source(XICSState *icp, int irq)
  530. {
  531. int sources = 1;
  532. int src;
  533. /* FIXME: implement multiple sources */
  534. for (src = 0; src < sources; ++src) {
  535. ICSState *ics = &icp->ics[src];
  536. if (ics_valid_irq(ics, irq)) {
  537. return src;
  538. }
  539. }
  540. return -1;
  541. }
  542. qemu_irq xics_get_qirq(XICSState *icp, int irq)
  543. {
  544. int src = xics_find_source(icp, irq);
  545. if (src >= 0) {
  546. ICSState *ics = &icp->ics[src];
  547. return ics->qirqs[irq - ics->offset];
  548. }
  549. return NULL;
  550. }
  551. static void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
  552. {
  553. assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
  554. ics->irqs[srcno].flags |=
  555. lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
  556. }
  557. void xics_set_irq_type(XICSState *icp, int irq, bool lsi)
  558. {
  559. int src = xics_find_source(icp, irq);
  560. ICSState *ics;
  561. assert(src >= 0);
  562. ics = &icp->ics[src];
  563. ics_set_irq_type(ics, irq - ics->offset, lsi);
  564. }
  565. #define ICS_IRQ_FREE(ics, srcno) \
  566. (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
  567. static int ics_find_free_block(ICSState *ics, int num, int alignnum)
  568. {
  569. int first, i;
  570. for (first = 0; first < ics->nr_irqs; first += alignnum) {
  571. if (num > (ics->nr_irqs - first)) {
  572. return -1;
  573. }
  574. for (i = first; i < first + num; ++i) {
  575. if (!ICS_IRQ_FREE(ics, i)) {
  576. break;
  577. }
  578. }
  579. if (i == (first + num)) {
  580. return first;
  581. }
  582. }
  583. return -1;
  584. }
  585. int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
  586. {
  587. ICSState *ics = &icp->ics[src];
  588. int irq;
  589. if (irq_hint) {
  590. assert(src == xics_find_source(icp, irq_hint));
  591. if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
  592. trace_xics_alloc_failed_hint(src, irq_hint);
  593. return -1;
  594. }
  595. irq = irq_hint;
  596. } else {
  597. irq = ics_find_free_block(ics, 1, 1);
  598. if (irq < 0) {
  599. trace_xics_alloc_failed_no_left(src);
  600. return -1;
  601. }
  602. irq += ics->offset;
  603. }
  604. ics_set_irq_type(ics, irq - ics->offset, lsi);
  605. trace_xics_alloc(src, irq);
  606. return irq;
  607. }
  608. /*
  609. * Allocate block of consequtive IRQs, returns a number of the first.
  610. * If align==true, aligns the first IRQ number to num.
  611. */
  612. int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align)
  613. {
  614. int i, first = -1;
  615. ICSState *ics = &icp->ics[src];
  616. assert(src == 0);
  617. /*
  618. * MSIMesage::data is used for storing VIRQ so
  619. * it has to be aligned to num to support multiple
  620. * MSI vectors. MSI-X is not affected by this.
  621. * The hint is used for the first IRQ, the rest should
  622. * be allocated continuously.
  623. */
  624. if (align) {
  625. assert((num == 1) || (num == 2) || (num == 4) ||
  626. (num == 8) || (num == 16) || (num == 32));
  627. first = ics_find_free_block(ics, num, num);
  628. } else {
  629. first = ics_find_free_block(ics, num, 1);
  630. }
  631. if (first >= 0) {
  632. for (i = first; i < first + num; ++i) {
  633. ics_set_irq_type(ics, i, lsi);
  634. }
  635. }
  636. first += ics->offset;
  637. trace_xics_alloc_block(src, first, num, lsi, align);
  638. return first;
  639. }
  640. static void ics_free(ICSState *ics, int srcno, int num)
  641. {
  642. int i;
  643. for (i = srcno; i < srcno + num; ++i) {
  644. if (ICS_IRQ_FREE(ics, i)) {
  645. trace_xics_ics_free_warn(ics - ics->icp->ics, i + ics->offset);
  646. }
  647. memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
  648. }
  649. }
  650. void xics_free(XICSState *icp, int irq, int num)
  651. {
  652. int src = xics_find_source(icp, irq);
  653. if (src >= 0) {
  654. ICSState *ics = &icp->ics[src];
  655. /* FIXME: implement multiple sources */
  656. assert(src == 0);
  657. trace_xics_ics_free(ics - icp->ics, irq, num);
  658. ics_free(ics, irq - ics->offset, num);
  659. }
  660. }
  661. /*
  662. * Guest interfaces
  663. */
  664. static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  665. target_ulong opcode, target_ulong *args)
  666. {
  667. CPUState *cs = CPU(cpu);
  668. target_ulong cppr = args[0];
  669. icp_set_cppr(spapr->icp, cs->cpu_index, cppr);
  670. return H_SUCCESS;
  671. }
  672. static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  673. target_ulong opcode, target_ulong *args)
  674. {
  675. target_ulong server = get_cpu_index_by_dt_id(args[0]);
  676. target_ulong mfrr = args[1];
  677. if (server >= spapr->icp->nr_servers) {
  678. return H_PARAMETER;
  679. }
  680. icp_set_mfrr(spapr->icp, server, mfrr);
  681. return H_SUCCESS;
  682. }
  683. static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  684. target_ulong opcode, target_ulong *args)
  685. {
  686. CPUState *cs = CPU(cpu);
  687. uint32_t xirr = icp_accept(spapr->icp->ss + cs->cpu_index);
  688. args[0] = xirr;
  689. return H_SUCCESS;
  690. }
  691. static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  692. target_ulong opcode, target_ulong *args)
  693. {
  694. CPUState *cs = CPU(cpu);
  695. ICPState *ss = &spapr->icp->ss[cs->cpu_index];
  696. uint32_t xirr = icp_accept(ss);
  697. args[0] = xirr;
  698. args[1] = cpu_get_real_ticks();
  699. return H_SUCCESS;
  700. }
  701. static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  702. target_ulong opcode, target_ulong *args)
  703. {
  704. CPUState *cs = CPU(cpu);
  705. target_ulong xirr = args[0];
  706. icp_eoi(spapr->icp, cs->cpu_index, xirr);
  707. return H_SUCCESS;
  708. }
  709. static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  710. target_ulong opcode, target_ulong *args)
  711. {
  712. CPUState *cs = CPU(cpu);
  713. ICPState *ss = &spapr->icp->ss[cs->cpu_index];
  714. args[0] = ss->xirr;
  715. args[1] = ss->mfrr;
  716. return H_SUCCESS;
  717. }
  718. static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  719. uint32_t token,
  720. uint32_t nargs, target_ulong args,
  721. uint32_t nret, target_ulong rets)
  722. {
  723. ICSState *ics = spapr->icp->ics;
  724. uint32_t nr, server, priority;
  725. if ((nargs != 3) || (nret != 1)) {
  726. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  727. return;
  728. }
  729. nr = rtas_ld(args, 0);
  730. server = get_cpu_index_by_dt_id(rtas_ld(args, 1));
  731. priority = rtas_ld(args, 2);
  732. if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
  733. || (priority > 0xff)) {
  734. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  735. return;
  736. }
  737. ics_write_xive(ics, nr, server, priority, priority);
  738. rtas_st(rets, 0, RTAS_OUT_SUCCESS);
  739. }
  740. static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  741. uint32_t token,
  742. uint32_t nargs, target_ulong args,
  743. uint32_t nret, target_ulong rets)
  744. {
  745. ICSState *ics = spapr->icp->ics;
  746. uint32_t nr;
  747. if ((nargs != 1) || (nret != 3)) {
  748. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  749. return;
  750. }
  751. nr = rtas_ld(args, 0);
  752. if (!ics_valid_irq(ics, nr)) {
  753. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  754. return;
  755. }
  756. rtas_st(rets, 0, RTAS_OUT_SUCCESS);
  757. rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
  758. rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
  759. }
  760. static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  761. uint32_t token,
  762. uint32_t nargs, target_ulong args,
  763. uint32_t nret, target_ulong rets)
  764. {
  765. ICSState *ics = spapr->icp->ics;
  766. uint32_t nr;
  767. if ((nargs != 1) || (nret != 1)) {
  768. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  769. return;
  770. }
  771. nr = rtas_ld(args, 0);
  772. if (!ics_valid_irq(ics, nr)) {
  773. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  774. return;
  775. }
  776. ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
  777. ics->irqs[nr - ics->offset].priority);
  778. rtas_st(rets, 0, RTAS_OUT_SUCCESS);
  779. }
  780. static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  781. uint32_t token,
  782. uint32_t nargs, target_ulong args,
  783. uint32_t nret, target_ulong rets)
  784. {
  785. ICSState *ics = spapr->icp->ics;
  786. uint32_t nr;
  787. if ((nargs != 1) || (nret != 1)) {
  788. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  789. return;
  790. }
  791. nr = rtas_ld(args, 0);
  792. if (!ics_valid_irq(ics, nr)) {
  793. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  794. return;
  795. }
  796. ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
  797. ics->irqs[nr - ics->offset].saved_priority,
  798. ics->irqs[nr - ics->offset].saved_priority);
  799. rtas_st(rets, 0, RTAS_OUT_SUCCESS);
  800. }
  801. /*
  802. * XICS
  803. */
  804. static void xics_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
  805. {
  806. icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
  807. }
  808. static void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers,
  809. Error **errp)
  810. {
  811. int i;
  812. icp->nr_servers = nr_servers;
  813. icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
  814. for (i = 0; i < icp->nr_servers; i++) {
  815. char buffer[32];
  816. object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
  817. snprintf(buffer, sizeof(buffer), "icp[%d]", i);
  818. object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
  819. errp);
  820. }
  821. }
  822. static void xics_realize(DeviceState *dev, Error **errp)
  823. {
  824. XICSState *icp = XICS(dev);
  825. Error *error = NULL;
  826. int i;
  827. if (!icp->nr_servers) {
  828. error_setg(errp, "Number of servers needs to be greater 0");
  829. return;
  830. }
  831. /* Registration of global state belongs into realize */
  832. spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
  833. spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
  834. spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
  835. spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_int_on);
  836. spapr_register_hypercall(H_CPPR, h_cppr);
  837. spapr_register_hypercall(H_IPI, h_ipi);
  838. spapr_register_hypercall(H_XIRR, h_xirr);
  839. spapr_register_hypercall(H_XIRR_X, h_xirr_x);
  840. spapr_register_hypercall(H_EOI, h_eoi);
  841. spapr_register_hypercall(H_IPOLL, h_ipoll);
  842. object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
  843. if (error) {
  844. error_propagate(errp, error);
  845. return;
  846. }
  847. for (i = 0; i < icp->nr_servers; i++) {
  848. object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
  849. if (error) {
  850. error_propagate(errp, error);
  851. return;
  852. }
  853. }
  854. }
  855. static void xics_initfn(Object *obj)
  856. {
  857. XICSState *xics = XICS(obj);
  858. xics->ics = ICS(object_new(TYPE_ICS));
  859. object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
  860. xics->ics->icp = xics;
  861. }
  862. static void xics_class_init(ObjectClass *oc, void *data)
  863. {
  864. DeviceClass *dc = DEVICE_CLASS(oc);
  865. XICSStateClass *xsc = XICS_CLASS(oc);
  866. dc->realize = xics_realize;
  867. xsc->set_nr_irqs = xics_set_nr_irqs;
  868. xsc->set_nr_servers = xics_set_nr_servers;
  869. }
  870. static const TypeInfo xics_info = {
  871. .name = TYPE_XICS,
  872. .parent = TYPE_XICS_COMMON,
  873. .instance_size = sizeof(XICSState),
  874. .class_size = sizeof(XICSStateClass),
  875. .class_init = xics_class_init,
  876. .instance_init = xics_initfn,
  877. };
  878. static void xics_register_types(void)
  879. {
  880. type_register_static(&xics_common_info);
  881. type_register_static(&xics_info);
  882. type_register_static(&ics_info);
  883. type_register_static(&icp_info);
  884. }
  885. type_init(xics_register_types)