|
|
1.1 root 1: /* 1.1.1.3 ! root 2: * Heathrow PIC support (OldWorld PowerMac) ! 3: * ! 4: * Copyright (c) 2005-2007 Fabrice Bellard ! 5: * Copyright (c) 2007 Jocelyn Mayer ! 6: * 1.1 root 7: * Permission is hereby granted, free of charge, to any person obtaining a copy 8: * of this software and associated documentation files (the "Software"), to deal 9: * in the Software without restriction, including without limitation the rights 10: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11: * copies of the Software, and to permit persons to whom the Software is 12: * furnished to do so, subject to the following conditions: 13: * 14: * The above copyright notice and this permission notice shall be included in 15: * all copies or substantial portions of the Software. 16: * 17: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23: * THE SOFTWARE. 24: */ 1.1.1.3 ! root 25: #include "hw.h" ! 26: #include "ppc_mac.h" 1.1 root 27: 28: //#define DEBUG 29: 30: typedef struct HeathrowPIC { 31: uint32_t events; 32: uint32_t mask; 33: uint32_t levels; 34: uint32_t level_triggered; 35: } HeathrowPIC; 36: 1.1.1.3 ! root 37: typedef struct HeathrowPICS { 1.1 root 38: HeathrowPIC pics[2]; 1.1.1.3 ! root 39: qemu_irq *irqs; ! 40: } HeathrowPICS; 1.1 root 41: 42: static inline int check_irq(HeathrowPIC *pic) 43: { 44: return (pic->events | (pic->levels & pic->level_triggered)) & pic->mask; 45: } 46: 47: /* update the CPU irq state */ 48: static void heathrow_pic_update(HeathrowPICS *s) 49: { 50: if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) { 1.1.1.3 ! root 51: qemu_irq_raise(s->irqs[0]); 1.1 root 52: } else { 1.1.1.3 ! root 53: qemu_irq_lower(s->irqs[0]); 1.1 root 54: } 55: } 56: 57: static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) 58: { 59: HeathrowPICS *s = opaque; 60: HeathrowPIC *pic; 61: unsigned int n; 62: 1.1.1.3 ! root 63: #ifdef TARGET_WORDS_BIGENDIAN 1.1 root 64: value = bswap32(value); 65: #endif 66: n = ((addr & 0xfff) - 0x10) >> 4; 1.1.1.3 ! root 67: #ifdef DEBUG ! 68: printf("pic_writel: " PADDRX " %u: %08x\n", addr, n, value); ! 69: #endif 1.1 root 70: if (n >= 2) 71: return; 72: pic = &s->pics[n]; 73: switch(addr & 0xf) { 74: case 0x04: 75: pic->mask = value; 76: heathrow_pic_update(s); 77: break; 78: case 0x08: 79: /* do not reset level triggered IRQs */ 80: value &= ~pic->level_triggered; 81: pic->events &= ~value; 82: heathrow_pic_update(s); 83: break; 84: default: 85: break; 86: } 87: } 88: 89: static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) 90: { 91: HeathrowPICS *s = opaque; 92: HeathrowPIC *pic; 93: unsigned int n; 94: uint32_t value; 1.1.1.3 ! root 95: 1.1 root 96: n = ((addr & 0xfff) - 0x10) >> 4; 97: if (n >= 2) { 98: value = 0; 99: } else { 100: pic = &s->pics[n]; 101: switch(addr & 0xf) { 102: case 0x0: 103: value = pic->events; 104: break; 105: case 0x4: 106: value = pic->mask; 107: break; 108: case 0xc: 109: value = pic->levels; 110: break; 111: default: 112: value = 0; 113: break; 114: } 115: } 116: #ifdef DEBUG 1.1.1.3 ! root 117: printf("pic_readl: " PADDRX " %u: %08x\n", addr, n, value); 1.1 root 118: #endif 1.1.1.3 ! root 119: #ifdef TARGET_WORDS_BIGENDIAN 1.1 root 120: value = bswap32(value); 1.1.1.3 ! root 121: #endif 1.1 root 122: return value; 123: } 124: 125: static CPUWriteMemoryFunc *pic_write[] = { 126: &pic_writel, 127: &pic_writel, 128: &pic_writel, 129: }; 130: 131: static CPUReadMemoryFunc *pic_read[] = { 132: &pic_readl, 133: &pic_readl, 134: &pic_readl, 135: }; 136: 137: 1.1.1.3 ! root 138: static void heathrow_pic_set_irq(void *opaque, int num, int level) 1.1 root 139: { 140: HeathrowPICS *s = opaque; 141: HeathrowPIC *pic; 142: unsigned int irq_bit; 143: 144: #if defined(DEBUG) 145: { 146: static int last_level[64]; 147: if (last_level[num] != level) { 148: printf("set_irq: num=0x%02x level=%d\n", num, level); 149: last_level[num] = level; 150: } 151: } 152: #endif 153: pic = &s->pics[1 - (num >> 5)]; 154: irq_bit = 1 << (num & 0x1f); 155: if (level) { 156: pic->events |= irq_bit & ~pic->level_triggered; 157: pic->levels |= irq_bit; 158: } else { 159: pic->levels &= ~irq_bit; 160: } 161: heathrow_pic_update(s); 162: } 163: 1.1.1.3 ! root 164: qemu_irq *heathrow_pic_init(int *pmem_index, ! 165: int nb_cpus, qemu_irq **irqs) 1.1 root 166: { 167: HeathrowPICS *s; 1.1.1.3 ! root 168: 1.1 root 169: s = qemu_mallocz(sizeof(HeathrowPICS)); 170: s->pics[0].level_triggered = 0; 171: s->pics[1].level_triggered = 0x1ff00000; 1.1.1.3 ! root 172: /* only 1 CPU */ ! 173: s->irqs = irqs[0]; 1.1 root 174: *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s); 1.1.1.3 ! root 175: ! 176: return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64); 1.1 root 177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.