Rev 3665 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3665 | Rev 4638 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | /* |
1 | /* |
| 2 | * Copyright (c) 2005 Jakub Jermar |
2 | * Copyright (c) 2005 Jakub Jermar |
| - | 3 | * Copyright (c) 2009 Pavel Rimsky |
|
| 3 | * All rights reserved. |
4 | * All rights reserved. |
| 4 | * |
5 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
6 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
7 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
8 | * are met: |
| Line 31... | Line 32... | ||
| 31 | */ |
32 | */ |
| 32 | /** @file |
33 | /** @file |
| 33 | */ |
34 | */ |
| 34 | 35 | ||
| 35 | #include <arch/interrupt.h> |
36 | #include <arch/interrupt.h> |
| 36 | #include <arch/sparc64.h> |
- | |
| 37 | #include <arch/trap/interrupt.h> |
37 | #include <arch/trap/interrupt.h> |
| - | 38 | #include <arch/sparc64.h> |
|
| 38 | #include <interrupt.h> |
39 | #include <interrupt.h> |
| 39 | #include <ddi/irq.h> |
40 | #include <ddi/irq.h> |
| 40 | #include <arch/types.h> |
41 | #include <arch/types.h> |
| 41 | #include <debug.h> |
42 | #include <debug.h> |
| 42 | #include <arch/asm.h> |
43 | #include <arch/asm.h> |
| Line 57... | Line 58... | ||
| 57 | { |
58 | { |
| 58 | ASSERT(n >= IVT_FIRST && n <= IVT_ITEMS); |
59 | ASSERT(n >= IVT_FIRST && n <= IVT_ITEMS); |
| 59 | 60 | ||
| 60 | exc_register(n - 1, name, f); |
61 | exc_register(n - 1, name, f); |
| 61 | } |
62 | } |
| 62 | - | ||
| 63 | /** Process hardware interrupt. |
- | |
| 64 | * |
- | |
| 65 | * @param n Ignored. |
- | |
| 66 | * @param istate Ignored. |
- | |
| 67 | */ |
- | |
| 68 | void interrupt(int n, istate_t *istate) |
- | |
| 69 | { |
- | |
| 70 | uint64_t status; |
- | |
| 71 | uint64_t intrcv; |
- | |
| 72 | uint64_t data0; |
- | |
| 73 | status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); |
- | |
| 74 | if (status & (!INTR_DISPATCH_STATUS_BUSY)) |
- | |
| 75 | panic("Interrupt Dispatch Status busy bit not set\n"); |
- | |
| 76 | - | ||
| 77 | intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0); |
- | |
| 78 | #if defined (US) |
- | |
| 79 | data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0); |
- | |
| 80 | #elif defined (US3) |
- | |
| 81 | data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0); |
- | |
| 82 | #endif |
- | |
| 83 | - | ||
| 84 | irq_t *irq = irq_dispatch_and_lock(data0); |
- | |
| 85 | if (irq) { |
- | |
| 86 | /* |
- | |
| 87 | * The IRQ handler was found. |
- | |
| 88 | */ |
- | |
| 89 | irq->handler(irq, irq->arg); |
- | |
| 90 | /* |
- | |
| 91 | * See if there is a clear-interrupt-routine and call it. |
- | |
| 92 | */ |
- | |
| 93 | if (irq->cir) { |
- | |
| 94 | irq->cir(irq->cir_arg, irq->inr); |
- | |
| 95 | } |
- | |
| 96 | spinlock_unlock(&irq->lock); |
- | |
| 97 | } else if (data0 > config.base) { |
- | |
| 98 | /* |
- | |
| 99 | * This is a cross-call. |
- | |
| 100 | * data0 contains address of the kernel function. |
- | |
| 101 | * We call the function only after we verify |
- | |
| 102 | * it is one of the supported ones. |
- | |
| 103 | */ |
- | |
| 104 | #ifdef CONFIG_SMP |
- | |
| 105 | if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) { |
- | |
| 106 | tlb_shootdown_ipi_recv(); |
- | |
| 107 | } |
- | |
| 108 | #endif |
- | |
| 109 | } else { |
- | |
| 110 | /* |
- | |
| 111 | * Spurious interrupt. |
- | |
| 112 | */ |
- | |
| 113 | #ifdef CONFIG_DEBUG |
- | |
| 114 | printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64 |
- | |
| 115 | ", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0); |
- | |
| 116 | #endif |
- | |
| 117 | } |
- | |
| 118 | - | ||
| 119 | membar(); |
- | |
| 120 | asi_u64_write(ASI_INTR_RECEIVE, 0, 0); |
- | |
| 121 | } |
- | |
| 122 | - | ||
| 123 | /** @} |
63 | /** @} |
| 124 | */ |
64 | */ |