|
|
1.1 ! root 1: /* ! 2: * ColdFire Interrupt Controller emulation. ! 3: * ! 4: * Copyright (c) 2007 CodeSourcery. ! 5: * ! 6: * This code is licenced under the GPL ! 7: */ ! 8: #include "hw.h" ! 9: #include "mcf.h" ! 10: ! 11: typedef struct { ! 12: uint64_t ipr; ! 13: uint64_t imr; ! 14: uint64_t ifr; ! 15: uint64_t enabled; ! 16: uint8_t icr[64]; ! 17: CPUState *env; ! 18: int active_vector; ! 19: } mcf_intc_state; ! 20: ! 21: static void mcf_intc_update(mcf_intc_state *s) ! 22: { ! 23: uint64_t active; ! 24: int i; ! 25: int best; ! 26: int best_level; ! 27: ! 28: active = (s->ipr | s->ifr) & s->enabled & ~s->imr; ! 29: best_level = 0; ! 30: best = 64; ! 31: if (active) { ! 32: for (i = 0; i < 64; i++) { ! 33: if ((active & 1) != 0 && s->icr[i] >= best_level) { ! 34: best_level = s->icr[i]; ! 35: best = i; ! 36: } ! 37: active >>= 1; ! 38: } ! 39: } ! 40: s->active_vector = ((best == 64) ? 24 : (best + 64)); ! 41: m68k_set_irq_level(s->env, best_level, s->active_vector); ! 42: } ! 43: ! 44: static uint32_t mcf_intc_read(void *opaque, target_phys_addr_t addr) ! 45: { ! 46: int offset; ! 47: mcf_intc_state *s = (mcf_intc_state *)opaque; ! 48: offset = addr & 0xff; ! 49: if (offset >= 0x40 && offset < 0x80) { ! 50: return s->icr[offset - 0x40]; ! 51: } ! 52: switch (offset) { ! 53: case 0x00: ! 54: return (uint32_t)(s->ipr >> 32); ! 55: case 0x04: ! 56: return (uint32_t)s->ipr; ! 57: case 0x08: ! 58: return (uint32_t)(s->imr >> 32); ! 59: case 0x0c: ! 60: return (uint32_t)s->imr; ! 61: case 0x10: ! 62: return (uint32_t)(s->ifr >> 32); ! 63: case 0x14: ! 64: return (uint32_t)s->ifr; ! 65: case 0xe0: /* SWIACK. */ ! 66: return s->active_vector; ! 67: case 0xe1: case 0xe2: case 0xe3: case 0xe4: ! 68: case 0xe5: case 0xe6: case 0xe7: ! 69: /* LnIACK */ ! 70: cpu_abort(cpu_single_env, "mcf_intc_read: LnIACK not implemented\n"); ! 71: default: ! 72: return 0; ! 73: } ! 74: } ! 75: ! 76: static void mcf_intc_write(void *opaque, target_phys_addr_t addr, uint32_t val) ! 77: { ! 78: int offset; ! 79: mcf_intc_state *s = (mcf_intc_state *)opaque; ! 80: offset = addr & 0xff; ! 81: if (offset >= 0x40 && offset < 0x80) { ! 82: int n = offset - 0x40; ! 83: s->icr[n] = val; ! 84: if (val == 0) ! 85: s->enabled &= ~(1ull << n); ! 86: else ! 87: s->enabled |= (1ull << n); ! 88: mcf_intc_update(s); ! 89: return; ! 90: } ! 91: switch (offset) { ! 92: case 0x00: case 0x04: ! 93: /* Ignore IPR writes. */ ! 94: return; ! 95: case 0x08: ! 96: s->imr = (s->imr & 0xffffffff) | ((uint64_t)val << 32); ! 97: break; ! 98: case 0x0c: ! 99: s->imr = (s->imr & 0xffffffff00000000ull) | (uint32_t)val; ! 100: break; ! 101: default: ! 102: cpu_abort(cpu_single_env, "mcf_intc_write: Bad write offset %d\n", ! 103: offset); ! 104: break; ! 105: } ! 106: mcf_intc_update(s); ! 107: } ! 108: ! 109: static void mcf_intc_set_irq(void *opaque, int irq, int level) ! 110: { ! 111: mcf_intc_state *s = (mcf_intc_state *)opaque; ! 112: if (irq >= 64) ! 113: return; ! 114: if (level) ! 115: s->ipr |= 1ull << irq; ! 116: else ! 117: s->ipr &= ~(1ull << irq); ! 118: mcf_intc_update(s); ! 119: } ! 120: ! 121: static void mcf_intc_reset(mcf_intc_state *s) ! 122: { ! 123: s->imr = ~0ull; ! 124: s->ipr = 0; ! 125: s->ifr = 0; ! 126: s->enabled = 0; ! 127: memset(s->icr, 0, 64); ! 128: s->active_vector = 24; ! 129: } ! 130: ! 131: static CPUReadMemoryFunc *mcf_intc_readfn[] = { ! 132: mcf_intc_read, ! 133: mcf_intc_read, ! 134: mcf_intc_read ! 135: }; ! 136: ! 137: static CPUWriteMemoryFunc *mcf_intc_writefn[] = { ! 138: mcf_intc_write, ! 139: mcf_intc_write, ! 140: mcf_intc_write ! 141: }; ! 142: ! 143: qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env) ! 144: { ! 145: mcf_intc_state *s; ! 146: int iomemtype; ! 147: ! 148: s = qemu_mallocz(sizeof(mcf_intc_state)); ! 149: s->env = env; ! 150: mcf_intc_reset(s); ! 151: ! 152: iomemtype = cpu_register_io_memory(0, mcf_intc_readfn, ! 153: mcf_intc_writefn, s); ! 154: cpu_register_physical_memory(base, 0x100, iomemtype); ! 155: ! 156: return qemu_allocate_irqs(mcf_intc_set_irq, s, 64); ! 157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.