find -type f | xargs sed -i 's/[\t ]*$//g' # Yes, again. Note the star in the regex.
[qemu] / hw / heathrow_pic.c
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 typedef struct HeathrowPICS {
36     HeathrowPIC pics[2];
37 } HeathrowPICS;
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(first_cpu, CPU_INTERRUPT_HARD);
49     } else {
50         cpu_reset_interrupt(first_cpu, 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 static 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 qemu_irq *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 qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
168 }