|
|
1.1 ! root 1: /* ! 2: * Heathrow PIC support (standard PowerMac PIC) ! 3: * ! 4: * Copyright (c) 2005 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 "vl.h" ! 25: ! 26: //#define DEBUG ! 27: ! 28: typedef struct HeathrowPIC { ! 29: uint32_t events; ! 30: uint32_t mask; ! 31: uint32_t levels; ! 32: uint32_t level_triggered; ! 33: } HeathrowPIC; ! 34: ! 35: struct HeathrowPICS { ! 36: HeathrowPIC pics[2]; ! 37: }; ! 38: ! 39: static inline int check_irq(HeathrowPIC *pic) ! 40: { ! 41: return (pic->events | (pic->levels & pic->level_triggered)) & pic->mask; ! 42: } ! 43: ! 44: /* update the CPU irq state */ ! 45: static void heathrow_pic_update(HeathrowPICS *s) ! 46: { ! 47: if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) { ! 48: cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); ! 49: } else { ! 50: cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); ! 51: } ! 52: } ! 53: ! 54: static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) ! 55: { ! 56: HeathrowPICS *s = opaque; ! 57: HeathrowPIC *pic; ! 58: unsigned int n; ! 59: ! 60: value = bswap32(value); ! 61: #ifdef DEBUG ! 62: printf("pic_writel: %08x: %08x\n", ! 63: addr, value); ! 64: #endif ! 65: n = ((addr & 0xfff) - 0x10) >> 4; ! 66: if (n >= 2) ! 67: return; ! 68: pic = &s->pics[n]; ! 69: switch(addr & 0xf) { ! 70: case 0x04: ! 71: pic->mask = value; ! 72: heathrow_pic_update(s); ! 73: break; ! 74: case 0x08: ! 75: /* do not reset level triggered IRQs */ ! 76: value &= ~pic->level_triggered; ! 77: pic->events &= ~value; ! 78: heathrow_pic_update(s); ! 79: break; ! 80: default: ! 81: break; ! 82: } ! 83: } ! 84: ! 85: static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) ! 86: { ! 87: HeathrowPICS *s = opaque; ! 88: HeathrowPIC *pic; ! 89: unsigned int n; ! 90: uint32_t value; ! 91: ! 92: n = ((addr & 0xfff) - 0x10) >> 4; ! 93: if (n >= 2) { ! 94: value = 0; ! 95: } else { ! 96: pic = &s->pics[n]; ! 97: switch(addr & 0xf) { ! 98: case 0x0: ! 99: value = pic->events; ! 100: break; ! 101: case 0x4: ! 102: value = pic->mask; ! 103: break; ! 104: case 0xc: ! 105: value = pic->levels; ! 106: break; ! 107: default: ! 108: value = 0; ! 109: break; ! 110: } ! 111: } ! 112: #ifdef DEBUG ! 113: printf("pic_readl: %08x: %08x\n", ! 114: addr, value); ! 115: #endif ! 116: value = bswap32(value); ! 117: return value; ! 118: } ! 119: ! 120: static CPUWriteMemoryFunc *pic_write[] = { ! 121: &pic_writel, ! 122: &pic_writel, ! 123: &pic_writel, ! 124: }; ! 125: ! 126: static CPUReadMemoryFunc *pic_read[] = { ! 127: &pic_readl, ! 128: &pic_readl, ! 129: &pic_readl, ! 130: }; ! 131: ! 132: ! 133: void heathrow_pic_set_irq(void *opaque, int num, int level) ! 134: { ! 135: HeathrowPICS *s = opaque; ! 136: HeathrowPIC *pic; ! 137: unsigned int irq_bit; ! 138: ! 139: #if defined(DEBUG) ! 140: { ! 141: static int last_level[64]; ! 142: if (last_level[num] != level) { ! 143: printf("set_irq: num=0x%02x level=%d\n", num, level); ! 144: last_level[num] = level; ! 145: } ! 146: } ! 147: #endif ! 148: pic = &s->pics[1 - (num >> 5)]; ! 149: irq_bit = 1 << (num & 0x1f); ! 150: if (level) { ! 151: pic->events |= irq_bit & ~pic->level_triggered; ! 152: pic->levels |= irq_bit; ! 153: } else { ! 154: pic->levels &= ~irq_bit; ! 155: } ! 156: heathrow_pic_update(s); ! 157: } ! 158: ! 159: HeathrowPICS *heathrow_pic_init(int *pmem_index) ! 160: { ! 161: HeathrowPICS *s; ! 162: ! 163: s = qemu_mallocz(sizeof(HeathrowPICS)); ! 164: s->pics[0].level_triggered = 0; ! 165: s->pics[1].level_triggered = 0x1ff00000; ! 166: *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s); ! 167: return s; ! 168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.