|
|
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:
1.1.1.4 root 28: /* debug PIC */
29: //#define DEBUG_PIC
30:
31: #ifdef DEBUG_PIC
1.1.1.5 root 32: #define PIC_DPRINTF(fmt, ...) \
33: do { printf("PIC: " fmt , ## __VA_ARGS__); } while (0)
1.1.1.4 root 34: #else
1.1.1.5 root 35: #define PIC_DPRINTF(fmt, ...)
1.1.1.4 root 36: #endif
1.1 root 37:
38: typedef struct HeathrowPIC {
39: uint32_t events;
40: uint32_t mask;
41: uint32_t levels;
42: uint32_t level_triggered;
43: } HeathrowPIC;
44:
1.1.1.3 root 45: typedef struct HeathrowPICS {
1.1.1.10! root 46: MemoryRegion mem;
1.1 root 47: HeathrowPIC pics[2];
1.1.1.3 root 48: qemu_irq *irqs;
49: } HeathrowPICS;
1.1 root 50:
51: static inline int check_irq(HeathrowPIC *pic)
52: {
53: return (pic->events | (pic->levels & pic->level_triggered)) & pic->mask;
54: }
55:
56: /* update the CPU irq state */
57: static void heathrow_pic_update(HeathrowPICS *s)
58: {
59: if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) {
1.1.1.3 root 60: qemu_irq_raise(s->irqs[0]);
1.1 root 61: } else {
1.1.1.3 root 62: qemu_irq_lower(s->irqs[0]);
1.1 root 63: }
64: }
65:
1.1.1.10! root 66: static void pic_write(void *opaque, target_phys_addr_t addr,
! 67: uint64_t value, unsigned size)
1.1 root 68: {
69: HeathrowPICS *s = opaque;
70: HeathrowPIC *pic;
71: unsigned int n;
72:
73: n = ((addr & 0xfff) - 0x10) >> 4;
1.1.1.4 root 74: PIC_DPRINTF("writel: " TARGET_FMT_plx " %u: %08x\n", addr, n, value);
1.1 root 75: if (n >= 2)
76: return;
77: pic = &s->pics[n];
78: switch(addr & 0xf) {
79: case 0x04:
80: pic->mask = value;
81: heathrow_pic_update(s);
82: break;
83: case 0x08:
84: /* do not reset level triggered IRQs */
85: value &= ~pic->level_triggered;
86: pic->events &= ~value;
87: heathrow_pic_update(s);
88: break;
89: default:
90: break;
91: }
92: }
93:
1.1.1.10! root 94: static uint64_t pic_read(void *opaque, target_phys_addr_t addr,
! 95: unsigned size)
1.1 root 96: {
97: HeathrowPICS *s = opaque;
98: HeathrowPIC *pic;
99: unsigned int n;
100: uint32_t value;
1.1.1.3 root 101:
1.1 root 102: n = ((addr & 0xfff) - 0x10) >> 4;
103: if (n >= 2) {
104: value = 0;
105: } else {
106: pic = &s->pics[n];
107: switch(addr & 0xf) {
108: case 0x0:
109: value = pic->events;
110: break;
111: case 0x4:
112: value = pic->mask;
113: break;
114: case 0xc:
115: value = pic->levels;
116: break;
117: default:
118: value = 0;
119: break;
120: }
121: }
1.1.1.4 root 122: PIC_DPRINTF("readl: " TARGET_FMT_plx " %u: %08x\n", addr, n, value);
1.1 root 123: return value;
124: }
125:
1.1.1.10! root 126: static const MemoryRegionOps heathrow_pic_ops = {
! 127: .read = pic_read,
! 128: .write = pic_write,
! 129: .endianness = DEVICE_LITTLE_ENDIAN,
1.1 root 130: };
131:
1.1.1.3 root 132: static void heathrow_pic_set_irq(void *opaque, int num, int level)
1.1 root 133: {
134: HeathrowPICS *s = opaque;
135: HeathrowPIC *pic;
136: unsigned int irq_bit;
137:
138: #if defined(DEBUG)
139: {
140: static int last_level[64];
141: if (last_level[num] != level) {
1.1.1.4 root 142: PIC_DPRINTF("set_irq: num=0x%02x level=%d\n", num, level);
1.1 root 143: last_level[num] = level;
144: }
145: }
146: #endif
147: pic = &s->pics[1 - (num >> 5)];
148: irq_bit = 1 << (num & 0x1f);
149: if (level) {
150: pic->events |= irq_bit & ~pic->level_triggered;
151: pic->levels |= irq_bit;
152: } else {
153: pic->levels &= ~irq_bit;
154: }
155: heathrow_pic_update(s);
156: }
157:
1.1.1.9 root 158: static const VMStateDescription vmstate_heathrow_pic_one = {
159: .name = "heathrow_pic_one",
160: .version_id = 0,
161: .minimum_version_id = 0,
162: .minimum_version_id_old = 0,
163: .fields = (VMStateField[]) {
164: VMSTATE_UINT32(events, HeathrowPIC),
165: VMSTATE_UINT32(mask, HeathrowPIC),
166: VMSTATE_UINT32(levels, HeathrowPIC),
167: VMSTATE_UINT32(level_triggered, HeathrowPIC),
168: VMSTATE_END_OF_LIST()
169: }
170: };
171:
172: static const VMStateDescription vmstate_heathrow_pic = {
173: .name = "heathrow_pic",
174: .version_id = 1,
175: .minimum_version_id = 1,
176: .minimum_version_id_old = 1,
177: .fields = (VMStateField[]) {
178: VMSTATE_STRUCT_ARRAY(pics, HeathrowPICS, 2, 1,
179: vmstate_heathrow_pic_one, HeathrowPIC),
180: VMSTATE_END_OF_LIST()
181: }
182: };
1.1.1.4 root 183:
184: static void heathrow_pic_reset_one(HeathrowPIC *s)
185: {
186: memset(s, '\0', sizeof(HeathrowPIC));
187: }
188:
189: static void heathrow_pic_reset(void *opaque)
190: {
191: HeathrowPICS *s = opaque;
192:
193: heathrow_pic_reset_one(&s->pics[0]);
194: heathrow_pic_reset_one(&s->pics[1]);
195:
196: s->pics[0].level_triggered = 0;
197: s->pics[1].level_triggered = 0x1ff00000;
198: }
199:
1.1.1.10! root 200: qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
1.1.1.3 root 201: int nb_cpus, qemu_irq **irqs)
1.1 root 202: {
203: HeathrowPICS *s;
1.1.1.3 root 204:
1.1.1.10! root 205: s = g_malloc0(sizeof(HeathrowPICS));
1.1.1.3 root 206: /* only 1 CPU */
207: s->irqs = irqs[0];
1.1.1.10! root 208: memory_region_init_io(&s->mem, &heathrow_pic_ops, s,
! 209: "heathrow-pic", 0x1000);
! 210: *pmem = &s->mem;
1.1.1.3 root 211:
1.1.1.9 root 212: vmstate_register(NULL, -1, &vmstate_heathrow_pic, s);
1.1.1.4 root 213: qemu_register_reset(heathrow_pic_reset, s);
1.1.1.3 root 214: return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
1.1 root 215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.