2 * arch/ppc64/kernel/xics.c
4 * Copyright 2000 IBM Corporation.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/threads.h>
14 #include <linux/kernel.h>
15 #include <linux/irq.h>
16 #include <linux/smp.h>
17 #include <linux/interrupt.h>
18 #include <linux/signal.h>
21 #include <asm/pgtable.h>
26 #include <asm/ppcdebug.h>
27 #include <asm/hvcall.h>
28 #include <asm/machdep.h>
32 void xics_enable_irq(u_int irq);
33 void xics_disable_irq(u_int irq);
34 void xics_mask_and_ack_irq(u_int irq);
35 void xics_end_irq(u_int irq);
36 void xics_set_affinity(unsigned int irq_nr, unsigned long cpumask);
38 struct hw_interrupt_type xics_pic = {
44 xics_mask_and_ack_irq,
49 struct hw_interrupt_type xics_8259_pic = {
55 xics_mask_and_ack_irq,
60 #define XICS_IRQ_OFFSET 0x10
61 #define XICS_IRQ_SPURIOUS 0
63 /* Want a priority other than 0. Various HW issues require this. */
64 #define DEFAULT_PRIORITY 5
67 * Mark IPIs as higher priority so we can take them inside interrupts that
68 * arent marked SA_INTERRUPT
70 #define IPI_PRIORITY 4
88 static struct xics_ipl *xics_per_cpu[NR_CPUS];
90 static int xics_irq_8259_cascade = 0;
91 static int xics_irq_8259_cascade_real = 0;
92 static unsigned int default_server = 0xFF;
93 static unsigned int default_distrib_server = 0;
96 * XICS only has a single IPI, so encode the messages per CPU
98 struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
100 /* RTAS service tokens */
107 int (*xirr_info_get)(int cpu);
108 void (*xirr_info_set)(int cpu, int val);
109 void (*cppr_info)(int cpu, u8 val);
110 void (*qirr_info)(int cpu, u8 val);
116 static int pSeries_xirr_info_get(int n_cpu)
118 return xics_per_cpu[n_cpu]->xirr.word;
121 static void pSeries_xirr_info_set(int n_cpu, int value)
123 xics_per_cpu[n_cpu]->xirr.word = value;
126 static void pSeries_cppr_info(int n_cpu, u8 value)
128 xics_per_cpu[n_cpu]->xirr.bytes[0] = value;
131 static void pSeries_qirr_info(int n_cpu, u8 value)
133 xics_per_cpu[n_cpu]->qirr.bytes[0] = value;
136 static xics_ops pSeries_ops = {
137 pSeries_xirr_info_get,
138 pSeries_xirr_info_set,
143 static xics_ops *ops = &pSeries_ops;
148 static inline long plpar_eoi(unsigned long xirr)
150 return plpar_hcall_norets(H_EOI, xirr);
153 static inline long plpar_cppr(unsigned long cppr)
155 return plpar_hcall_norets(H_CPPR, cppr);
158 static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
160 return plpar_hcall_norets(H_IPI, servernum, mfrr);
163 static inline long plpar_xirr(unsigned long *xirr_ret)
166 return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
169 static int pSeriesLP_xirr_info_get(int n_cpu)
171 unsigned long lpar_rc;
172 unsigned long return_value;
174 lpar_rc = plpar_xirr(&return_value);
175 if (lpar_rc != H_Success)
176 panic(" bad return code xirr - rc = %lx \n", lpar_rc);
177 return (int)return_value;
180 static void pSeriesLP_xirr_info_set(int n_cpu, int value)
182 unsigned long lpar_rc;
183 unsigned long val64 = value & 0xffffffff;
185 lpar_rc = plpar_eoi(val64);
186 if (lpar_rc != H_Success)
187 panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
191 static void pSeriesLP_cppr_info(int n_cpu, u8 value)
193 unsigned long lpar_rc;
195 lpar_rc = plpar_cppr(value);
196 if (lpar_rc != H_Success)
197 panic("bad return code cppr - rc = %lx\n", lpar_rc);
200 static void pSeriesLP_qirr_info(int n_cpu , u8 value)
202 unsigned long lpar_rc;
204 lpar_rc = plpar_ipi(n_cpu, value);
205 if (lpar_rc != H_Success)
206 panic("bad return code qirr - rc = %lx\n", lpar_rc);
209 xics_ops pSeriesLP_ops = {
210 pSeriesLP_xirr_info_get,
211 pSeriesLP_xirr_info_set,
216 void xics_enable_irq(u_int virq)
222 virq -= XICS_IRQ_OFFSET;
223 irq = virt_irq_to_real(virq);
227 #ifdef CONFIG_IRQ_ALL_CPUS
228 if (smp_threads_ready)
229 server = default_distrib_server;
231 server = default_server;
233 server = default_server;
236 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
238 if (call_status != 0) {
239 printk("xics_enable_irq: irq=%x: ibm_set_xive returned %lx\n",
244 /* Now unmask the interrupt (often a no-op) */
245 call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
246 if (call_status != 0) {
247 printk("xics_enable_irq: irq=%x: ibm_int_on returned %lx\n",
253 void xics_disable_irq(u_int virq)
258 virq -= XICS_IRQ_OFFSET;
259 irq = virt_irq_to_real(virq);
263 call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
264 if (call_status != 0) {
265 printk("xics_disable_irq: irq=%x: ibm_int_off returned %lx\n",
271 void xics_end_irq(u_int irq)
273 int cpu = smp_processor_id();
276 ops->xirr_info_set(cpu, ((0xff<<24) |
277 (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
280 void xics_mask_and_ack_irq(u_int irq)
282 int cpu = smp_processor_id();
284 if (irq < XICS_IRQ_OFFSET) {
287 ops->xirr_info_set(cpu, ((0xff<<24) |
288 xics_irq_8259_cascade_real));
293 int xics_get_irq(struct pt_regs *regs)
295 u_int cpu = smp_processor_id();
299 vec = ops->xirr_info_get(cpu);
300 /* (vec >> 24) == old priority */
303 /* for sanity, this had better be < NR_IRQS - 16 */
304 if (vec == xics_irq_8259_cascade_real) {
305 irq = i8259_irq(cpu);
307 /* Spurious cascaded interrupt. Still must ack xics */
308 xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade);
311 } else if (vec == XICS_IRQ_SPURIOUS) {
314 irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET;
321 extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
323 irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
325 int cpu = smp_processor_id();
327 ops->qirr_info(cpu, 0xff);
328 while (xics_ipi_message[cpu].value) {
329 if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
330 &xics_ipi_message[cpu].value)) {
332 smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
334 if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
335 &xics_ipi_message[cpu].value)) {
337 smp_message_recv(PPC_MSG_RESCHEDULE, regs);
340 if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
341 &xics_ipi_message[cpu].value)) {
343 smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
347 if (test_and_clear_bit(PPC_MSG_XMON_BREAK,
348 &xics_ipi_message[cpu].value)) {
350 smp_message_recv(PPC_MSG_XMON_BREAK, regs);
357 void xics_cause_IPI(int cpu)
359 ops->qirr_info(cpu, IPI_PRIORITY);
362 void xics_setup_cpu(void)
364 int cpu = smp_processor_id();
366 ops->cppr_info(cpu, 0xff);
370 #endif /* CONFIG_SMP */
372 void xics_init_IRQ(void)
375 unsigned long intr_size = 0;
376 struct device_node *np;
377 uint *ireg, ilen, indx=0;
378 unsigned long intr_base = 0;
379 struct xics_interrupt_node {
380 unsigned long long addr;
381 unsigned long long size;
384 ppc64_boot_msg(0x20, "XICS Init");
386 ibm_get_xive = rtas_token("ibm,get-xive");
387 ibm_set_xive = rtas_token("ibm,set-xive");
388 ibm_int_on = rtas_token("ibm,int-on");
389 ibm_int_off = rtas_token("ibm,int-off");
391 np = find_type_devices("PowerPC-External-Interrupt-Presentation");
393 printk(KERN_WARNING "Can't find Interrupt Presentation\n");
394 udbg_printf("Can't find Interrupt Presentation\n");
398 ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", 0);
401 * set node starting index for this node
406 ireg = (uint *)get_property(np, "reg", &ilen);
408 printk(KERN_WARNING "Can't find Interrupt Reg Property\n");
409 udbg_printf("Can't find Interrupt Reg Property\n");
414 inodes[indx].addr = (unsigned long long)*ireg++ << 32;
415 ilen -= sizeof(uint);
416 inodes[indx].addr |= *ireg++;
417 ilen -= sizeof(uint);
418 inodes[indx].size = (unsigned long long)*ireg++ << 32;
419 ilen -= sizeof(uint);
420 inodes[indx].size |= *ireg++;
421 ilen -= sizeof(uint);
423 if (indx >= NR_CPUS) break;
427 if ((indx < NR_CPUS) && np) goto nextnode;
429 /* Find the server numbers for the boot cpu. */
430 for (np = find_type_devices("cpu"); np; np = np->next) {
431 ireg = (uint *)get_property(np, "reg", &ilen);
432 if (ireg && ireg[0] == smp_processor_id()) {
433 ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
434 i = ilen / sizeof(int);
436 default_server = ireg[0];
437 default_distrib_server = ireg[i-1]; /* take last element */
443 intr_base = inodes[0].addr;
444 intr_size = (ulong)inodes[0].size;
446 np = find_type_devices("interrupt-controller");
448 printk(KERN_WARNING "xics: no ISA Interrupt Controller\n");
449 xics_irq_8259_cascade_real = -1;
450 xics_irq_8259_cascade = -1;
452 ireg = (uint *) get_property(np, "interrupts", 0);
454 printk(KERN_WARNING "Can't find ISA Interrupts Property\n");
455 udbg_printf("Can't find ISA Interrupts Property\n");
458 xics_irq_8259_cascade_real = *ireg;
459 xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
462 if (systemcfg->platform == PLATFORM_PSERIES) {
464 for (i = 0; i < NR_CPUS; ++i) {
465 if (!cpu_possible(i))
467 xics_per_cpu[i] = __ioremap((ulong)inodes[i].addr,
468 (ulong)inodes[i].size,
472 xics_per_cpu[0] = __ioremap((ulong)intr_base, intr_size,
474 #endif /* CONFIG_SMP */
475 #ifdef CONFIG_PPC_PSERIES
476 /* actually iSeries does not use any of xics...but it has link dependencies
477 * for now, except this new one...
479 } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
480 ops = &pSeriesLP_ops;
484 xics_8259_pic.enable = i8259_pic.enable;
485 xics_8259_pic.disable = i8259_pic.disable;
486 for (i = 0; i < 16; ++i)
487 irq_desc[i].handler = &xics_8259_pic;
488 for (; i < NR_IRQS; ++i)
489 irq_desc[i].handler = &xics_pic;
491 ops->cppr_info(boot_cpuid, 0xff);
493 if (xics_irq_8259_cascade != -1) {
494 if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET,
495 no_action, 0, "8259 cascade", 0))
496 printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
501 real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] =
503 /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
504 request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, SA_INTERRUPT,
506 irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU;
508 ppc64_boot_msg(0x21, "XICS Done");
511 void xics_set_affinity(unsigned int virq, unsigned long cpumask)
513 irq_desc_t *desc = irq_desc + virq;
517 unsigned long xics_status[2];
518 unsigned long newmask;
520 virq -= XICS_IRQ_OFFSET;
521 irq = virt_irq_to_real(virq);
525 spin_lock_irqsave(&desc->lock, flags);
527 status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq);
530 printk("xics_set_affinity: irq=%d ibm,get-xive returns %ld\n",
535 /* For the moment only implement delivery to all cpus or one cpu */
536 if (cpumask == -1UL) {
537 newmask = default_distrib_server;
539 if (!(cpumask & cpu_online_map))
541 newmask = find_first_bit(&cpumask, 8*sizeof(unsigned long));
544 status = rtas_call(ibm_set_xive, 3, 1, NULL,
545 irq, newmask, xics_status[1]);
548 printk("xics_set_affinity irq=%d ibm,set-xive returns %ld\n",
554 spin_unlock_irqrestore(&desc->lock, flags);