Statistics
| Branch: | Revision:

root / hw / heathrow_pic.c @ 5fafdf24

History | View | Annotate | Download (4.3 kB)

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