|
|
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
! 32: #define PIC_DPRINTF(fmt, args...) \
! 33: do { printf("PIC: " fmt , ##args); } while (0)
! 34: #else
! 35: #define PIC_DPRINTF(fmt, args...)
! 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 root 46: HeathrowPIC pics[2];
1.1.1.3 root 47: qemu_irq *irqs;
48: } HeathrowPICS;
1.1 root 49:
50: static inline int check_irq(HeathrowPIC *pic)
51: {
52: return (pic->events | (pic->levels & pic->level_triggered)) & pic->mask;
53: }
54:
55: /* update the CPU irq state */
56: static void heathrow_pic_update(HeathrowPICS *s)
57: {
58: if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) {
1.1.1.3 root 59: qemu_irq_raise(s->irqs[0]);
1.1 root 60: } else {
1.1.1.3 root 61: qemu_irq_lower(s->irqs[0]);
1.1 root 62: }
63: }
64:
65: static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
66: {
67: HeathrowPICS *s = opaque;
68: HeathrowPIC *pic;
69: unsigned int n;
70:
1.1.1.3 root 71: #ifdef TARGET_WORDS_BIGENDIAN
1.1 root 72: value = bswap32(value);
73: #endif
74: n = ((addr & 0xfff) - 0x10) >> 4;
1.1.1.4 ! root 75: PIC_DPRINTF("writel: " TARGET_FMT_plx " %u: %08x\n", addr, n, value);
1.1 root 76: if (n >= 2)
77: return;
78: pic = &s->pics[n];
79: switch(addr & 0xf) {
80: case 0x04:
81: pic->mask = value;
82: heathrow_pic_update(s);
83: break;
84: case 0x08:
85: /* do not reset level triggered IRQs */
86: value &= ~pic->level_triggered;
87: pic->events &= ~value;
88: heathrow_pic_update(s);
89: break;
90: default:
91: break;
92: }
93: }
94:
95: static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
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.1.3 root 123: #ifdef TARGET_WORDS_BIGENDIAN
1.1 root 124: value = bswap32(value);
1.1.1.3 root 125: #endif
1.1 root 126: return value;
127: }
128:
129: static CPUWriteMemoryFunc *pic_write[] = {
130: &pic_writel,
131: &pic_writel,
132: &pic_writel,
133: };
134:
135: static CPUReadMemoryFunc *pic_read[] = {
136: &pic_readl,
137: &pic_readl,
138: &pic_readl,
139: };
140:
141:
1.1.1.3 root 142: static void heathrow_pic_set_irq(void *opaque, int num, int level)
1.1 root 143: {
144: HeathrowPICS *s = opaque;
145: HeathrowPIC *pic;
146: unsigned int irq_bit;
147:
148: #if defined(DEBUG)
149: {
150: static int last_level[64];
151: if (last_level[num] != level) {
1.1.1.4 ! root 152: PIC_DPRINTF("set_irq: num=0x%02x level=%d\n", num, level);
1.1 root 153: last_level[num] = level;
154: }
155: }
156: #endif
157: pic = &s->pics[1 - (num >> 5)];
158: irq_bit = 1 << (num & 0x1f);
159: if (level) {
160: pic->events |= irq_bit & ~pic->level_triggered;
161: pic->levels |= irq_bit;
162: } else {
163: pic->levels &= ~irq_bit;
164: }
165: heathrow_pic_update(s);
166: }
167:
1.1.1.4 ! root 168: static void heathrow_pic_save_one(QEMUFile *f, HeathrowPIC *s)
! 169: {
! 170: qemu_put_be32s(f, &s->events);
! 171: qemu_put_be32s(f, &s->mask);
! 172: qemu_put_be32s(f, &s->levels);
! 173: qemu_put_be32s(f, &s->level_triggered);
! 174: }
! 175:
! 176: static void heathrow_pic_save(QEMUFile *f, void *opaque)
! 177: {
! 178: HeathrowPICS *s = (HeathrowPICS *)opaque;
! 179:
! 180: heathrow_pic_save_one(f, &s->pics[0]);
! 181: heathrow_pic_save_one(f, &s->pics[1]);
! 182: }
! 183:
! 184: static void heathrow_pic_load_one(QEMUFile *f, HeathrowPIC *s)
! 185: {
! 186: qemu_get_be32s(f, &s->events);
! 187: qemu_get_be32s(f, &s->mask);
! 188: qemu_get_be32s(f, &s->levels);
! 189: qemu_get_be32s(f, &s->level_triggered);
! 190: }
! 191:
! 192: static int heathrow_pic_load(QEMUFile *f, void *opaque, int version_id)
! 193: {
! 194: HeathrowPICS *s = (HeathrowPICS *)opaque;
! 195:
! 196: if (version_id != 1)
! 197: return -EINVAL;
! 198:
! 199: heathrow_pic_load_one(f, &s->pics[0]);
! 200: heathrow_pic_load_one(f, &s->pics[1]);
! 201:
! 202: return 0;
! 203: }
! 204:
! 205: static void heathrow_pic_reset_one(HeathrowPIC *s)
! 206: {
! 207: memset(s, '\0', sizeof(HeathrowPIC));
! 208: }
! 209:
! 210: static void heathrow_pic_reset(void *opaque)
! 211: {
! 212: HeathrowPICS *s = opaque;
! 213:
! 214: heathrow_pic_reset_one(&s->pics[0]);
! 215: heathrow_pic_reset_one(&s->pics[1]);
! 216:
! 217: s->pics[0].level_triggered = 0;
! 218: s->pics[1].level_triggered = 0x1ff00000;
! 219: }
! 220:
1.1.1.3 root 221: qemu_irq *heathrow_pic_init(int *pmem_index,
222: int nb_cpus, qemu_irq **irqs)
1.1 root 223: {
224: HeathrowPICS *s;
1.1.1.3 root 225:
1.1 root 226: s = qemu_mallocz(sizeof(HeathrowPICS));
1.1.1.3 root 227: /* only 1 CPU */
228: s->irqs = irqs[0];
1.1 root 229: *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s);
1.1.1.3 root 230:
1.1.1.4 ! root 231: register_savevm("heathrow_pic", -1, 1, heathrow_pic_save,
! 232: heathrow_pic_load, s);
! 233: qemu_register_reset(heathrow_pic_reset, s);
! 234: heathrow_pic_reset(s);
1.1.1.3 root 235: return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
1.1 root 236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.