Statistics
| Branch: | Revision:

root / hw / ppc405_uc.c @ 4118a970

History | View | Annotate | Download (90.4 kB)

1 8ecc7913 j_mayer
/*
2 8ecc7913 j_mayer
 * QEMU PowerPC 405 embedded processors emulation
3 5fafdf24 ths
 *
4 8ecc7913 j_mayer
 * Copyright (c) 2007 Jocelyn Mayer
5 5fafdf24 ths
 *
6 8ecc7913 j_mayer
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 8ecc7913 j_mayer
 * of this software and associated documentation files (the "Software"), to deal
8 8ecc7913 j_mayer
 * in the Software without restriction, including without limitation the rights
9 8ecc7913 j_mayer
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 8ecc7913 j_mayer
 * copies of the Software, and to permit persons to whom the Software is
11 8ecc7913 j_mayer
 * furnished to do so, subject to the following conditions:
12 8ecc7913 j_mayer
 *
13 8ecc7913 j_mayer
 * The above copyright notice and this permission notice shall be included in
14 8ecc7913 j_mayer
 * all copies or substantial portions of the Software.
15 8ecc7913 j_mayer
 *
16 8ecc7913 j_mayer
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 8ecc7913 j_mayer
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 8ecc7913 j_mayer
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 8ecc7913 j_mayer
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 8ecc7913 j_mayer
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 8ecc7913 j_mayer
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 8ecc7913 j_mayer
 * THE SOFTWARE.
23 8ecc7913 j_mayer
 */
24 8ecc7913 j_mayer
#include "vl.h"
25 04f20795 j_mayer
#include "ppc405.h"
26 8ecc7913 j_mayer
27 8ecc7913 j_mayer
extern int loglevel;
28 8ecc7913 j_mayer
extern FILE *logfile;
29 8ecc7913 j_mayer
30 9c02f1a2 j_mayer
//#define DEBUG_MMIO
31 8ecc7913 j_mayer
#define DEBUG_OPBA
32 8ecc7913 j_mayer
#define DEBUG_SDRAM
33 8ecc7913 j_mayer
#define DEBUG_GPIO
34 8ecc7913 j_mayer
#define DEBUG_SERIAL
35 8ecc7913 j_mayer
#define DEBUG_OCM
36 9c02f1a2 j_mayer
//#define DEBUG_I2C
37 9c02f1a2 j_mayer
#define DEBUG_GPT
38 9c02f1a2 j_mayer
#define DEBUG_MAL
39 8ecc7913 j_mayer
#define DEBUG_UIC
40 8ecc7913 j_mayer
#define DEBUG_CLOCKS
41 9c02f1a2 j_mayer
//#define DEBUG_UNASSIGNED
42 8ecc7913 j_mayer
43 8ecc7913 j_mayer
/*****************************************************************************/
44 8ecc7913 j_mayer
/* Generic PowerPC 405 processor instanciation */
45 8ecc7913 j_mayer
CPUState *ppc405_init (const unsigned char *cpu_model,
46 8ecc7913 j_mayer
                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
47 8ecc7913 j_mayer
                       uint32_t sysclk)
48 8ecc7913 j_mayer
{
49 8ecc7913 j_mayer
    CPUState *env;
50 8ecc7913 j_mayer
    ppc_def_t *def;
51 8ecc7913 j_mayer
52 8ecc7913 j_mayer
    /* init CPUs */
53 8ecc7913 j_mayer
    env = cpu_init();
54 8ecc7913 j_mayer
    qemu_register_reset(&cpu_ppc_reset, env);
55 8ecc7913 j_mayer
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
56 8ecc7913 j_mayer
    ppc_find_by_name(cpu_model, &def);
57 8ecc7913 j_mayer
    if (def == NULL) {
58 8ecc7913 j_mayer
        cpu_abort(env, "Unable to find PowerPC %s CPU definition\n",
59 8ecc7913 j_mayer
                  cpu_model);
60 8ecc7913 j_mayer
    }
61 8ecc7913 j_mayer
    cpu_ppc_register(env, def);
62 8ecc7913 j_mayer
    cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
63 8ecc7913 j_mayer
    cpu_clk->opaque = env;
64 8ecc7913 j_mayer
    /* Set time-base frequency to sysclk */
65 8ecc7913 j_mayer
    tb_clk->cb = ppc_emb_timers_init(env, sysclk);
66 8ecc7913 j_mayer
    tb_clk->opaque = env;
67 8ecc7913 j_mayer
    ppc_dcr_init(env, NULL, NULL);
68 8ecc7913 j_mayer
69 8ecc7913 j_mayer
    return env;
70 8ecc7913 j_mayer
}
71 8ecc7913 j_mayer
72 b8d3f5d1 j_mayer
ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
73 b8d3f5d1 j_mayer
                                uint32_t flags)
74 04f20795 j_mayer
{
75 04f20795 j_mayer
    ram_addr_t bdloc;
76 04f20795 j_mayer
    int i, n;
77 04f20795 j_mayer
78 04f20795 j_mayer
    /* We put the bd structure at the top of memory */
79 be58fc7c j_mayer
    if (bd->bi_memsize >= 0x01000000UL)
80 be58fc7c j_mayer
        bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t);
81 be58fc7c j_mayer
    else
82 be58fc7c j_mayer
        bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);
83 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x00, bd->bi_memstart);
84 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x04, bd->bi_memsize);
85 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x08, bd->bi_flashstart);
86 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x0C, bd->bi_flashsize);
87 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x10, bd->bi_flashoffset);
88 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x14, bd->bi_sramstart);
89 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x18, bd->bi_sramsize);
90 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x1C, bd->bi_bootflags);
91 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x20, bd->bi_ipaddr);
92 04f20795 j_mayer
    for (i = 0; i < 6; i++)
93 04f20795 j_mayer
        stb_raw(phys_ram_base + bdloc + 0x24 + i, bd->bi_enetaddr[i]);
94 04f20795 j_mayer
    stw_raw(phys_ram_base + bdloc + 0x2A, bd->bi_ethspeed);
95 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x2C, bd->bi_intfreq);
96 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x30, bd->bi_busfreq);
97 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x34, bd->bi_baudrate);
98 04f20795 j_mayer
    for (i = 0; i < 4; i++)
99 04f20795 j_mayer
        stb_raw(phys_ram_base + bdloc + 0x38 + i, bd->bi_s_version[i]);
100 04f20795 j_mayer
    for (i = 0; i < 32; i++)
101 04f20795 j_mayer
        stb_raw(phys_ram_base + bdloc + 0x3C + i, bd->bi_s_version[i]);
102 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x5C, bd->bi_plb_busfreq);
103 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + 0x60, bd->bi_pci_busfreq);
104 04f20795 j_mayer
    for (i = 0; i < 6; i++)
105 04f20795 j_mayer
        stb_raw(phys_ram_base + bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
106 04f20795 j_mayer
    n = 0x6A;
107 b8d3f5d1 j_mayer
    if (flags & 0x00000001) {
108 04f20795 j_mayer
        for (i = 0; i < 6; i++)
109 04f20795 j_mayer
            stb_raw(phys_ram_base + bdloc + n++, bd->bi_pci_enetaddr2[i]);
110 04f20795 j_mayer
    }
111 04f20795 j_mayer
    stl_raw(phys_ram_base + bdloc + n, bd->bi_opbfreq);
112 04f20795 j_mayer
    n += 4;
113 04f20795 j_mayer
    for (i = 0; i < 2; i++) {
114 04f20795 j_mayer
        stl_raw(phys_ram_base + bdloc + n, bd->bi_iic_fast[i]);
115 04f20795 j_mayer
        n += 4;
116 04f20795 j_mayer
    }
117 04f20795 j_mayer
118 04f20795 j_mayer
    return bdloc;
119 04f20795 j_mayer
}
120 04f20795 j_mayer
121 8ecc7913 j_mayer
/*****************************************************************************/
122 8ecc7913 j_mayer
/* Shared peripherals */
123 8ecc7913 j_mayer
124 8ecc7913 j_mayer
/*****************************************************************************/
125 8ecc7913 j_mayer
/* Fake device used to map multiple devices in a single memory page */
126 8ecc7913 j_mayer
#define MMIO_AREA_BITS 8
127 8ecc7913 j_mayer
#define MMIO_AREA_LEN (1 << MMIO_AREA_BITS)
128 8ecc7913 j_mayer
#define MMIO_AREA_NB (1 << (TARGET_PAGE_BITS - MMIO_AREA_BITS))
129 8ecc7913 j_mayer
#define MMIO_IDX(addr) (((addr) >> MMIO_AREA_BITS) & (MMIO_AREA_NB - 1))
130 8ecc7913 j_mayer
struct ppc4xx_mmio_t {
131 9c02f1a2 j_mayer
    target_phys_addr_t base;
132 8ecc7913 j_mayer
    CPUReadMemoryFunc **mem_read[MMIO_AREA_NB];
133 8ecc7913 j_mayer
    CPUWriteMemoryFunc **mem_write[MMIO_AREA_NB];
134 8ecc7913 j_mayer
    void *opaque[MMIO_AREA_NB];
135 8ecc7913 j_mayer
};
136 8ecc7913 j_mayer
137 9c02f1a2 j_mayer
static uint32_t unassigned_mmio_readb (void *opaque, target_phys_addr_t addr)
138 8ecc7913 j_mayer
{
139 8ecc7913 j_mayer
#ifdef DEBUG_UNASSIGNED
140 9c02f1a2 j_mayer
    ppc4xx_mmio_t *mmio;
141 9c02f1a2 j_mayer
142 9c02f1a2 j_mayer
    mmio = opaque;
143 9c02f1a2 j_mayer
    printf("Unassigned mmio read 0x" PADDRX " base " PADDRX "\n",
144 9c02f1a2 j_mayer
           addr, mmio->base);
145 8ecc7913 j_mayer
#endif
146 8ecc7913 j_mayer
147 8ecc7913 j_mayer
    return 0;
148 8ecc7913 j_mayer
}
149 8ecc7913 j_mayer
150 9c02f1a2 j_mayer
static void unassigned_mmio_writeb (void *opaque,
151 8ecc7913 j_mayer
                                   target_phys_addr_t addr, uint32_t val)
152 8ecc7913 j_mayer
{
153 8ecc7913 j_mayer
#ifdef DEBUG_UNASSIGNED
154 9c02f1a2 j_mayer
    ppc4xx_mmio_t *mmio;
155 9c02f1a2 j_mayer
156 9c02f1a2 j_mayer
    mmio = opaque;
157 9c02f1a2 j_mayer
    printf("Unassigned mmio write 0x" PADDRX " = 0x%x base " PADDRX "\n",
158 9c02f1a2 j_mayer
           addr, val, mmio->base);
159 8ecc7913 j_mayer
#endif
160 8ecc7913 j_mayer
}
161 8ecc7913 j_mayer
162 9c02f1a2 j_mayer
static CPUReadMemoryFunc *unassigned_mmio_read[3] = {
163 9c02f1a2 j_mayer
    unassigned_mmio_readb,
164 9c02f1a2 j_mayer
    unassigned_mmio_readb,
165 9c02f1a2 j_mayer
    unassigned_mmio_readb,
166 8ecc7913 j_mayer
};
167 8ecc7913 j_mayer
168 9c02f1a2 j_mayer
static CPUWriteMemoryFunc *unassigned_mmio_write[3] = {
169 9c02f1a2 j_mayer
    unassigned_mmio_writeb,
170 9c02f1a2 j_mayer
    unassigned_mmio_writeb,
171 9c02f1a2 j_mayer
    unassigned_mmio_writeb,
172 8ecc7913 j_mayer
};
173 8ecc7913 j_mayer
174 8ecc7913 j_mayer
static uint32_t mmio_readlen (ppc4xx_mmio_t *mmio,
175 8ecc7913 j_mayer
                              target_phys_addr_t addr, int len)
176 8ecc7913 j_mayer
{
177 8ecc7913 j_mayer
    CPUReadMemoryFunc **mem_read;
178 8ecc7913 j_mayer
    uint32_t ret;
179 8ecc7913 j_mayer
    int idx;
180 8ecc7913 j_mayer
181 8ecc7913 j_mayer
    idx = MMIO_IDX(addr - mmio->base);
182 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
183 8ecc7913 j_mayer
    printf("%s: mmio %p len %d addr " PADDRX " idx %d\n", __func__,
184 8ecc7913 j_mayer
           mmio, len, addr, idx);
185 8ecc7913 j_mayer
#endif
186 8ecc7913 j_mayer
    mem_read = mmio->mem_read[idx];
187 9c02f1a2 j_mayer
    ret = (*mem_read[len])(mmio->opaque[idx], addr - mmio->base);
188 8ecc7913 j_mayer
189 8ecc7913 j_mayer
    return ret;
190 8ecc7913 j_mayer
}
191 8ecc7913 j_mayer
192 8ecc7913 j_mayer
static void mmio_writelen (ppc4xx_mmio_t *mmio,
193 8ecc7913 j_mayer
                           target_phys_addr_t addr, uint32_t value, int len)
194 8ecc7913 j_mayer
{
195 8ecc7913 j_mayer
    CPUWriteMemoryFunc **mem_write;
196 8ecc7913 j_mayer
    int idx;
197 8ecc7913 j_mayer
198 8ecc7913 j_mayer
    idx = MMIO_IDX(addr - mmio->base);
199 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
200 8ecc7913 j_mayer
    printf("%s: mmio %p len %d addr " PADDRX " idx %d value %08x\n", __func__,
201 8ecc7913 j_mayer
           mmio, len, addr, idx, value);
202 8ecc7913 j_mayer
#endif
203 8ecc7913 j_mayer
    mem_write = mmio->mem_write[idx];
204 9c02f1a2 j_mayer
    (*mem_write[len])(mmio->opaque[idx], addr - mmio->base, value);
205 8ecc7913 j_mayer
}
206 8ecc7913 j_mayer
207 8ecc7913 j_mayer
static uint32_t mmio_readb (void *opaque, target_phys_addr_t addr)
208 8ecc7913 j_mayer
{
209 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
210 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
211 8ecc7913 j_mayer
#endif
212 8ecc7913 j_mayer
213 8ecc7913 j_mayer
    return mmio_readlen(opaque, addr, 0);
214 8ecc7913 j_mayer
}
215 8ecc7913 j_mayer
216 8ecc7913 j_mayer
static void mmio_writeb (void *opaque,
217 8ecc7913 j_mayer
                         target_phys_addr_t addr, uint32_t value)
218 8ecc7913 j_mayer
{
219 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
220 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
221 8ecc7913 j_mayer
#endif
222 8ecc7913 j_mayer
    mmio_writelen(opaque, addr, value, 0);
223 8ecc7913 j_mayer
}
224 8ecc7913 j_mayer
225 8ecc7913 j_mayer
static uint32_t mmio_readw (void *opaque, target_phys_addr_t addr)
226 8ecc7913 j_mayer
{
227 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
228 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
229 8ecc7913 j_mayer
#endif
230 8ecc7913 j_mayer
231 8ecc7913 j_mayer
    return mmio_readlen(opaque, addr, 1);
232 8ecc7913 j_mayer
}
233 8ecc7913 j_mayer
234 8ecc7913 j_mayer
static void mmio_writew (void *opaque,
235 8ecc7913 j_mayer
                         target_phys_addr_t addr, uint32_t value)
236 8ecc7913 j_mayer
{
237 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
238 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
239 8ecc7913 j_mayer
#endif
240 8ecc7913 j_mayer
    mmio_writelen(opaque, addr, value, 1);
241 8ecc7913 j_mayer
}
242 8ecc7913 j_mayer
243 8ecc7913 j_mayer
static uint32_t mmio_readl (void *opaque, target_phys_addr_t addr)
244 8ecc7913 j_mayer
{
245 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
246 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
247 8ecc7913 j_mayer
#endif
248 8ecc7913 j_mayer
249 8ecc7913 j_mayer
    return mmio_readlen(opaque, addr, 2);
250 8ecc7913 j_mayer
}
251 8ecc7913 j_mayer
252 8ecc7913 j_mayer
static void mmio_writel (void *opaque,
253 8ecc7913 j_mayer
                         target_phys_addr_t addr, uint32_t value)
254 8ecc7913 j_mayer
{
255 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
256 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
257 8ecc7913 j_mayer
#endif
258 8ecc7913 j_mayer
    mmio_writelen(opaque, addr, value, 2);
259 8ecc7913 j_mayer
}
260 8ecc7913 j_mayer
261 8ecc7913 j_mayer
static CPUReadMemoryFunc *mmio_read[] = {
262 8ecc7913 j_mayer
    &mmio_readb,
263 8ecc7913 j_mayer
    &mmio_readw,
264 8ecc7913 j_mayer
    &mmio_readl,
265 8ecc7913 j_mayer
};
266 8ecc7913 j_mayer
267 8ecc7913 j_mayer
static CPUWriteMemoryFunc *mmio_write[] = {
268 8ecc7913 j_mayer
    &mmio_writeb,
269 8ecc7913 j_mayer
    &mmio_writew,
270 8ecc7913 j_mayer
    &mmio_writel,
271 8ecc7913 j_mayer
};
272 8ecc7913 j_mayer
273 8ecc7913 j_mayer
int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
274 9c02f1a2 j_mayer
                          target_phys_addr_t offset, uint32_t len,
275 8ecc7913 j_mayer
                          CPUReadMemoryFunc **mem_read,
276 8ecc7913 j_mayer
                          CPUWriteMemoryFunc **mem_write, void *opaque)
277 8ecc7913 j_mayer
{
278 8ecc7913 j_mayer
    uint32_t end;
279 8ecc7913 j_mayer
    int idx, eidx;
280 8ecc7913 j_mayer
281 8ecc7913 j_mayer
    if ((offset + len) > TARGET_PAGE_SIZE)
282 8ecc7913 j_mayer
        return -1;
283 8ecc7913 j_mayer
    idx = MMIO_IDX(offset);
284 8ecc7913 j_mayer
    end = offset + len - 1;
285 8ecc7913 j_mayer
    eidx = MMIO_IDX(end);
286 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
287 8ecc7913 j_mayer
    printf("%s: offset %08x len %08x %08x %d %d\n", __func__, offset, len,
288 8ecc7913 j_mayer
           end, idx, eidx);
289 8ecc7913 j_mayer
#endif
290 8ecc7913 j_mayer
    for (; idx <= eidx; idx++) {
291 8ecc7913 j_mayer
        mmio->mem_read[idx] = mem_read;
292 8ecc7913 j_mayer
        mmio->mem_write[idx] = mem_write;
293 8ecc7913 j_mayer
        mmio->opaque[idx] = opaque;
294 8ecc7913 j_mayer
    }
295 8ecc7913 j_mayer
296 8ecc7913 j_mayer
    return 0;
297 8ecc7913 j_mayer
}
298 8ecc7913 j_mayer
299 9c02f1a2 j_mayer
ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base)
300 8ecc7913 j_mayer
{
301 8ecc7913 j_mayer
    ppc4xx_mmio_t *mmio;
302 8ecc7913 j_mayer
    int mmio_memory;
303 8ecc7913 j_mayer
304 8ecc7913 j_mayer
    mmio = qemu_mallocz(sizeof(ppc4xx_mmio_t));
305 8ecc7913 j_mayer
    if (mmio != NULL) {
306 8ecc7913 j_mayer
        mmio->base = base;
307 8ecc7913 j_mayer
        mmio_memory = cpu_register_io_memory(0, mmio_read, mmio_write, mmio);
308 8ecc7913 j_mayer
#if defined(DEBUG_MMIO)
309 8ecc7913 j_mayer
        printf("%s: %p base %08x len %08x %d\n", __func__,
310 8ecc7913 j_mayer
               mmio, base, TARGET_PAGE_SIZE, mmio_memory);
311 8ecc7913 j_mayer
#endif
312 8ecc7913 j_mayer
        cpu_register_physical_memory(base, TARGET_PAGE_SIZE, mmio_memory);
313 8ecc7913 j_mayer
        ppc4xx_mmio_register(env, mmio, 0, TARGET_PAGE_SIZE,
314 9c02f1a2 j_mayer
                             unassigned_mmio_read, unassigned_mmio_write,
315 9c02f1a2 j_mayer
                             mmio);
316 8ecc7913 j_mayer
    }
317 8ecc7913 j_mayer
318 8ecc7913 j_mayer
    return mmio;
319 8ecc7913 j_mayer
}
320 8ecc7913 j_mayer
321 8ecc7913 j_mayer
/*****************************************************************************/
322 8ecc7913 j_mayer
/* Peripheral local bus arbitrer */
323 8ecc7913 j_mayer
enum {
324 8ecc7913 j_mayer
    PLB0_BESR = 0x084,
325 8ecc7913 j_mayer
    PLB0_BEAR = 0x086,
326 8ecc7913 j_mayer
    PLB0_ACR  = 0x087,
327 8ecc7913 j_mayer
};
328 8ecc7913 j_mayer
329 8ecc7913 j_mayer
typedef struct ppc4xx_plb_t ppc4xx_plb_t;
330 8ecc7913 j_mayer
struct ppc4xx_plb_t {
331 8ecc7913 j_mayer
    uint32_t acr;
332 8ecc7913 j_mayer
    uint32_t bear;
333 8ecc7913 j_mayer
    uint32_t besr;
334 8ecc7913 j_mayer
};
335 8ecc7913 j_mayer
336 8ecc7913 j_mayer
static target_ulong dcr_read_plb (void *opaque, int dcrn)
337 8ecc7913 j_mayer
{
338 8ecc7913 j_mayer
    ppc4xx_plb_t *plb;
339 8ecc7913 j_mayer
    target_ulong ret;
340 8ecc7913 j_mayer
341 8ecc7913 j_mayer
    plb = opaque;
342 8ecc7913 j_mayer
    switch (dcrn) {
343 8ecc7913 j_mayer
    case PLB0_ACR:
344 8ecc7913 j_mayer
        ret = plb->acr;
345 8ecc7913 j_mayer
        break;
346 8ecc7913 j_mayer
    case PLB0_BEAR:
347 8ecc7913 j_mayer
        ret = plb->bear;
348 8ecc7913 j_mayer
        break;
349 8ecc7913 j_mayer
    case PLB0_BESR:
350 8ecc7913 j_mayer
        ret = plb->besr;
351 8ecc7913 j_mayer
        break;
352 8ecc7913 j_mayer
    default:
353 8ecc7913 j_mayer
        /* Avoid gcc warning */
354 8ecc7913 j_mayer
        ret = 0;
355 8ecc7913 j_mayer
        break;
356 8ecc7913 j_mayer
    }
357 8ecc7913 j_mayer
358 8ecc7913 j_mayer
    return ret;
359 8ecc7913 j_mayer
}
360 8ecc7913 j_mayer
361 8ecc7913 j_mayer
static void dcr_write_plb (void *opaque, int dcrn, target_ulong val)
362 8ecc7913 j_mayer
{
363 8ecc7913 j_mayer
    ppc4xx_plb_t *plb;
364 8ecc7913 j_mayer
365 8ecc7913 j_mayer
    plb = opaque;
366 8ecc7913 j_mayer
    switch (dcrn) {
367 8ecc7913 j_mayer
    case PLB0_ACR:
368 9c02f1a2 j_mayer
        /* We don't care about the actual parameters written as
369 9c02f1a2 j_mayer
         * we don't manage any priorities on the bus
370 9c02f1a2 j_mayer
         */
371 9c02f1a2 j_mayer
        plb->acr = val & 0xF8000000;
372 8ecc7913 j_mayer
        break;
373 8ecc7913 j_mayer
    case PLB0_BEAR:
374 8ecc7913 j_mayer
        /* Read only */
375 8ecc7913 j_mayer
        break;
376 8ecc7913 j_mayer
    case PLB0_BESR:
377 8ecc7913 j_mayer
        /* Write-clear */
378 8ecc7913 j_mayer
        plb->besr &= ~val;
379 8ecc7913 j_mayer
        break;
380 8ecc7913 j_mayer
    }
381 8ecc7913 j_mayer
}
382 8ecc7913 j_mayer
383 8ecc7913 j_mayer
static void ppc4xx_plb_reset (void *opaque)
384 8ecc7913 j_mayer
{
385 8ecc7913 j_mayer
    ppc4xx_plb_t *plb;
386 8ecc7913 j_mayer
387 8ecc7913 j_mayer
    plb = opaque;
388 8ecc7913 j_mayer
    plb->acr = 0x00000000;
389 8ecc7913 j_mayer
    plb->bear = 0x00000000;
390 8ecc7913 j_mayer
    plb->besr = 0x00000000;
391 8ecc7913 j_mayer
}
392 8ecc7913 j_mayer
393 8ecc7913 j_mayer
void ppc4xx_plb_init (CPUState *env)
394 8ecc7913 j_mayer
{
395 8ecc7913 j_mayer
    ppc4xx_plb_t *plb;
396 8ecc7913 j_mayer
397 8ecc7913 j_mayer
    plb = qemu_mallocz(sizeof(ppc4xx_plb_t));
398 8ecc7913 j_mayer
    if (plb != NULL) {
399 8ecc7913 j_mayer
        ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
400 8ecc7913 j_mayer
        ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
401 8ecc7913 j_mayer
        ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
402 8ecc7913 j_mayer
        ppc4xx_plb_reset(plb);
403 8ecc7913 j_mayer
        qemu_register_reset(ppc4xx_plb_reset, plb);
404 8ecc7913 j_mayer
    }
405 8ecc7913 j_mayer
}
406 8ecc7913 j_mayer
407 8ecc7913 j_mayer
/*****************************************************************************/
408 8ecc7913 j_mayer
/* PLB to OPB bridge */
409 8ecc7913 j_mayer
enum {
410 8ecc7913 j_mayer
    POB0_BESR0 = 0x0A0,
411 8ecc7913 j_mayer
    POB0_BESR1 = 0x0A2,
412 8ecc7913 j_mayer
    POB0_BEAR  = 0x0A4,
413 8ecc7913 j_mayer
};
414 8ecc7913 j_mayer
415 8ecc7913 j_mayer
typedef struct ppc4xx_pob_t ppc4xx_pob_t;
416 8ecc7913 j_mayer
struct ppc4xx_pob_t {
417 8ecc7913 j_mayer
    uint32_t bear;
418 8ecc7913 j_mayer
    uint32_t besr[2];
419 8ecc7913 j_mayer
};
420 8ecc7913 j_mayer
421 8ecc7913 j_mayer
static target_ulong dcr_read_pob (void *opaque, int dcrn)
422 8ecc7913 j_mayer
{
423 8ecc7913 j_mayer
    ppc4xx_pob_t *pob;
424 8ecc7913 j_mayer
    target_ulong ret;
425 8ecc7913 j_mayer
426 8ecc7913 j_mayer
    pob = opaque;
427 8ecc7913 j_mayer
    switch (dcrn) {
428 8ecc7913 j_mayer
    case POB0_BEAR:
429 8ecc7913 j_mayer
        ret = pob->bear;
430 8ecc7913 j_mayer
        break;
431 8ecc7913 j_mayer
    case POB0_BESR0:
432 8ecc7913 j_mayer
    case POB0_BESR1:
433 8ecc7913 j_mayer
        ret = pob->besr[dcrn - POB0_BESR0];
434 8ecc7913 j_mayer
        break;
435 8ecc7913 j_mayer
    default:
436 8ecc7913 j_mayer
        /* Avoid gcc warning */
437 8ecc7913 j_mayer
        ret = 0;
438 8ecc7913 j_mayer
        break;
439 8ecc7913 j_mayer
    }
440 8ecc7913 j_mayer
441 8ecc7913 j_mayer
    return ret;
442 8ecc7913 j_mayer
}
443 8ecc7913 j_mayer
444 8ecc7913 j_mayer
static void dcr_write_pob (void *opaque, int dcrn, target_ulong val)
445 8ecc7913 j_mayer
{
446 8ecc7913 j_mayer
    ppc4xx_pob_t *pob;
447 8ecc7913 j_mayer
448 8ecc7913 j_mayer
    pob = opaque;
449 8ecc7913 j_mayer
    switch (dcrn) {
450 8ecc7913 j_mayer
    case POB0_BEAR:
451 8ecc7913 j_mayer
        /* Read only */
452 8ecc7913 j_mayer
        break;
453 8ecc7913 j_mayer
    case POB0_BESR0:
454 8ecc7913 j_mayer
    case POB0_BESR1:
455 8ecc7913 j_mayer
        /* Write-clear */
456 8ecc7913 j_mayer
        pob->besr[dcrn - POB0_BESR0] &= ~val;
457 8ecc7913 j_mayer
        break;
458 8ecc7913 j_mayer
    }
459 8ecc7913 j_mayer
}
460 8ecc7913 j_mayer
461 8ecc7913 j_mayer
static void ppc4xx_pob_reset (void *opaque)
462 8ecc7913 j_mayer
{
463 8ecc7913 j_mayer
    ppc4xx_pob_t *pob;
464 8ecc7913 j_mayer
465 8ecc7913 j_mayer
    pob = opaque;
466 8ecc7913 j_mayer
    /* No error */
467 8ecc7913 j_mayer
    pob->bear = 0x00000000;
468 8ecc7913 j_mayer
    pob->besr[0] = 0x0000000;
469 8ecc7913 j_mayer
    pob->besr[1] = 0x0000000;
470 8ecc7913 j_mayer
}
471 8ecc7913 j_mayer
472 8ecc7913 j_mayer
void ppc4xx_pob_init (CPUState *env)
473 8ecc7913 j_mayer
{
474 8ecc7913 j_mayer
    ppc4xx_pob_t *pob;
475 8ecc7913 j_mayer
476 8ecc7913 j_mayer
    pob = qemu_mallocz(sizeof(ppc4xx_pob_t));
477 8ecc7913 j_mayer
    if (pob != NULL) {
478 8ecc7913 j_mayer
        ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);
479 8ecc7913 j_mayer
        ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);
480 8ecc7913 j_mayer
        ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);
481 8ecc7913 j_mayer
        qemu_register_reset(ppc4xx_pob_reset, pob);
482 8ecc7913 j_mayer
        ppc4xx_pob_reset(env);
483 8ecc7913 j_mayer
    }
484 8ecc7913 j_mayer
}
485 8ecc7913 j_mayer
486 8ecc7913 j_mayer
/*****************************************************************************/
487 8ecc7913 j_mayer
/* OPB arbitrer */
488 8ecc7913 j_mayer
typedef struct ppc4xx_opba_t ppc4xx_opba_t;
489 8ecc7913 j_mayer
struct ppc4xx_opba_t {
490 9c02f1a2 j_mayer
    target_phys_addr_t base;
491 8ecc7913 j_mayer
    uint8_t cr;
492 8ecc7913 j_mayer
    uint8_t pr;
493 8ecc7913 j_mayer
};
494 8ecc7913 j_mayer
495 8ecc7913 j_mayer
static uint32_t opba_readb (void *opaque, target_phys_addr_t addr)
496 8ecc7913 j_mayer
{
497 8ecc7913 j_mayer
    ppc4xx_opba_t *opba;
498 8ecc7913 j_mayer
    uint32_t ret;
499 8ecc7913 j_mayer
500 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
501 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
502 8ecc7913 j_mayer
#endif
503 8ecc7913 j_mayer
    opba = opaque;
504 8ecc7913 j_mayer
    switch (addr - opba->base) {
505 8ecc7913 j_mayer
    case 0x00:
506 8ecc7913 j_mayer
        ret = opba->cr;
507 8ecc7913 j_mayer
        break;
508 8ecc7913 j_mayer
    case 0x01:
509 8ecc7913 j_mayer
        ret = opba->pr;
510 8ecc7913 j_mayer
        break;
511 8ecc7913 j_mayer
    default:
512 8ecc7913 j_mayer
        ret = 0x00;
513 8ecc7913 j_mayer
        break;
514 8ecc7913 j_mayer
    }
515 8ecc7913 j_mayer
516 8ecc7913 j_mayer
    return ret;
517 8ecc7913 j_mayer
}
518 8ecc7913 j_mayer
519 8ecc7913 j_mayer
static void opba_writeb (void *opaque,
520 8ecc7913 j_mayer
                         target_phys_addr_t addr, uint32_t value)
521 8ecc7913 j_mayer
{
522 8ecc7913 j_mayer
    ppc4xx_opba_t *opba;
523 8ecc7913 j_mayer
524 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
525 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
526 8ecc7913 j_mayer
#endif
527 8ecc7913 j_mayer
    opba = opaque;
528 8ecc7913 j_mayer
    switch (addr - opba->base) {
529 8ecc7913 j_mayer
    case 0x00:
530 8ecc7913 j_mayer
        opba->cr = value & 0xF8;
531 8ecc7913 j_mayer
        break;
532 8ecc7913 j_mayer
    case 0x01:
533 8ecc7913 j_mayer
        opba->pr = value & 0xFF;
534 8ecc7913 j_mayer
        break;
535 8ecc7913 j_mayer
    default:
536 8ecc7913 j_mayer
        break;
537 8ecc7913 j_mayer
    }
538 8ecc7913 j_mayer
}
539 8ecc7913 j_mayer
540 8ecc7913 j_mayer
static uint32_t opba_readw (void *opaque, target_phys_addr_t addr)
541 8ecc7913 j_mayer
{
542 8ecc7913 j_mayer
    uint32_t ret;
543 8ecc7913 j_mayer
544 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
545 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
546 8ecc7913 j_mayer
#endif
547 8ecc7913 j_mayer
    ret = opba_readb(opaque, addr) << 8;
548 8ecc7913 j_mayer
    ret |= opba_readb(opaque, addr + 1);
549 8ecc7913 j_mayer
550 8ecc7913 j_mayer
    return ret;
551 8ecc7913 j_mayer
}
552 8ecc7913 j_mayer
553 8ecc7913 j_mayer
static void opba_writew (void *opaque,
554 8ecc7913 j_mayer
                         target_phys_addr_t addr, uint32_t value)
555 8ecc7913 j_mayer
{
556 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
557 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
558 8ecc7913 j_mayer
#endif
559 8ecc7913 j_mayer
    opba_writeb(opaque, addr, value >> 8);
560 8ecc7913 j_mayer
    opba_writeb(opaque, addr + 1, value);
561 8ecc7913 j_mayer
}
562 8ecc7913 j_mayer
563 8ecc7913 j_mayer
static uint32_t opba_readl (void *opaque, target_phys_addr_t addr)
564 8ecc7913 j_mayer
{
565 8ecc7913 j_mayer
    uint32_t ret;
566 8ecc7913 j_mayer
567 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
568 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
569 8ecc7913 j_mayer
#endif
570 8ecc7913 j_mayer
    ret = opba_readb(opaque, addr) << 24;
571 8ecc7913 j_mayer
    ret |= opba_readb(opaque, addr + 1) << 16;
572 8ecc7913 j_mayer
573 8ecc7913 j_mayer
    return ret;
574 8ecc7913 j_mayer
}
575 8ecc7913 j_mayer
576 8ecc7913 j_mayer
static void opba_writel (void *opaque,
577 8ecc7913 j_mayer
                         target_phys_addr_t addr, uint32_t value)
578 8ecc7913 j_mayer
{
579 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
580 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
581 8ecc7913 j_mayer
#endif
582 8ecc7913 j_mayer
    opba_writeb(opaque, addr, value >> 24);
583 8ecc7913 j_mayer
    opba_writeb(opaque, addr + 1, value >> 16);
584 8ecc7913 j_mayer
}
585 8ecc7913 j_mayer
586 8ecc7913 j_mayer
static CPUReadMemoryFunc *opba_read[] = {
587 8ecc7913 j_mayer
    &opba_readb,
588 8ecc7913 j_mayer
    &opba_readw,
589 8ecc7913 j_mayer
    &opba_readl,
590 8ecc7913 j_mayer
};
591 8ecc7913 j_mayer
592 8ecc7913 j_mayer
static CPUWriteMemoryFunc *opba_write[] = {
593 8ecc7913 j_mayer
    &opba_writeb,
594 8ecc7913 j_mayer
    &opba_writew,
595 8ecc7913 j_mayer
    &opba_writel,
596 8ecc7913 j_mayer
};
597 8ecc7913 j_mayer
598 8ecc7913 j_mayer
static void ppc4xx_opba_reset (void *opaque)
599 8ecc7913 j_mayer
{
600 8ecc7913 j_mayer
    ppc4xx_opba_t *opba;
601 8ecc7913 j_mayer
602 8ecc7913 j_mayer
    opba = opaque;
603 8ecc7913 j_mayer
    opba->cr = 0x00; /* No dynamic priorities - park disabled */
604 8ecc7913 j_mayer
    opba->pr = 0x11;
605 8ecc7913 j_mayer
}
606 8ecc7913 j_mayer
607 9c02f1a2 j_mayer
void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,
608 9c02f1a2 j_mayer
                       target_phys_addr_t offset)
609 8ecc7913 j_mayer
{
610 8ecc7913 j_mayer
    ppc4xx_opba_t *opba;
611 8ecc7913 j_mayer
612 8ecc7913 j_mayer
    opba = qemu_mallocz(sizeof(ppc4xx_opba_t));
613 8ecc7913 j_mayer
    if (opba != NULL) {
614 9c02f1a2 j_mayer
        opba->base = offset;
615 8ecc7913 j_mayer
#ifdef DEBUG_OPBA
616 9c02f1a2 j_mayer
        printf("%s: offset=" PADDRX "\n", __func__, offset);
617 8ecc7913 j_mayer
#endif
618 8ecc7913 j_mayer
        ppc4xx_mmio_register(env, mmio, offset, 0x002,
619 8ecc7913 j_mayer
                             opba_read, opba_write, opba);
620 8ecc7913 j_mayer
        qemu_register_reset(ppc4xx_opba_reset, opba);
621 8ecc7913 j_mayer
        ppc4xx_opba_reset(opba);
622 8ecc7913 j_mayer
    }
623 8ecc7913 j_mayer
}
624 8ecc7913 j_mayer
625 8ecc7913 j_mayer
/*****************************************************************************/
626 8ecc7913 j_mayer
/* "Universal" Interrupt controller */
627 8ecc7913 j_mayer
enum {
628 8ecc7913 j_mayer
    DCR_UICSR  = 0x000,
629 8ecc7913 j_mayer
    DCR_UICSRS = 0x001,
630 8ecc7913 j_mayer
    DCR_UICER  = 0x002,
631 8ecc7913 j_mayer
    DCR_UICCR  = 0x003,
632 8ecc7913 j_mayer
    DCR_UICPR  = 0x004,
633 8ecc7913 j_mayer
    DCR_UICTR  = 0x005,
634 8ecc7913 j_mayer
    DCR_UICMSR = 0x006,
635 8ecc7913 j_mayer
    DCR_UICVR  = 0x007,
636 8ecc7913 j_mayer
    DCR_UICVCR = 0x008,
637 8ecc7913 j_mayer
    DCR_UICMAX = 0x009,
638 8ecc7913 j_mayer
};
639 8ecc7913 j_mayer
640 8ecc7913 j_mayer
#define UIC_MAX_IRQ 32
641 8ecc7913 j_mayer
typedef struct ppcuic_t ppcuic_t;
642 8ecc7913 j_mayer
struct ppcuic_t {
643 8ecc7913 j_mayer
    uint32_t dcr_base;
644 8ecc7913 j_mayer
    int use_vectors;
645 8ecc7913 j_mayer
    uint32_t uicsr;  /* Status register */
646 8ecc7913 j_mayer
    uint32_t uicer;  /* Enable register */
647 8ecc7913 j_mayer
    uint32_t uiccr;  /* Critical register */
648 8ecc7913 j_mayer
    uint32_t uicpr;  /* Polarity register */
649 8ecc7913 j_mayer
    uint32_t uictr;  /* Triggering register */
650 8ecc7913 j_mayer
    uint32_t uicvcr; /* Vector configuration register */
651 8ecc7913 j_mayer
    uint32_t uicvr;
652 8ecc7913 j_mayer
    qemu_irq *irqs;
653 8ecc7913 j_mayer
};
654 8ecc7913 j_mayer
655 8ecc7913 j_mayer
static void ppcuic_trigger_irq (ppcuic_t *uic)
656 8ecc7913 j_mayer
{
657 8ecc7913 j_mayer
    uint32_t ir, cr;
658 8ecc7913 j_mayer
    int start, end, inc, i;
659 8ecc7913 j_mayer
660 8ecc7913 j_mayer
    /* Trigger interrupt if any is pending */
661 8ecc7913 j_mayer
    ir = uic->uicsr & uic->uicer & (~uic->uiccr);
662 8ecc7913 j_mayer
    cr = uic->uicsr & uic->uicer & uic->uiccr;
663 8ecc7913 j_mayer
#ifdef DEBUG_UIC
664 8ecc7913 j_mayer
    if (loglevel & CPU_LOG_INT) {
665 8ecc7913 j_mayer
        fprintf(logfile, "%s: uicsr %08x uicer %08x uiccr %08x\n"
666 8ecc7913 j_mayer
                "   %08x ir %08x cr %08x\n", __func__,
667 8ecc7913 j_mayer
                uic->uicsr, uic->uicer, uic->uiccr,
668 8ecc7913 j_mayer
                uic->uicsr & uic->uicer, ir, cr);
669 8ecc7913 j_mayer
    }
670 8ecc7913 j_mayer
#endif
671 8ecc7913 j_mayer
    if (ir != 0x0000000) {
672 8ecc7913 j_mayer
#ifdef DEBUG_UIC
673 8ecc7913 j_mayer
        if (loglevel & CPU_LOG_INT) {
674 8ecc7913 j_mayer
            fprintf(logfile, "Raise UIC interrupt\n");
675 8ecc7913 j_mayer
        }
676 8ecc7913 j_mayer
#endif
677 8ecc7913 j_mayer
        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
678 8ecc7913 j_mayer
    } else {
679 8ecc7913 j_mayer
#ifdef DEBUG_UIC
680 8ecc7913 j_mayer
        if (loglevel & CPU_LOG_INT) {
681 8ecc7913 j_mayer
            fprintf(logfile, "Lower UIC interrupt\n");
682 8ecc7913 j_mayer
        }
683 8ecc7913 j_mayer
#endif
684 8ecc7913 j_mayer
        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
685 8ecc7913 j_mayer
    }
686 8ecc7913 j_mayer
    /* Trigger critical interrupt if any is pending and update vector */
687 8ecc7913 j_mayer
    if (cr != 0x0000000) {
688 8ecc7913 j_mayer
        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
689 8ecc7913 j_mayer
        if (uic->use_vectors) {
690 8ecc7913 j_mayer
            /* Compute critical IRQ vector */
691 8ecc7913 j_mayer
            if (uic->uicvcr & 1) {
692 8ecc7913 j_mayer
                start = 31;
693 8ecc7913 j_mayer
                end = 0;
694 8ecc7913 j_mayer
                inc = -1;
695 8ecc7913 j_mayer
            } else {
696 8ecc7913 j_mayer
                start = 0;
697 8ecc7913 j_mayer
                end = 31;
698 8ecc7913 j_mayer
                inc = 1;
699 8ecc7913 j_mayer
            }
700 8ecc7913 j_mayer
            uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
701 8ecc7913 j_mayer
            for (i = start; i <= end; i += inc) {
702 8ecc7913 j_mayer
                if (cr & (1 << i)) {
703 8ecc7913 j_mayer
                    uic->uicvr += (i - start) * 512 * inc;
704 8ecc7913 j_mayer
                    break;
705 8ecc7913 j_mayer
                }
706 8ecc7913 j_mayer
            }
707 8ecc7913 j_mayer
        }
708 8ecc7913 j_mayer
#ifdef DEBUG_UIC
709 8ecc7913 j_mayer
        if (loglevel & CPU_LOG_INT) {
710 8ecc7913 j_mayer
            fprintf(logfile, "Raise UIC critical interrupt - vector %08x\n",
711 8ecc7913 j_mayer
                    uic->uicvr);
712 8ecc7913 j_mayer
        }
713 8ecc7913 j_mayer
#endif
714 8ecc7913 j_mayer
    } else {
715 8ecc7913 j_mayer
#ifdef DEBUG_UIC
716 8ecc7913 j_mayer
        if (loglevel & CPU_LOG_INT) {
717 8ecc7913 j_mayer
            fprintf(logfile, "Lower UIC critical interrupt\n");
718 8ecc7913 j_mayer
        }
719 8ecc7913 j_mayer
#endif
720 8ecc7913 j_mayer
        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
721 8ecc7913 j_mayer
        uic->uicvr = 0x00000000;
722 8ecc7913 j_mayer
    }
723 8ecc7913 j_mayer
}
724 8ecc7913 j_mayer
725 8ecc7913 j_mayer
static void ppcuic_set_irq (void *opaque, int irq_num, int level)
726 8ecc7913 j_mayer
{
727 8ecc7913 j_mayer
    ppcuic_t *uic;
728 8ecc7913 j_mayer
    uint32_t mask, sr;
729 8ecc7913 j_mayer
730 8ecc7913 j_mayer
    uic = opaque;
731 8ecc7913 j_mayer
    mask = 1 << irq_num;
732 8ecc7913 j_mayer
#ifdef DEBUG_UIC
733 8ecc7913 j_mayer
    if (loglevel & CPU_LOG_INT) {
734 8ecc7913 j_mayer
        fprintf(logfile, "%s: irq %d level %d uicsr %08x mask %08x => %08x "
735 8ecc7913 j_mayer
                "%08x\n", __func__, irq_num, level,
736 8ecc7913 j_mayer
                uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
737 8ecc7913 j_mayer
    }
738 8ecc7913 j_mayer
#endif
739 8ecc7913 j_mayer
    if (irq_num < 0 || irq_num > 31)
740 8ecc7913 j_mayer
        return;
741 8ecc7913 j_mayer
    sr = uic->uicsr;
742 8ecc7913 j_mayer
    if (!(uic->uicpr & mask)) {
743 8ecc7913 j_mayer
        /* Negatively asserted IRQ */
744 8ecc7913 j_mayer
        level = level == 0 ? 1 : 0;
745 8ecc7913 j_mayer
    }
746 8ecc7913 j_mayer
    /* Update status register */
747 8ecc7913 j_mayer
    if (uic->uictr & mask) {
748 8ecc7913 j_mayer
        /* Edge sensitive interrupt */
749 8ecc7913 j_mayer
        if (level == 1)
750 8ecc7913 j_mayer
            uic->uicsr |= mask;
751 8ecc7913 j_mayer
    } else {
752 8ecc7913 j_mayer
        /* Level sensitive interrupt */
753 8ecc7913 j_mayer
        if (level == 1)
754 8ecc7913 j_mayer
            uic->uicsr |= mask;
755 8ecc7913 j_mayer
        else
756 8ecc7913 j_mayer
            uic->uicsr &= ~mask;
757 8ecc7913 j_mayer
    }
758 8ecc7913 j_mayer
#ifdef DEBUG_UIC
759 8ecc7913 j_mayer
    if (loglevel & CPU_LOG_INT) {
760 8ecc7913 j_mayer
        fprintf(logfile, "%s: irq %d level %d sr %08x => %08x\n", __func__,
761 8ecc7913 j_mayer
                irq_num, level, uic->uicsr, sr);
762 8ecc7913 j_mayer
    }
763 8ecc7913 j_mayer
#endif
764 8ecc7913 j_mayer
    if (sr != uic->uicsr)
765 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
766 8ecc7913 j_mayer
}
767 8ecc7913 j_mayer
768 8ecc7913 j_mayer
static target_ulong dcr_read_uic (void *opaque, int dcrn)
769 8ecc7913 j_mayer
{
770 8ecc7913 j_mayer
    ppcuic_t *uic;
771 8ecc7913 j_mayer
    target_ulong ret;
772 8ecc7913 j_mayer
773 8ecc7913 j_mayer
    uic = opaque;
774 8ecc7913 j_mayer
    dcrn -= uic->dcr_base;
775 8ecc7913 j_mayer
    switch (dcrn) {
776 8ecc7913 j_mayer
    case DCR_UICSR:
777 8ecc7913 j_mayer
    case DCR_UICSRS:
778 8ecc7913 j_mayer
        ret = uic->uicsr;
779 8ecc7913 j_mayer
        break;
780 8ecc7913 j_mayer
    case DCR_UICER:
781 8ecc7913 j_mayer
        ret = uic->uicer;
782 8ecc7913 j_mayer
        break;
783 8ecc7913 j_mayer
    case DCR_UICCR:
784 8ecc7913 j_mayer
        ret = uic->uiccr;
785 8ecc7913 j_mayer
        break;
786 8ecc7913 j_mayer
    case DCR_UICPR:
787 8ecc7913 j_mayer
        ret = uic->uicpr;
788 8ecc7913 j_mayer
        break;
789 8ecc7913 j_mayer
    case DCR_UICTR:
790 8ecc7913 j_mayer
        ret = uic->uictr;
791 8ecc7913 j_mayer
        break;
792 8ecc7913 j_mayer
    case DCR_UICMSR:
793 8ecc7913 j_mayer
        ret = uic->uicsr & uic->uicer;
794 8ecc7913 j_mayer
        break;
795 8ecc7913 j_mayer
    case DCR_UICVR:
796 8ecc7913 j_mayer
        if (!uic->use_vectors)
797 8ecc7913 j_mayer
            goto no_read;
798 8ecc7913 j_mayer
        ret = uic->uicvr;
799 8ecc7913 j_mayer
        break;
800 8ecc7913 j_mayer
    case DCR_UICVCR:
801 8ecc7913 j_mayer
        if (!uic->use_vectors)
802 8ecc7913 j_mayer
            goto no_read;
803 8ecc7913 j_mayer
        ret = uic->uicvcr;
804 8ecc7913 j_mayer
        break;
805 8ecc7913 j_mayer
    default:
806 8ecc7913 j_mayer
    no_read:
807 8ecc7913 j_mayer
        ret = 0x00000000;
808 8ecc7913 j_mayer
        break;
809 8ecc7913 j_mayer
    }
810 8ecc7913 j_mayer
811 8ecc7913 j_mayer
    return ret;
812 8ecc7913 j_mayer
}
813 8ecc7913 j_mayer
814 8ecc7913 j_mayer
static void dcr_write_uic (void *opaque, int dcrn, target_ulong val)
815 8ecc7913 j_mayer
{
816 8ecc7913 j_mayer
    ppcuic_t *uic;
817 8ecc7913 j_mayer
818 8ecc7913 j_mayer
    uic = opaque;
819 8ecc7913 j_mayer
    dcrn -= uic->dcr_base;
820 8ecc7913 j_mayer
#ifdef DEBUG_UIC
821 8ecc7913 j_mayer
    if (loglevel & CPU_LOG_INT) {
822 8ecc7913 j_mayer
        fprintf(logfile, "%s: dcr %d val " ADDRX "\n", __func__, dcrn, val);
823 8ecc7913 j_mayer
    }
824 8ecc7913 j_mayer
#endif
825 8ecc7913 j_mayer
    switch (dcrn) {
826 8ecc7913 j_mayer
    case DCR_UICSR:
827 8ecc7913 j_mayer
        uic->uicsr &= ~val;
828 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
829 8ecc7913 j_mayer
        break;
830 8ecc7913 j_mayer
    case DCR_UICSRS:
831 8ecc7913 j_mayer
        uic->uicsr |= val;
832 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
833 8ecc7913 j_mayer
        break;
834 8ecc7913 j_mayer
    case DCR_UICER:
835 8ecc7913 j_mayer
        uic->uicer = val;
836 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
837 8ecc7913 j_mayer
        break;
838 8ecc7913 j_mayer
    case DCR_UICCR:
839 8ecc7913 j_mayer
        uic->uiccr = val;
840 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
841 8ecc7913 j_mayer
        break;
842 8ecc7913 j_mayer
    case DCR_UICPR:
843 8ecc7913 j_mayer
        uic->uicpr = val;
844 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
845 8ecc7913 j_mayer
        break;
846 8ecc7913 j_mayer
    case DCR_UICTR:
847 8ecc7913 j_mayer
        uic->uictr = val;
848 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
849 8ecc7913 j_mayer
        break;
850 8ecc7913 j_mayer
    case DCR_UICMSR:
851 8ecc7913 j_mayer
        break;
852 8ecc7913 j_mayer
    case DCR_UICVR:
853 8ecc7913 j_mayer
        break;
854 8ecc7913 j_mayer
    case DCR_UICVCR:
855 8ecc7913 j_mayer
        uic->uicvcr = val & 0xFFFFFFFD;
856 8ecc7913 j_mayer
        ppcuic_trigger_irq(uic);
857 8ecc7913 j_mayer
        break;
858 8ecc7913 j_mayer
    }
859 8ecc7913 j_mayer
}
860 8ecc7913 j_mayer
861 8ecc7913 j_mayer
static void ppcuic_reset (void *opaque)
862 8ecc7913 j_mayer
{
863 8ecc7913 j_mayer
    ppcuic_t *uic;
864 8ecc7913 j_mayer
865 8ecc7913 j_mayer
    uic = opaque;
866 8ecc7913 j_mayer
    uic->uiccr = 0x00000000;
867 8ecc7913 j_mayer
    uic->uicer = 0x00000000;
868 8ecc7913 j_mayer
    uic->uicpr = 0x00000000;
869 8ecc7913 j_mayer
    uic->uicsr = 0x00000000;
870 8ecc7913 j_mayer
    uic->uictr = 0x00000000;
871 8ecc7913 j_mayer
    if (uic->use_vectors) {
872 8ecc7913 j_mayer
        uic->uicvcr = 0x00000000;
873 8ecc7913 j_mayer
        uic->uicvr = 0x0000000;
874 8ecc7913 j_mayer
    }
875 8ecc7913 j_mayer
}
876 8ecc7913 j_mayer
877 8ecc7913 j_mayer
qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
878 8ecc7913 j_mayer
                       uint32_t dcr_base, int has_ssr, int has_vr)
879 8ecc7913 j_mayer
{
880 8ecc7913 j_mayer
    ppcuic_t *uic;
881 8ecc7913 j_mayer
    int i;
882 8ecc7913 j_mayer
883 8ecc7913 j_mayer
    uic = qemu_mallocz(sizeof(ppcuic_t));
884 8ecc7913 j_mayer
    if (uic != NULL) {
885 8ecc7913 j_mayer
        uic->dcr_base = dcr_base;
886 8ecc7913 j_mayer
        uic->irqs = irqs;
887 8ecc7913 j_mayer
        if (has_vr)
888 8ecc7913 j_mayer
            uic->use_vectors = 1;
889 8ecc7913 j_mayer
        for (i = 0; i < DCR_UICMAX; i++) {
890 8ecc7913 j_mayer
            ppc_dcr_register(env, dcr_base + i, uic,
891 8ecc7913 j_mayer
                             &dcr_read_uic, &dcr_write_uic);
892 8ecc7913 j_mayer
        }
893 8ecc7913 j_mayer
        qemu_register_reset(ppcuic_reset, uic);
894 8ecc7913 j_mayer
        ppcuic_reset(uic);
895 8ecc7913 j_mayer
    }
896 8ecc7913 j_mayer
897 8ecc7913 j_mayer
    return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
898 8ecc7913 j_mayer
}
899 8ecc7913 j_mayer
900 8ecc7913 j_mayer
/*****************************************************************************/
901 8ecc7913 j_mayer
/* Code decompression controller */
902 8ecc7913 j_mayer
/* XXX: TODO */
903 8ecc7913 j_mayer
904 8ecc7913 j_mayer
/*****************************************************************************/
905 8ecc7913 j_mayer
/* SDRAM controller */
906 8ecc7913 j_mayer
typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
907 8ecc7913 j_mayer
struct ppc4xx_sdram_t {
908 8ecc7913 j_mayer
    uint32_t addr;
909 8ecc7913 j_mayer
    int nbanks;
910 71db710f blueswir1
    target_phys_addr_t ram_bases[4];
911 71db710f blueswir1
    target_phys_addr_t ram_sizes[4];
912 8ecc7913 j_mayer
    uint32_t besr0;
913 8ecc7913 j_mayer
    uint32_t besr1;
914 8ecc7913 j_mayer
    uint32_t bear;
915 8ecc7913 j_mayer
    uint32_t cfg;
916 8ecc7913 j_mayer
    uint32_t status;
917 8ecc7913 j_mayer
    uint32_t rtr;
918 8ecc7913 j_mayer
    uint32_t pmit;
919 8ecc7913 j_mayer
    uint32_t bcr[4];
920 8ecc7913 j_mayer
    uint32_t tr;
921 8ecc7913 j_mayer
    uint32_t ecccfg;
922 8ecc7913 j_mayer
    uint32_t eccesr;
923 8ecc7913 j_mayer
    qemu_irq irq;
924 8ecc7913 j_mayer
};
925 8ecc7913 j_mayer
926 8ecc7913 j_mayer
enum {
927 8ecc7913 j_mayer
    SDRAM0_CFGADDR = 0x010,
928 8ecc7913 j_mayer
    SDRAM0_CFGDATA = 0x011,
929 8ecc7913 j_mayer
};
930 8ecc7913 j_mayer
931 36081602 j_mayer
static uint32_t sdram_bcr (target_phys_addr_t ram_base,
932 36081602 j_mayer
                           target_phys_addr_t ram_size)
933 8ecc7913 j_mayer
{
934 8ecc7913 j_mayer
    uint32_t bcr;
935 8ecc7913 j_mayer
936 8ecc7913 j_mayer
    switch (ram_size) {
937 8ecc7913 j_mayer
    case (4 * 1024 * 1024):
938 8ecc7913 j_mayer
        bcr = 0x00000000;
939 8ecc7913 j_mayer
        break;
940 8ecc7913 j_mayer
    case (8 * 1024 * 1024):
941 8ecc7913 j_mayer
        bcr = 0x00020000;
942 8ecc7913 j_mayer
        break;
943 8ecc7913 j_mayer
    case (16 * 1024 * 1024):
944 8ecc7913 j_mayer
        bcr = 0x00040000;
945 8ecc7913 j_mayer
        break;
946 8ecc7913 j_mayer
    case (32 * 1024 * 1024):
947 8ecc7913 j_mayer
        bcr = 0x00060000;
948 8ecc7913 j_mayer
        break;
949 8ecc7913 j_mayer
    case (64 * 1024 * 1024):
950 8ecc7913 j_mayer
        bcr = 0x00080000;
951 8ecc7913 j_mayer
        break;
952 8ecc7913 j_mayer
    case (128 * 1024 * 1024):
953 8ecc7913 j_mayer
        bcr = 0x000A0000;
954 8ecc7913 j_mayer
        break;
955 8ecc7913 j_mayer
    case (256 * 1024 * 1024):
956 8ecc7913 j_mayer
        bcr = 0x000C0000;
957 8ecc7913 j_mayer
        break;
958 8ecc7913 j_mayer
    default:
959 be58fc7c j_mayer
        printf("%s: invalid RAM size " TARGET_FMT_plx "\n",
960 be58fc7c j_mayer
               __func__, ram_size);
961 8ecc7913 j_mayer
        return 0x00000000;
962 8ecc7913 j_mayer
    }
963 8ecc7913 j_mayer
    bcr |= ram_base & 0xFF800000;
964 8ecc7913 j_mayer
    bcr |= 1;
965 8ecc7913 j_mayer
966 8ecc7913 j_mayer
    return bcr;
967 8ecc7913 j_mayer
}
968 8ecc7913 j_mayer
969 71db710f blueswir1
static inline target_phys_addr_t sdram_base (uint32_t bcr)
970 8ecc7913 j_mayer
{
971 8ecc7913 j_mayer
    return bcr & 0xFF800000;
972 8ecc7913 j_mayer
}
973 8ecc7913 j_mayer
974 8ecc7913 j_mayer
static target_ulong sdram_size (uint32_t bcr)
975 8ecc7913 j_mayer
{
976 8ecc7913 j_mayer
    target_ulong size;
977 8ecc7913 j_mayer
    int sh;
978 8ecc7913 j_mayer
979 8ecc7913 j_mayer
    sh = (bcr >> 17) & 0x7;
980 8ecc7913 j_mayer
    if (sh == 7)
981 8ecc7913 j_mayer
        size = -1;
982 8ecc7913 j_mayer
    else
983 8ecc7913 j_mayer
        size = (4 * 1024 * 1024) << sh;
984 8ecc7913 j_mayer
985 8ecc7913 j_mayer
    return size;
986 8ecc7913 j_mayer
}
987 8ecc7913 j_mayer
988 8ecc7913 j_mayer
static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
989 8ecc7913 j_mayer
{
990 8ecc7913 j_mayer
    if (*bcrp & 0x00000001) {
991 8ecc7913 j_mayer
        /* Unmap RAM */
992 8ecc7913 j_mayer
#ifdef DEBUG_SDRAM
993 be58fc7c j_mayer
        printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
994 be58fc7c j_mayer
               __func__, sdram_base(*bcrp), sdram_size(*bcrp));
995 8ecc7913 j_mayer
#endif
996 8ecc7913 j_mayer
        cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
997 8ecc7913 j_mayer
                                     IO_MEM_UNASSIGNED);
998 8ecc7913 j_mayer
    }
999 8ecc7913 j_mayer
    *bcrp = bcr & 0xFFDEE001;
1000 8ecc7913 j_mayer
    if (enabled && (bcr & 0x00000001)) {
1001 8ecc7913 j_mayer
#ifdef DEBUG_SDRAM
1002 be58fc7c j_mayer
        printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
1003 be58fc7c j_mayer
               __func__, sdram_base(bcr), sdram_size(bcr));
1004 8ecc7913 j_mayer
#endif
1005 8ecc7913 j_mayer
        cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
1006 8ecc7913 j_mayer
                                     sdram_base(bcr) | IO_MEM_RAM);
1007 8ecc7913 j_mayer
    }
1008 8ecc7913 j_mayer
}
1009 8ecc7913 j_mayer
1010 8ecc7913 j_mayer
static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
1011 8ecc7913 j_mayer
{
1012 8ecc7913 j_mayer
    int i;
1013 8ecc7913 j_mayer
1014 8ecc7913 j_mayer
    for (i = 0; i < sdram->nbanks; i++) {
1015 8ecc7913 j_mayer
        if (sdram->ram_sizes[i] != 0) {
1016 8ecc7913 j_mayer
            sdram_set_bcr(&sdram->bcr[i],
1017 8ecc7913 j_mayer
                          sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
1018 8ecc7913 j_mayer
                          1);
1019 8ecc7913 j_mayer
        } else {
1020 8ecc7913 j_mayer
            sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
1021 8ecc7913 j_mayer
        }
1022 8ecc7913 j_mayer
    }
1023 8ecc7913 j_mayer
}
1024 8ecc7913 j_mayer
1025 8ecc7913 j_mayer
static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
1026 8ecc7913 j_mayer
{
1027 8ecc7913 j_mayer
    int i;
1028 8ecc7913 j_mayer
1029 8ecc7913 j_mayer
    for (i = 0; i < sdram->nbanks; i++) {
1030 04f20795 j_mayer
#ifdef DEBUG_SDRAM
1031 be58fc7c j_mayer
        printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
1032 be58fc7c j_mayer
               __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
1033 04f20795 j_mayer
#endif
1034 8ecc7913 j_mayer
        cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
1035 8ecc7913 j_mayer
                                     sdram_size(sdram->bcr[i]),
1036 8ecc7913 j_mayer
                                     IO_MEM_UNASSIGNED);
1037 8ecc7913 j_mayer
    }
1038 8ecc7913 j_mayer
}
1039 8ecc7913 j_mayer
1040 8ecc7913 j_mayer
static target_ulong dcr_read_sdram (void *opaque, int dcrn)
1041 8ecc7913 j_mayer
{
1042 8ecc7913 j_mayer
    ppc4xx_sdram_t *sdram;
1043 8ecc7913 j_mayer
    target_ulong ret;
1044 8ecc7913 j_mayer
1045 8ecc7913 j_mayer
    sdram = opaque;
1046 8ecc7913 j_mayer
    switch (dcrn) {
1047 8ecc7913 j_mayer
    case SDRAM0_CFGADDR:
1048 8ecc7913 j_mayer
        ret = sdram->addr;
1049 8ecc7913 j_mayer
        break;
1050 8ecc7913 j_mayer
    case SDRAM0_CFGDATA:
1051 8ecc7913 j_mayer
        switch (sdram->addr) {
1052 8ecc7913 j_mayer
        case 0x00: /* SDRAM_BESR0 */
1053 8ecc7913 j_mayer
            ret = sdram->besr0;
1054 8ecc7913 j_mayer
            break;
1055 8ecc7913 j_mayer
        case 0x08: /* SDRAM_BESR1 */
1056 8ecc7913 j_mayer
            ret = sdram->besr1;
1057 8ecc7913 j_mayer
            break;
1058 8ecc7913 j_mayer
        case 0x10: /* SDRAM_BEAR */
1059 8ecc7913 j_mayer
            ret = sdram->bear;
1060 8ecc7913 j_mayer
            break;
1061 8ecc7913 j_mayer
        case 0x20: /* SDRAM_CFG */
1062 8ecc7913 j_mayer
            ret = sdram->cfg;
1063 8ecc7913 j_mayer
            break;
1064 8ecc7913 j_mayer
        case 0x24: /* SDRAM_STATUS */
1065 8ecc7913 j_mayer
            ret = sdram->status;
1066 8ecc7913 j_mayer
            break;
1067 8ecc7913 j_mayer
        case 0x30: /* SDRAM_RTR */
1068 8ecc7913 j_mayer
            ret = sdram->rtr;
1069 8ecc7913 j_mayer
            break;
1070 8ecc7913 j_mayer
        case 0x34: /* SDRAM_PMIT */
1071 8ecc7913 j_mayer
            ret = sdram->pmit;
1072 8ecc7913 j_mayer
            break;
1073 8ecc7913 j_mayer
        case 0x40: /* SDRAM_B0CR */
1074 8ecc7913 j_mayer
            ret = sdram->bcr[0];
1075 8ecc7913 j_mayer
            break;
1076 8ecc7913 j_mayer
        case 0x44: /* SDRAM_B1CR */
1077 8ecc7913 j_mayer
            ret = sdram->bcr[1];
1078 8ecc7913 j_mayer
            break;
1079 8ecc7913 j_mayer
        case 0x48: /* SDRAM_B2CR */
1080 8ecc7913 j_mayer
            ret = sdram->bcr[2];
1081 8ecc7913 j_mayer
            break;
1082 8ecc7913 j_mayer
        case 0x4C: /* SDRAM_B3CR */
1083 8ecc7913 j_mayer
            ret = sdram->bcr[3];
1084 8ecc7913 j_mayer
            break;
1085 8ecc7913 j_mayer
        case 0x80: /* SDRAM_TR */
1086 8ecc7913 j_mayer
            ret = -1; /* ? */
1087 8ecc7913 j_mayer
            break;
1088 8ecc7913 j_mayer
        case 0x94: /* SDRAM_ECCCFG */
1089 8ecc7913 j_mayer
            ret = sdram->ecccfg;
1090 8ecc7913 j_mayer
            break;
1091 8ecc7913 j_mayer
        case 0x98: /* SDRAM_ECCESR */
1092 8ecc7913 j_mayer
            ret = sdram->eccesr;
1093 8ecc7913 j_mayer
            break;
1094 8ecc7913 j_mayer
        default: /* Error */
1095 8ecc7913 j_mayer
            ret = -1;
1096 8ecc7913 j_mayer
            break;
1097 8ecc7913 j_mayer
        }
1098 8ecc7913 j_mayer
        break;
1099 8ecc7913 j_mayer
    default:
1100 8ecc7913 j_mayer
        /* Avoid gcc warning */
1101 8ecc7913 j_mayer
        ret = 0x00000000;
1102 8ecc7913 j_mayer
        break;
1103 8ecc7913 j_mayer
    }
1104 8ecc7913 j_mayer
1105 8ecc7913 j_mayer
    return ret;
1106 8ecc7913 j_mayer
}
1107 8ecc7913 j_mayer
1108 8ecc7913 j_mayer
static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)
1109 8ecc7913 j_mayer
{
1110 8ecc7913 j_mayer
    ppc4xx_sdram_t *sdram;
1111 8ecc7913 j_mayer
1112 8ecc7913 j_mayer
    sdram = opaque;
1113 8ecc7913 j_mayer
    switch (dcrn) {
1114 8ecc7913 j_mayer
    case SDRAM0_CFGADDR:
1115 8ecc7913 j_mayer
        sdram->addr = val;
1116 8ecc7913 j_mayer
        break;
1117 8ecc7913 j_mayer
    case SDRAM0_CFGDATA:
1118 8ecc7913 j_mayer
        switch (sdram->addr) {
1119 8ecc7913 j_mayer
        case 0x00: /* SDRAM_BESR0 */
1120 8ecc7913 j_mayer
            sdram->besr0 &= ~val;
1121 8ecc7913 j_mayer
            break;
1122 8ecc7913 j_mayer
        case 0x08: /* SDRAM_BESR1 */
1123 8ecc7913 j_mayer
            sdram->besr1 &= ~val;
1124 8ecc7913 j_mayer
            break;
1125 8ecc7913 j_mayer
        case 0x10: /* SDRAM_BEAR */
1126 8ecc7913 j_mayer
            sdram->bear = val;
1127 8ecc7913 j_mayer
            break;
1128 8ecc7913 j_mayer
        case 0x20: /* SDRAM_CFG */
1129 8ecc7913 j_mayer
            val &= 0xFFE00000;
1130 8ecc7913 j_mayer
            if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
1131 8ecc7913 j_mayer
#ifdef DEBUG_SDRAM
1132 8ecc7913 j_mayer
                printf("%s: enable SDRAM controller\n", __func__);
1133 8ecc7913 j_mayer
#endif
1134 8ecc7913 j_mayer
                /* validate all RAM mappings */
1135 8ecc7913 j_mayer
                sdram_map_bcr(sdram);
1136 8ecc7913 j_mayer
                sdram->status &= ~0x80000000;
1137 8ecc7913 j_mayer
            } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
1138 8ecc7913 j_mayer
#ifdef DEBUG_SDRAM
1139 8ecc7913 j_mayer
                printf("%s: disable SDRAM controller\n", __func__);
1140 8ecc7913 j_mayer
#endif
1141 8ecc7913 j_mayer
                /* invalidate all RAM mappings */
1142 8ecc7913 j_mayer
                sdram_unmap_bcr(sdram);
1143 8ecc7913 j_mayer
                sdram->status |= 0x80000000;
1144 8ecc7913 j_mayer
            }
1145 8ecc7913 j_mayer
            if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
1146 8ecc7913 j_mayer
                sdram->status |= 0x40000000;
1147 8ecc7913 j_mayer
            else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
1148 8ecc7913 j_mayer
                sdram->status &= ~0x40000000;
1149 8ecc7913 j_mayer
            sdram->cfg = val;
1150 8ecc7913 j_mayer
            break;
1151 8ecc7913 j_mayer
        case 0x24: /* SDRAM_STATUS */
1152 8ecc7913 j_mayer
            /* Read-only register */
1153 8ecc7913 j_mayer
            break;
1154 8ecc7913 j_mayer
        case 0x30: /* SDRAM_RTR */
1155 8ecc7913 j_mayer
            sdram->rtr = val & 0x3FF80000;
1156 8ecc7913 j_mayer
            break;
1157 8ecc7913 j_mayer
        case 0x34: /* SDRAM_PMIT */
1158 8ecc7913 j_mayer
            sdram->pmit = (val & 0xF8000000) | 0x07C00000;
1159 8ecc7913 j_mayer
            break;
1160 8ecc7913 j_mayer
        case 0x40: /* SDRAM_B0CR */
1161 8ecc7913 j_mayer
            sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
1162 8ecc7913 j_mayer
            break;
1163 8ecc7913 j_mayer
        case 0x44: /* SDRAM_B1CR */
1164 8ecc7913 j_mayer
            sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
1165 8ecc7913 j_mayer
            break;
1166 8ecc7913 j_mayer
        case 0x48: /* SDRAM_B2CR */
1167 8ecc7913 j_mayer
            sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
1168 8ecc7913 j_mayer
            break;
1169 8ecc7913 j_mayer
        case 0x4C: /* SDRAM_B3CR */
1170 8ecc7913 j_mayer
            sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
1171 8ecc7913 j_mayer
            break;
1172 8ecc7913 j_mayer
        case 0x80: /* SDRAM_TR */
1173 8ecc7913 j_mayer
            sdram->tr = val & 0x018FC01F;
1174 8ecc7913 j_mayer
            break;
1175 8ecc7913 j_mayer
        case 0x94: /* SDRAM_ECCCFG */
1176 8ecc7913 j_mayer
            sdram->ecccfg = val & 0x00F00000;
1177 8ecc7913 j_mayer
            break;
1178 8ecc7913 j_mayer
        case 0x98: /* SDRAM_ECCESR */
1179 8ecc7913 j_mayer
            val &= 0xFFF0F000;
1180 8ecc7913 j_mayer
            if (sdram->eccesr == 0 && val != 0)
1181 8ecc7913 j_mayer
                qemu_irq_raise(sdram->irq);
1182 8ecc7913 j_mayer
            else if (sdram->eccesr != 0 && val == 0)
1183 8ecc7913 j_mayer
                qemu_irq_lower(sdram->irq);
1184 8ecc7913 j_mayer
            sdram->eccesr = val;
1185 8ecc7913 j_mayer
            break;
1186 8ecc7913 j_mayer
        default: /* Error */
1187 8ecc7913 j_mayer
            break;
1188 8ecc7913 j_mayer
        }
1189 8ecc7913 j_mayer
        break;
1190 8ecc7913 j_mayer
    }
1191 8ecc7913 j_mayer
}
1192 8ecc7913 j_mayer
1193 8ecc7913 j_mayer
static void sdram_reset (void *opaque)
1194 8ecc7913 j_mayer
{
1195 8ecc7913 j_mayer
    ppc4xx_sdram_t *sdram;
1196 8ecc7913 j_mayer
1197 8ecc7913 j_mayer
    sdram = opaque;
1198 8ecc7913 j_mayer
    sdram->addr = 0x00000000;
1199 8ecc7913 j_mayer
    sdram->bear = 0x00000000;
1200 8ecc7913 j_mayer
    sdram->besr0 = 0x00000000; /* No error */
1201 8ecc7913 j_mayer
    sdram->besr1 = 0x00000000; /* No error */
1202 8ecc7913 j_mayer
    sdram->cfg = 0x00000000;
1203 8ecc7913 j_mayer
    sdram->ecccfg = 0x00000000; /* No ECC */
1204 8ecc7913 j_mayer
    sdram->eccesr = 0x00000000; /* No error */
1205 8ecc7913 j_mayer
    sdram->pmit = 0x07C00000;
1206 8ecc7913 j_mayer
    sdram->rtr = 0x05F00000;
1207 8ecc7913 j_mayer
    sdram->tr = 0x00854009;
1208 8ecc7913 j_mayer
    /* We pre-initialize RAM banks */
1209 8ecc7913 j_mayer
    sdram->status = 0x00000000;
1210 8ecc7913 j_mayer
    sdram->cfg = 0x00800000;
1211 8ecc7913 j_mayer
    sdram_unmap_bcr(sdram);
1212 8ecc7913 j_mayer
}
1213 8ecc7913 j_mayer
1214 8ecc7913 j_mayer
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
1215 71db710f blueswir1
                        target_phys_addr_t *ram_bases,
1216 71db710f blueswir1
                        target_phys_addr_t *ram_sizes,
1217 04f20795 j_mayer
                        int do_init)
1218 8ecc7913 j_mayer
{
1219 8ecc7913 j_mayer
    ppc4xx_sdram_t *sdram;
1220 8ecc7913 j_mayer
1221 8ecc7913 j_mayer
    sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
1222 8ecc7913 j_mayer
    if (sdram != NULL) {
1223 8ecc7913 j_mayer
        sdram->irq = irq;
1224 8ecc7913 j_mayer
        sdram->nbanks = nbanks;
1225 71db710f blueswir1
        memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
1226 36081602 j_mayer
        memcpy(sdram->ram_bases, ram_bases,
1227 36081602 j_mayer
               nbanks * sizeof(target_phys_addr_t));
1228 71db710f blueswir1
        memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
1229 36081602 j_mayer
        memcpy(sdram->ram_sizes, ram_sizes,
1230 36081602 j_mayer
               nbanks * sizeof(target_phys_addr_t));
1231 8ecc7913 j_mayer
        sdram_reset(sdram);
1232 8ecc7913 j_mayer
        qemu_register_reset(&sdram_reset, sdram);
1233 8ecc7913 j_mayer
        ppc_dcr_register(env, SDRAM0_CFGADDR,
1234 8ecc7913 j_mayer
                         sdram, &dcr_read_sdram, &dcr_write_sdram);
1235 8ecc7913 j_mayer
        ppc_dcr_register(env, SDRAM0_CFGDATA,
1236 8ecc7913 j_mayer
                         sdram, &dcr_read_sdram, &dcr_write_sdram);
1237 04f20795 j_mayer
        if (do_init)
1238 04f20795 j_mayer
            sdram_map_bcr(sdram);
1239 8ecc7913 j_mayer
    }
1240 8ecc7913 j_mayer
}
1241 8ecc7913 j_mayer
1242 8ecc7913 j_mayer
/*****************************************************************************/
1243 8ecc7913 j_mayer
/* Peripheral controller */
1244 8ecc7913 j_mayer
typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
1245 8ecc7913 j_mayer
struct ppc4xx_ebc_t {
1246 8ecc7913 j_mayer
    uint32_t addr;
1247 8ecc7913 j_mayer
    uint32_t bcr[8];
1248 8ecc7913 j_mayer
    uint32_t bap[8];
1249 8ecc7913 j_mayer
    uint32_t bear;
1250 8ecc7913 j_mayer
    uint32_t besr0;
1251 8ecc7913 j_mayer
    uint32_t besr1;
1252 8ecc7913 j_mayer
    uint32_t cfg;
1253 8ecc7913 j_mayer
};
1254 8ecc7913 j_mayer
1255 8ecc7913 j_mayer
enum {
1256 8ecc7913 j_mayer
    EBC0_CFGADDR = 0x012,
1257 8ecc7913 j_mayer
    EBC0_CFGDATA = 0x013,
1258 8ecc7913 j_mayer
};
1259 8ecc7913 j_mayer
1260 8ecc7913 j_mayer
static target_ulong dcr_read_ebc (void *opaque, int dcrn)
1261 8ecc7913 j_mayer
{
1262 8ecc7913 j_mayer
    ppc4xx_ebc_t *ebc;
1263 8ecc7913 j_mayer
    target_ulong ret;
1264 8ecc7913 j_mayer
1265 8ecc7913 j_mayer
    ebc = opaque;
1266 8ecc7913 j_mayer
    switch (dcrn) {
1267 8ecc7913 j_mayer
    case EBC0_CFGADDR:
1268 8ecc7913 j_mayer
        ret = ebc->addr;
1269 8ecc7913 j_mayer
        break;
1270 8ecc7913 j_mayer
    case EBC0_CFGDATA:
1271 8ecc7913 j_mayer
        switch (ebc->addr) {
1272 8ecc7913 j_mayer
        case 0x00: /* B0CR */
1273 8ecc7913 j_mayer
            ret = ebc->bcr[0];
1274 8ecc7913 j_mayer
            break;
1275 8ecc7913 j_mayer
        case 0x01: /* B1CR */
1276 8ecc7913 j_mayer
            ret = ebc->bcr[1];
1277 8ecc7913 j_mayer
            break;
1278 8ecc7913 j_mayer
        case 0x02: /* B2CR */
1279 8ecc7913 j_mayer
            ret = ebc->bcr[2];
1280 8ecc7913 j_mayer
            break;
1281 8ecc7913 j_mayer
        case 0x03: /* B3CR */
1282 8ecc7913 j_mayer
            ret = ebc->bcr[3];
1283 8ecc7913 j_mayer
            break;
1284 8ecc7913 j_mayer
        case 0x04: /* B4CR */
1285 8ecc7913 j_mayer
            ret = ebc->bcr[4];
1286 8ecc7913 j_mayer
            break;
1287 8ecc7913 j_mayer
        case 0x05: /* B5CR */
1288 8ecc7913 j_mayer
            ret = ebc->bcr[5];
1289 8ecc7913 j_mayer
            break;
1290 8ecc7913 j_mayer
        case 0x06: /* B6CR */
1291 8ecc7913 j_mayer
            ret = ebc->bcr[6];
1292 8ecc7913 j_mayer
            break;
1293 8ecc7913 j_mayer
        case 0x07: /* B7CR */
1294 8ecc7913 j_mayer
            ret = ebc->bcr[7];
1295 8ecc7913 j_mayer
            break;
1296 8ecc7913 j_mayer
        case 0x10: /* B0AP */
1297 8ecc7913 j_mayer
            ret = ebc->bap[0];
1298 8ecc7913 j_mayer
            break;
1299 8ecc7913 j_mayer
        case 0x11: /* B1AP */
1300 8ecc7913 j_mayer
            ret = ebc->bap[1];
1301 8ecc7913 j_mayer
            break;
1302 8ecc7913 j_mayer
        case 0x12: /* B2AP */
1303 8ecc7913 j_mayer
            ret = ebc->bap[2];
1304 8ecc7913 j_mayer
            break;
1305 8ecc7913 j_mayer
        case 0x13: /* B3AP */
1306 8ecc7913 j_mayer
            ret = ebc->bap[3];
1307 8ecc7913 j_mayer
            break;
1308 8ecc7913 j_mayer
        case 0x14: /* B4AP */
1309 8ecc7913 j_mayer
            ret = ebc->bap[4];
1310 8ecc7913 j_mayer
            break;
1311 8ecc7913 j_mayer
        case 0x15: /* B5AP */
1312 8ecc7913 j_mayer
            ret = ebc->bap[5];
1313 8ecc7913 j_mayer
            break;
1314 8ecc7913 j_mayer
        case 0x16: /* B6AP */
1315 8ecc7913 j_mayer
            ret = ebc->bap[6];
1316 8ecc7913 j_mayer
            break;
1317 8ecc7913 j_mayer
        case 0x17: /* B7AP */
1318 8ecc7913 j_mayer
            ret = ebc->bap[7];
1319 8ecc7913 j_mayer
            break;
1320 8ecc7913 j_mayer
        case 0x20: /* BEAR */
1321 8ecc7913 j_mayer
            ret = ebc->bear;
1322 8ecc7913 j_mayer
            break;
1323 8ecc7913 j_mayer
        case 0x21: /* BESR0 */
1324 8ecc7913 j_mayer
            ret = ebc->besr0;
1325 8ecc7913 j_mayer
            break;
1326 8ecc7913 j_mayer
        case 0x22: /* BESR1 */
1327 8ecc7913 j_mayer
            ret = ebc->besr1;
1328 8ecc7913 j_mayer
            break;
1329 8ecc7913 j_mayer
        case 0x23: /* CFG */
1330 8ecc7913 j_mayer
            ret = ebc->cfg;
1331 8ecc7913 j_mayer
            break;
1332 8ecc7913 j_mayer
        default:
1333 8ecc7913 j_mayer
            ret = 0x00000000;
1334 8ecc7913 j_mayer
            break;
1335 8ecc7913 j_mayer
        }
1336 8ecc7913 j_mayer
    default:
1337 8ecc7913 j_mayer
        ret = 0x00000000;
1338 8ecc7913 j_mayer
        break;
1339 8ecc7913 j_mayer
    }
1340 8ecc7913 j_mayer
1341 8ecc7913 j_mayer
    return ret;
1342 8ecc7913 j_mayer
}
1343 8ecc7913 j_mayer
1344 8ecc7913 j_mayer
static void dcr_write_ebc (void *opaque, int dcrn, target_ulong val)
1345 8ecc7913 j_mayer
{
1346 8ecc7913 j_mayer
    ppc4xx_ebc_t *ebc;
1347 8ecc7913 j_mayer
1348 8ecc7913 j_mayer
    ebc = opaque;
1349 8ecc7913 j_mayer
    switch (dcrn) {
1350 8ecc7913 j_mayer
    case EBC0_CFGADDR:
1351 8ecc7913 j_mayer
        ebc->addr = val;
1352 8ecc7913 j_mayer
        break;
1353 8ecc7913 j_mayer
    case EBC0_CFGDATA:
1354 8ecc7913 j_mayer
        switch (ebc->addr) {
1355 8ecc7913 j_mayer
        case 0x00: /* B0CR */
1356 8ecc7913 j_mayer
            break;
1357 8ecc7913 j_mayer
        case 0x01: /* B1CR */
1358 8ecc7913 j_mayer
            break;
1359 8ecc7913 j_mayer
        case 0x02: /* B2CR */
1360 8ecc7913 j_mayer
            break;
1361 8ecc7913 j_mayer
        case 0x03: /* B3CR */
1362 8ecc7913 j_mayer
            break;
1363 8ecc7913 j_mayer
        case 0x04: /* B4CR */
1364 8ecc7913 j_mayer
            break;
1365 8ecc7913 j_mayer
        case 0x05: /* B5CR */
1366 8ecc7913 j_mayer
            break;
1367 8ecc7913 j_mayer
        case 0x06: /* B6CR */
1368 8ecc7913 j_mayer
            break;
1369 8ecc7913 j_mayer
        case 0x07: /* B7CR */
1370 8ecc7913 j_mayer
            break;
1371 8ecc7913 j_mayer
        case 0x10: /* B0AP */
1372 8ecc7913 j_mayer
            break;
1373 8ecc7913 j_mayer
        case 0x11: /* B1AP */
1374 8ecc7913 j_mayer
            break;
1375 8ecc7913 j_mayer
        case 0x12: /* B2AP */
1376 8ecc7913 j_mayer
            break;
1377 8ecc7913 j_mayer
        case 0x13: /* B3AP */
1378 8ecc7913 j_mayer
            break;
1379 8ecc7913 j_mayer
        case 0x14: /* B4AP */
1380 8ecc7913 j_mayer
            break;
1381 8ecc7913 j_mayer
        case 0x15: /* B5AP */
1382 8ecc7913 j_mayer
            break;
1383 8ecc7913 j_mayer
        case 0x16: /* B6AP */
1384 8ecc7913 j_mayer
            break;
1385 8ecc7913 j_mayer
        case 0x17: /* B7AP */
1386 8ecc7913 j_mayer
            break;
1387 8ecc7913 j_mayer
        case 0x20: /* BEAR */
1388 8ecc7913 j_mayer
            break;
1389 8ecc7913 j_mayer
        case 0x21: /* BESR0 */
1390 8ecc7913 j_mayer
            break;
1391 8ecc7913 j_mayer
        case 0x22: /* BESR1 */
1392 8ecc7913 j_mayer
            break;
1393 8ecc7913 j_mayer
        case 0x23: /* CFG */
1394 8ecc7913 j_mayer
            break;
1395 8ecc7913 j_mayer
        default:
1396 8ecc7913 j_mayer
            break;
1397 8ecc7913 j_mayer
        }
1398 8ecc7913 j_mayer
        break;
1399 8ecc7913 j_mayer
    default:
1400 8ecc7913 j_mayer
        break;
1401 8ecc7913 j_mayer
    }
1402 8ecc7913 j_mayer
}
1403 8ecc7913 j_mayer
1404 8ecc7913 j_mayer
static void ebc_reset (void *opaque)
1405 8ecc7913 j_mayer
{
1406 8ecc7913 j_mayer
    ppc4xx_ebc_t *ebc;
1407 8ecc7913 j_mayer
    int i;
1408 8ecc7913 j_mayer
1409 8ecc7913 j_mayer
    ebc = opaque;
1410 8ecc7913 j_mayer
    ebc->addr = 0x00000000;
1411 8ecc7913 j_mayer
    ebc->bap[0] = 0x7F8FFE80;
1412 8ecc7913 j_mayer
    ebc->bcr[0] = 0xFFE28000;
1413 8ecc7913 j_mayer
    for (i = 0; i < 8; i++) {
1414 8ecc7913 j_mayer
        ebc->bap[i] = 0x00000000;
1415 8ecc7913 j_mayer
        ebc->bcr[i] = 0x00000000;
1416 8ecc7913 j_mayer
    }
1417 8ecc7913 j_mayer
    ebc->besr0 = 0x00000000;
1418 8ecc7913 j_mayer
    ebc->besr1 = 0x00000000;
1419 9c02f1a2 j_mayer
    ebc->cfg = 0x80400000;
1420 8ecc7913 j_mayer
}
1421 8ecc7913 j_mayer
1422 8ecc7913 j_mayer
void ppc405_ebc_init (CPUState *env)
1423 8ecc7913 j_mayer
{
1424 8ecc7913 j_mayer
    ppc4xx_ebc_t *ebc;
1425 8ecc7913 j_mayer
1426 8ecc7913 j_mayer
    ebc = qemu_mallocz(sizeof(ppc4xx_ebc_t));
1427 8ecc7913 j_mayer
    if (ebc != NULL) {
1428 8ecc7913 j_mayer
        ebc_reset(ebc);
1429 8ecc7913 j_mayer
        qemu_register_reset(&ebc_reset, ebc);
1430 8ecc7913 j_mayer
        ppc_dcr_register(env, EBC0_CFGADDR,
1431 8ecc7913 j_mayer
                         ebc, &dcr_read_ebc, &dcr_write_ebc);
1432 8ecc7913 j_mayer
        ppc_dcr_register(env, EBC0_CFGDATA,
1433 8ecc7913 j_mayer
                         ebc, &dcr_read_ebc, &dcr_write_ebc);
1434 8ecc7913 j_mayer
    }
1435 8ecc7913 j_mayer
}
1436 8ecc7913 j_mayer
1437 8ecc7913 j_mayer
/*****************************************************************************/
1438 8ecc7913 j_mayer
/* DMA controller */
1439 8ecc7913 j_mayer
enum {
1440 8ecc7913 j_mayer
    DMA0_CR0 = 0x100,
1441 8ecc7913 j_mayer
    DMA0_CT0 = 0x101,
1442 8ecc7913 j_mayer
    DMA0_DA0 = 0x102,
1443 8ecc7913 j_mayer
    DMA0_SA0 = 0x103,
1444 8ecc7913 j_mayer
    DMA0_SG0 = 0x104,
1445 8ecc7913 j_mayer
    DMA0_CR1 = 0x108,
1446 8ecc7913 j_mayer
    DMA0_CT1 = 0x109,
1447 8ecc7913 j_mayer
    DMA0_DA1 = 0x10A,
1448 8ecc7913 j_mayer
    DMA0_SA1 = 0x10B,
1449 8ecc7913 j_mayer
    DMA0_SG1 = 0x10C,
1450 8ecc7913 j_mayer
    DMA0_CR2 = 0x110,
1451 8ecc7913 j_mayer
    DMA0_CT2 = 0x111,
1452 8ecc7913 j_mayer
    DMA0_DA2 = 0x112,
1453 8ecc7913 j_mayer
    DMA0_SA2 = 0x113,
1454 8ecc7913 j_mayer
    DMA0_SG2 = 0x114,
1455 8ecc7913 j_mayer
    DMA0_CR3 = 0x118,
1456 8ecc7913 j_mayer
    DMA0_CT3 = 0x119,
1457 8ecc7913 j_mayer
    DMA0_DA3 = 0x11A,
1458 8ecc7913 j_mayer
    DMA0_SA3 = 0x11B,
1459 8ecc7913 j_mayer
    DMA0_SG3 = 0x11C,
1460 8ecc7913 j_mayer
    DMA0_SR  = 0x120,
1461 8ecc7913 j_mayer
    DMA0_SGC = 0x123,
1462 8ecc7913 j_mayer
    DMA0_SLP = 0x125,
1463 8ecc7913 j_mayer
    DMA0_POL = 0x126,
1464 8ecc7913 j_mayer
};
1465 8ecc7913 j_mayer
1466 8ecc7913 j_mayer
typedef struct ppc405_dma_t ppc405_dma_t;
1467 8ecc7913 j_mayer
struct ppc405_dma_t {
1468 8ecc7913 j_mayer
    qemu_irq irqs[4];
1469 8ecc7913 j_mayer
    uint32_t cr[4];
1470 8ecc7913 j_mayer
    uint32_t ct[4];
1471 8ecc7913 j_mayer
    uint32_t da[4];
1472 8ecc7913 j_mayer
    uint32_t sa[4];
1473 8ecc7913 j_mayer
    uint32_t sg[4];
1474 8ecc7913 j_mayer
    uint32_t sr;
1475 8ecc7913 j_mayer
    uint32_t sgc;
1476 8ecc7913 j_mayer
    uint32_t slp;
1477 8ecc7913 j_mayer
    uint32_t pol;
1478 8ecc7913 j_mayer
};
1479 8ecc7913 j_mayer
1480 8ecc7913 j_mayer
static target_ulong dcr_read_dma (void *opaque, int dcrn)
1481 8ecc7913 j_mayer
{
1482 8ecc7913 j_mayer
    ppc405_dma_t *dma;
1483 8ecc7913 j_mayer
1484 8ecc7913 j_mayer
    dma = opaque;
1485 8ecc7913 j_mayer
1486 8ecc7913 j_mayer
    return 0;
1487 8ecc7913 j_mayer
}
1488 8ecc7913 j_mayer
1489 8ecc7913 j_mayer
static void dcr_write_dma (void *opaque, int dcrn, target_ulong val)
1490 8ecc7913 j_mayer
{
1491 8ecc7913 j_mayer
    ppc405_dma_t *dma;
1492 8ecc7913 j_mayer
1493 8ecc7913 j_mayer
    dma = opaque;
1494 8ecc7913 j_mayer
}
1495 8ecc7913 j_mayer
1496 8ecc7913 j_mayer
static void ppc405_dma_reset (void *opaque)
1497 8ecc7913 j_mayer
{
1498 8ecc7913 j_mayer
    ppc405_dma_t *dma;
1499 8ecc7913 j_mayer
    int i;
1500 8ecc7913 j_mayer
1501 8ecc7913 j_mayer
    dma = opaque;
1502 8ecc7913 j_mayer
    for (i = 0; i < 4; i++) {
1503 8ecc7913 j_mayer
        dma->cr[i] = 0x00000000;
1504 8ecc7913 j_mayer
        dma->ct[i] = 0x00000000;
1505 8ecc7913 j_mayer
        dma->da[i] = 0x00000000;
1506 8ecc7913 j_mayer
        dma->sa[i] = 0x00000000;
1507 8ecc7913 j_mayer
        dma->sg[i] = 0x00000000;
1508 8ecc7913 j_mayer
    }
1509 8ecc7913 j_mayer
    dma->sr = 0x00000000;
1510 8ecc7913 j_mayer
    dma->sgc = 0x00000000;
1511 8ecc7913 j_mayer
    dma->slp = 0x7C000000;
1512 8ecc7913 j_mayer
    dma->pol = 0x00000000;
1513 8ecc7913 j_mayer
}
1514 8ecc7913 j_mayer
1515 8ecc7913 j_mayer
void ppc405_dma_init (CPUState *env, qemu_irq irqs[4])
1516 8ecc7913 j_mayer
{
1517 8ecc7913 j_mayer
    ppc405_dma_t *dma;
1518 8ecc7913 j_mayer
1519 8ecc7913 j_mayer
    dma = qemu_mallocz(sizeof(ppc405_dma_t));
1520 8ecc7913 j_mayer
    if (dma != NULL) {
1521 8ecc7913 j_mayer
        memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq));
1522 8ecc7913 j_mayer
        ppc405_dma_reset(dma);
1523 8ecc7913 j_mayer
        qemu_register_reset(&ppc405_dma_reset, dma);
1524 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CR0,
1525 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1526 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CT0,
1527 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1528 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_DA0,
1529 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1530 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SA0,
1531 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1532 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SG0,
1533 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1534 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CR1,
1535 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1536 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CT1,
1537 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1538 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_DA1,
1539 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1540 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SA1,
1541 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1542 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SG1,
1543 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1544 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CR2,
1545 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1546 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CT2,
1547 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1548 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_DA2,
1549 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1550 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SA2,
1551 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1552 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SG2,
1553 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1554 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CR3,
1555 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1556 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_CT3,
1557 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1558 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_DA3,
1559 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1560 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SA3,
1561 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1562 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SG3,
1563 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1564 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SR,
1565 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1566 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SGC,
1567 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1568 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_SLP,
1569 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1570 8ecc7913 j_mayer
        ppc_dcr_register(env, DMA0_POL,
1571 8ecc7913 j_mayer
                         dma, &dcr_read_dma, &dcr_write_dma);
1572 8ecc7913 j_mayer
    }
1573 8ecc7913 j_mayer
}
1574 8ecc7913 j_mayer
1575 8ecc7913 j_mayer
/*****************************************************************************/
1576 8ecc7913 j_mayer
/* GPIO */
1577 8ecc7913 j_mayer
typedef struct ppc405_gpio_t ppc405_gpio_t;
1578 8ecc7913 j_mayer
struct ppc405_gpio_t {
1579 9c02f1a2 j_mayer
    target_phys_addr_t base;
1580 8ecc7913 j_mayer
    uint32_t or;
1581 8ecc7913 j_mayer
    uint32_t tcr;
1582 8ecc7913 j_mayer
    uint32_t osrh;
1583 8ecc7913 j_mayer
    uint32_t osrl;
1584 8ecc7913 j_mayer
    uint32_t tsrh;
1585 8ecc7913 j_mayer
    uint32_t tsrl;
1586 8ecc7913 j_mayer
    uint32_t odr;
1587 8ecc7913 j_mayer
    uint32_t ir;
1588 8ecc7913 j_mayer
    uint32_t rr1;
1589 8ecc7913 j_mayer
    uint32_t isr1h;
1590 8ecc7913 j_mayer
    uint32_t isr1l;
1591 8ecc7913 j_mayer
};
1592 8ecc7913 j_mayer
1593 8ecc7913 j_mayer
static uint32_t ppc405_gpio_readb (void *opaque, target_phys_addr_t addr)
1594 8ecc7913 j_mayer
{
1595 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1596 8ecc7913 j_mayer
1597 8ecc7913 j_mayer
    gpio = opaque;
1598 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1599 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
1600 8ecc7913 j_mayer
#endif
1601 8ecc7913 j_mayer
1602 8ecc7913 j_mayer
    return 0;
1603 8ecc7913 j_mayer
}
1604 8ecc7913 j_mayer
1605 8ecc7913 j_mayer
static void ppc405_gpio_writeb (void *opaque,
1606 8ecc7913 j_mayer
                                target_phys_addr_t addr, uint32_t value)
1607 8ecc7913 j_mayer
{
1608 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1609 8ecc7913 j_mayer
1610 8ecc7913 j_mayer
    gpio = opaque;
1611 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1612 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1613 8ecc7913 j_mayer
#endif
1614 8ecc7913 j_mayer
}
1615 8ecc7913 j_mayer
1616 8ecc7913 j_mayer
static uint32_t ppc405_gpio_readw (void *opaque, target_phys_addr_t addr)
1617 8ecc7913 j_mayer
{
1618 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1619 8ecc7913 j_mayer
1620 8ecc7913 j_mayer
    gpio = opaque;
1621 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1622 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
1623 8ecc7913 j_mayer
#endif
1624 8ecc7913 j_mayer
1625 8ecc7913 j_mayer
    return 0;
1626 8ecc7913 j_mayer
}
1627 8ecc7913 j_mayer
1628 8ecc7913 j_mayer
static void ppc405_gpio_writew (void *opaque,
1629 8ecc7913 j_mayer
                                target_phys_addr_t addr, uint32_t value)
1630 8ecc7913 j_mayer
{
1631 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1632 8ecc7913 j_mayer
1633 8ecc7913 j_mayer
    gpio = opaque;
1634 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1635 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1636 8ecc7913 j_mayer
#endif
1637 8ecc7913 j_mayer
}
1638 8ecc7913 j_mayer
1639 8ecc7913 j_mayer
static uint32_t ppc405_gpio_readl (void *opaque, target_phys_addr_t addr)
1640 8ecc7913 j_mayer
{
1641 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1642 8ecc7913 j_mayer
1643 8ecc7913 j_mayer
    gpio = opaque;
1644 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1645 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
1646 8ecc7913 j_mayer
#endif
1647 8ecc7913 j_mayer
1648 8ecc7913 j_mayer
    return 0;
1649 8ecc7913 j_mayer
}
1650 8ecc7913 j_mayer
1651 8ecc7913 j_mayer
static void ppc405_gpio_writel (void *opaque,
1652 8ecc7913 j_mayer
                                target_phys_addr_t addr, uint32_t value)
1653 8ecc7913 j_mayer
{
1654 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1655 8ecc7913 j_mayer
1656 8ecc7913 j_mayer
    gpio = opaque;
1657 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1658 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1659 8ecc7913 j_mayer
#endif
1660 8ecc7913 j_mayer
}
1661 8ecc7913 j_mayer
1662 8ecc7913 j_mayer
static CPUReadMemoryFunc *ppc405_gpio_read[] = {
1663 8ecc7913 j_mayer
    &ppc405_gpio_readb,
1664 8ecc7913 j_mayer
    &ppc405_gpio_readw,
1665 8ecc7913 j_mayer
    &ppc405_gpio_readl,
1666 8ecc7913 j_mayer
};
1667 8ecc7913 j_mayer
1668 8ecc7913 j_mayer
static CPUWriteMemoryFunc *ppc405_gpio_write[] = {
1669 8ecc7913 j_mayer
    &ppc405_gpio_writeb,
1670 8ecc7913 j_mayer
    &ppc405_gpio_writew,
1671 8ecc7913 j_mayer
    &ppc405_gpio_writel,
1672 8ecc7913 j_mayer
};
1673 8ecc7913 j_mayer
1674 8ecc7913 j_mayer
static void ppc405_gpio_reset (void *opaque)
1675 8ecc7913 j_mayer
{
1676 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1677 8ecc7913 j_mayer
1678 8ecc7913 j_mayer
    gpio = opaque;
1679 8ecc7913 j_mayer
}
1680 8ecc7913 j_mayer
1681 9c02f1a2 j_mayer
void ppc405_gpio_init (CPUState *env, ppc4xx_mmio_t *mmio,
1682 9c02f1a2 j_mayer
                       target_phys_addr_t offset)
1683 8ecc7913 j_mayer
{
1684 8ecc7913 j_mayer
    ppc405_gpio_t *gpio;
1685 8ecc7913 j_mayer
1686 8ecc7913 j_mayer
    gpio = qemu_mallocz(sizeof(ppc405_gpio_t));
1687 8ecc7913 j_mayer
    if (gpio != NULL) {
1688 9c02f1a2 j_mayer
        gpio->base = offset;
1689 8ecc7913 j_mayer
        ppc405_gpio_reset(gpio);
1690 8ecc7913 j_mayer
        qemu_register_reset(&ppc405_gpio_reset, gpio);
1691 8ecc7913 j_mayer
#ifdef DEBUG_GPIO
1692 9c02f1a2 j_mayer
        printf("%s: offset=" PADDRX "\n", __func__, offset);
1693 8ecc7913 j_mayer
#endif
1694 8ecc7913 j_mayer
        ppc4xx_mmio_register(env, mmio, offset, 0x038,
1695 8ecc7913 j_mayer
                             ppc405_gpio_read, ppc405_gpio_write, gpio);
1696 8ecc7913 j_mayer
    }
1697 8ecc7913 j_mayer
}
1698 8ecc7913 j_mayer
1699 8ecc7913 j_mayer
/*****************************************************************************/
1700 8ecc7913 j_mayer
/* Serial ports */
1701 8ecc7913 j_mayer
static CPUReadMemoryFunc *serial_mm_read[] = {
1702 8ecc7913 j_mayer
    &serial_mm_readb,
1703 8ecc7913 j_mayer
    &serial_mm_readw,
1704 8ecc7913 j_mayer
    &serial_mm_readl,
1705 8ecc7913 j_mayer
};
1706 8ecc7913 j_mayer
1707 8ecc7913 j_mayer
static CPUWriteMemoryFunc *serial_mm_write[] = {
1708 8ecc7913 j_mayer
    &serial_mm_writeb,
1709 8ecc7913 j_mayer
    &serial_mm_writew,
1710 8ecc7913 j_mayer
    &serial_mm_writel,
1711 8ecc7913 j_mayer
};
1712 8ecc7913 j_mayer
1713 8ecc7913 j_mayer
void ppc405_serial_init (CPUState *env, ppc4xx_mmio_t *mmio,
1714 9c02f1a2 j_mayer
                         target_phys_addr_t offset, qemu_irq irq,
1715 8ecc7913 j_mayer
                         CharDriverState *chr)
1716 8ecc7913 j_mayer
{
1717 8ecc7913 j_mayer
    void *serial;
1718 8ecc7913 j_mayer
1719 8ecc7913 j_mayer
#ifdef DEBUG_SERIAL
1720 9c02f1a2 j_mayer
    printf("%s: offset=" PADDRX "\n", __func__, offset);
1721 8ecc7913 j_mayer
#endif
1722 9c02f1a2 j_mayer
    serial = serial_mm_init(offset, 0, irq, chr, 0);
1723 8ecc7913 j_mayer
    ppc4xx_mmio_register(env, mmio, offset, 0x008,
1724 8ecc7913 j_mayer
                         serial_mm_read, serial_mm_write, serial);
1725 8ecc7913 j_mayer
}
1726 8ecc7913 j_mayer
1727 8ecc7913 j_mayer
/*****************************************************************************/
1728 8ecc7913 j_mayer
/* On Chip Memory */
1729 8ecc7913 j_mayer
enum {
1730 8ecc7913 j_mayer
    OCM0_ISARC   = 0x018,
1731 8ecc7913 j_mayer
    OCM0_ISACNTL = 0x019,
1732 8ecc7913 j_mayer
    OCM0_DSARC   = 0x01A,
1733 8ecc7913 j_mayer
    OCM0_DSACNTL = 0x01B,
1734 8ecc7913 j_mayer
};
1735 8ecc7913 j_mayer
1736 8ecc7913 j_mayer
typedef struct ppc405_ocm_t ppc405_ocm_t;
1737 8ecc7913 j_mayer
struct ppc405_ocm_t {
1738 8ecc7913 j_mayer
    target_ulong offset;
1739 8ecc7913 j_mayer
    uint32_t isarc;
1740 8ecc7913 j_mayer
    uint32_t isacntl;
1741 8ecc7913 j_mayer
    uint32_t dsarc;
1742 8ecc7913 j_mayer
    uint32_t dsacntl;
1743 8ecc7913 j_mayer
};
1744 8ecc7913 j_mayer
1745 8ecc7913 j_mayer
static void ocm_update_mappings (ppc405_ocm_t *ocm,
1746 8ecc7913 j_mayer
                                 uint32_t isarc, uint32_t isacntl,
1747 8ecc7913 j_mayer
                                 uint32_t dsarc, uint32_t dsacntl)
1748 8ecc7913 j_mayer
{
1749 8ecc7913 j_mayer
#ifdef DEBUG_OCM
1750 8ecc7913 j_mayer
    printf("OCM update ISA %08x %08x (%08x %08x) DSA %08x %08x (%08x %08x)\n",
1751 8ecc7913 j_mayer
           isarc, isacntl, dsarc, dsacntl,
1752 8ecc7913 j_mayer
           ocm->isarc, ocm->isacntl, ocm->dsarc, ocm->dsacntl);
1753 8ecc7913 j_mayer
#endif
1754 8ecc7913 j_mayer
    if (ocm->isarc != isarc ||
1755 8ecc7913 j_mayer
        (ocm->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
1756 8ecc7913 j_mayer
        if (ocm->isacntl & 0x80000000) {
1757 8ecc7913 j_mayer
            /* Unmap previously assigned memory region */
1758 8ecc7913 j_mayer
            printf("OCM unmap ISA %08x\n", ocm->isarc);
1759 8ecc7913 j_mayer
            cpu_register_physical_memory(ocm->isarc, 0x04000000,
1760 8ecc7913 j_mayer
                                         IO_MEM_UNASSIGNED);
1761 8ecc7913 j_mayer
        }
1762 8ecc7913 j_mayer
        if (isacntl & 0x80000000) {
1763 8ecc7913 j_mayer
            /* Map new instruction memory region */
1764 8ecc7913 j_mayer
#ifdef DEBUG_OCM
1765 8ecc7913 j_mayer
            printf("OCM map ISA %08x\n", isarc);
1766 8ecc7913 j_mayer
#endif
1767 8ecc7913 j_mayer
            cpu_register_physical_memory(isarc, 0x04000000,
1768 8ecc7913 j_mayer
                                         ocm->offset | IO_MEM_RAM);
1769 8ecc7913 j_mayer
        }
1770 8ecc7913 j_mayer
    }
1771 8ecc7913 j_mayer
    if (ocm->dsarc != dsarc ||
1772 8ecc7913 j_mayer
        (ocm->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
1773 8ecc7913 j_mayer
        if (ocm->dsacntl & 0x80000000) {
1774 8ecc7913 j_mayer
            /* Beware not to unmap the region we just mapped */
1775 8ecc7913 j_mayer
            if (!(isacntl & 0x80000000) || ocm->dsarc != isarc) {
1776 8ecc7913 j_mayer
                /* Unmap previously assigned memory region */
1777 8ecc7913 j_mayer
#ifdef DEBUG_OCM
1778 8ecc7913 j_mayer
                printf("OCM unmap DSA %08x\n", ocm->dsarc);
1779 8ecc7913 j_mayer
#endif
1780 8ecc7913 j_mayer
                cpu_register_physical_memory(ocm->dsarc, 0x04000000,
1781 8ecc7913 j_mayer
                                             IO_MEM_UNASSIGNED);
1782 8ecc7913 j_mayer
            }
1783 8ecc7913 j_mayer
        }
1784 8ecc7913 j_mayer
        if (dsacntl & 0x80000000) {
1785 8ecc7913 j_mayer
            /* Beware not to remap the region we just mapped */
1786 8ecc7913 j_mayer
            if (!(isacntl & 0x80000000) || dsarc != isarc) {
1787 8ecc7913 j_mayer
                /* Map new data memory region */
1788 8ecc7913 j_mayer
#ifdef DEBUG_OCM
1789 8ecc7913 j_mayer
                printf("OCM map DSA %08x\n", dsarc);
1790 8ecc7913 j_mayer
#endif
1791 8ecc7913 j_mayer
                cpu_register_physical_memory(dsarc, 0x04000000,
1792 8ecc7913 j_mayer
                                             ocm->offset | IO_MEM_RAM);
1793 8ecc7913 j_mayer
            }
1794 8ecc7913 j_mayer
        }
1795 8ecc7913 j_mayer
    }
1796 8ecc7913 j_mayer
}
1797 8ecc7913 j_mayer
1798 8ecc7913 j_mayer
static target_ulong dcr_read_ocm (void *opaque, int dcrn)
1799 8ecc7913 j_mayer
{
1800 8ecc7913 j_mayer
    ppc405_ocm_t *ocm;
1801 8ecc7913 j_mayer
    target_ulong ret;
1802 8ecc7913 j_mayer
1803 8ecc7913 j_mayer
    ocm = opaque;
1804 8ecc7913 j_mayer
    switch (dcrn) {
1805 8ecc7913 j_mayer
    case OCM0_ISARC:
1806 8ecc7913 j_mayer
        ret = ocm->isarc;
1807 8ecc7913 j_mayer
        break;
1808 8ecc7913 j_mayer
    case OCM0_ISACNTL:
1809 8ecc7913 j_mayer
        ret = ocm->isacntl;
1810 8ecc7913 j_mayer
        break;
1811 8ecc7913 j_mayer
    case OCM0_DSARC:
1812 8ecc7913 j_mayer
        ret = ocm->dsarc;
1813 8ecc7913 j_mayer
        break;
1814 8ecc7913 j_mayer
    case OCM0_DSACNTL:
1815 8ecc7913 j_mayer
        ret = ocm->dsacntl;
1816 8ecc7913 j_mayer
        break;
1817 8ecc7913 j_mayer
    default:
1818 8ecc7913 j_mayer
        ret = 0;
1819 8ecc7913 j_mayer
        break;
1820 8ecc7913 j_mayer
    }
1821 8ecc7913 j_mayer
1822 8ecc7913 j_mayer
    return ret;
1823 8ecc7913 j_mayer
}
1824 8ecc7913 j_mayer
1825 8ecc7913 j_mayer
static void dcr_write_ocm (void *opaque, int dcrn, target_ulong val)
1826 8ecc7913 j_mayer
{
1827 8ecc7913 j_mayer
    ppc405_ocm_t *ocm;
1828 8ecc7913 j_mayer
    uint32_t isarc, dsarc, isacntl, dsacntl;
1829 8ecc7913 j_mayer
1830 8ecc7913 j_mayer
    ocm = opaque;
1831 8ecc7913 j_mayer
    isarc = ocm->isarc;
1832 8ecc7913 j_mayer
    dsarc = ocm->dsarc;
1833 8ecc7913 j_mayer
    isacntl = ocm->isacntl;
1834 8ecc7913 j_mayer
    dsacntl = ocm->dsacntl;
1835 8ecc7913 j_mayer
    switch (dcrn) {
1836 8ecc7913 j_mayer
    case OCM0_ISARC:
1837 8ecc7913 j_mayer
        isarc = val & 0xFC000000;
1838 8ecc7913 j_mayer
        break;
1839 8ecc7913 j_mayer
    case OCM0_ISACNTL:
1840 8ecc7913 j_mayer
        isacntl = val & 0xC0000000;
1841 8ecc7913 j_mayer
        break;
1842 8ecc7913 j_mayer
    case OCM0_DSARC:
1843 8ecc7913 j_mayer
        isarc = val & 0xFC000000;
1844 8ecc7913 j_mayer
        break;
1845 8ecc7913 j_mayer
    case OCM0_DSACNTL:
1846 8ecc7913 j_mayer
        isacntl = val & 0xC0000000;
1847 8ecc7913 j_mayer
        break;
1848 8ecc7913 j_mayer
    }
1849 8ecc7913 j_mayer
    ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl);
1850 8ecc7913 j_mayer
    ocm->isarc = isarc;
1851 8ecc7913 j_mayer
    ocm->dsarc = dsarc;
1852 8ecc7913 j_mayer
    ocm->isacntl = isacntl;
1853 8ecc7913 j_mayer
    ocm->dsacntl = dsacntl;
1854 8ecc7913 j_mayer
}
1855 8ecc7913 j_mayer
1856 8ecc7913 j_mayer
static void ocm_reset (void *opaque)
1857 8ecc7913 j_mayer
{
1858 8ecc7913 j_mayer
    ppc405_ocm_t *ocm;
1859 8ecc7913 j_mayer
    uint32_t isarc, dsarc, isacntl, dsacntl;
1860 8ecc7913 j_mayer
1861 8ecc7913 j_mayer
    ocm = opaque;
1862 8ecc7913 j_mayer
    isarc = 0x00000000;
1863 8ecc7913 j_mayer
    isacntl = 0x00000000;
1864 8ecc7913 j_mayer
    dsarc = 0x00000000;
1865 8ecc7913 j_mayer
    dsacntl = 0x00000000;
1866 8ecc7913 j_mayer
    ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl);
1867 8ecc7913 j_mayer
    ocm->isarc = isarc;
1868 8ecc7913 j_mayer
    ocm->dsarc = dsarc;
1869 8ecc7913 j_mayer
    ocm->isacntl = isacntl;
1870 8ecc7913 j_mayer
    ocm->dsacntl = dsacntl;
1871 8ecc7913 j_mayer
}
1872 8ecc7913 j_mayer
1873 8ecc7913 j_mayer
void ppc405_ocm_init (CPUState *env, unsigned long offset)
1874 8ecc7913 j_mayer
{
1875 8ecc7913 j_mayer
    ppc405_ocm_t *ocm;
1876 8ecc7913 j_mayer
1877 8ecc7913 j_mayer
    ocm = qemu_mallocz(sizeof(ppc405_ocm_t));
1878 8ecc7913 j_mayer
    if (ocm != NULL) {
1879 8ecc7913 j_mayer
        ocm->offset = offset;
1880 8ecc7913 j_mayer
        ocm_reset(ocm);
1881 8ecc7913 j_mayer
        qemu_register_reset(&ocm_reset, ocm);
1882 8ecc7913 j_mayer
        ppc_dcr_register(env, OCM0_ISARC,
1883 8ecc7913 j_mayer
                         ocm, &dcr_read_ocm, &dcr_write_ocm);
1884 8ecc7913 j_mayer
        ppc_dcr_register(env, OCM0_ISACNTL,
1885 8ecc7913 j_mayer
                         ocm, &dcr_read_ocm, &dcr_write_ocm);
1886 8ecc7913 j_mayer
        ppc_dcr_register(env, OCM0_DSARC,
1887 8ecc7913 j_mayer
                         ocm, &dcr_read_ocm, &dcr_write_ocm);
1888 8ecc7913 j_mayer
        ppc_dcr_register(env, OCM0_DSACNTL,
1889 8ecc7913 j_mayer
                         ocm, &dcr_read_ocm, &dcr_write_ocm);
1890 8ecc7913 j_mayer
    }
1891 8ecc7913 j_mayer
}
1892 8ecc7913 j_mayer
1893 8ecc7913 j_mayer
/*****************************************************************************/
1894 8ecc7913 j_mayer
/* I2C controller */
1895 8ecc7913 j_mayer
typedef struct ppc4xx_i2c_t ppc4xx_i2c_t;
1896 8ecc7913 j_mayer
struct ppc4xx_i2c_t {
1897 9c02f1a2 j_mayer
    target_phys_addr_t base;
1898 9c02f1a2 j_mayer
    qemu_irq irq;
1899 8ecc7913 j_mayer
    uint8_t mdata;
1900 8ecc7913 j_mayer
    uint8_t lmadr;
1901 8ecc7913 j_mayer
    uint8_t hmadr;
1902 8ecc7913 j_mayer
    uint8_t cntl;
1903 8ecc7913 j_mayer
    uint8_t mdcntl;
1904 8ecc7913 j_mayer
    uint8_t sts;
1905 8ecc7913 j_mayer
    uint8_t extsts;
1906 8ecc7913 j_mayer
    uint8_t sdata;
1907 8ecc7913 j_mayer
    uint8_t lsadr;
1908 8ecc7913 j_mayer
    uint8_t hsadr;
1909 8ecc7913 j_mayer
    uint8_t clkdiv;
1910 8ecc7913 j_mayer
    uint8_t intrmsk;
1911 8ecc7913 j_mayer
    uint8_t xfrcnt;
1912 8ecc7913 j_mayer
    uint8_t xtcntlss;
1913 8ecc7913 j_mayer
    uint8_t directcntl;
1914 8ecc7913 j_mayer
};
1915 8ecc7913 j_mayer
1916 8ecc7913 j_mayer
static uint32_t ppc4xx_i2c_readb (void *opaque, target_phys_addr_t addr)
1917 8ecc7913 j_mayer
{
1918 8ecc7913 j_mayer
    ppc4xx_i2c_t *i2c;
1919 8ecc7913 j_mayer
    uint32_t ret;
1920 8ecc7913 j_mayer
1921 8ecc7913 j_mayer
#ifdef DEBUG_I2C
1922 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
1923 8ecc7913 j_mayer
#endif
1924 8ecc7913 j_mayer
    i2c = opaque;
1925 8ecc7913 j_mayer
    switch (addr - i2c->base) {
1926 8ecc7913 j_mayer
    case 0x00:
1927 8ecc7913 j_mayer
        //        i2c_readbyte(&i2c->mdata);
1928 8ecc7913 j_mayer
        ret = i2c->mdata;
1929 8ecc7913 j_mayer
        break;
1930 8ecc7913 j_mayer
    case 0x02:
1931 8ecc7913 j_mayer
        ret = i2c->sdata;
1932 8ecc7913 j_mayer
        break;
1933 8ecc7913 j_mayer
    case 0x04:
1934 8ecc7913 j_mayer
        ret = i2c->lmadr;
1935 8ecc7913 j_mayer
        break;
1936 8ecc7913 j_mayer
    case 0x05:
1937 8ecc7913 j_mayer
        ret = i2c->hmadr;
1938 8ecc7913 j_mayer
        break;
1939 8ecc7913 j_mayer
    case 0x06:
1940 8ecc7913 j_mayer
        ret = i2c->cntl;
1941 8ecc7913 j_mayer
        break;
1942 8ecc7913 j_mayer
    case 0x07:
1943 8ecc7913 j_mayer
        ret = i2c->mdcntl;
1944 8ecc7913 j_mayer
        break;
1945 8ecc7913 j_mayer
    case 0x08:
1946 8ecc7913 j_mayer
        ret = i2c->sts;
1947 8ecc7913 j_mayer
        break;
1948 8ecc7913 j_mayer
    case 0x09:
1949 8ecc7913 j_mayer
        ret = i2c->extsts;
1950 8ecc7913 j_mayer
        break;
1951 8ecc7913 j_mayer
    case 0x0A:
1952 8ecc7913 j_mayer
        ret = i2c->lsadr;
1953 8ecc7913 j_mayer
        break;
1954 8ecc7913 j_mayer
    case 0x0B:
1955 8ecc7913 j_mayer
        ret = i2c->hsadr;
1956 8ecc7913 j_mayer
        break;
1957 8ecc7913 j_mayer
    case 0x0C:
1958 8ecc7913 j_mayer
        ret = i2c->clkdiv;
1959 8ecc7913 j_mayer
        break;
1960 8ecc7913 j_mayer
    case 0x0D:
1961 8ecc7913 j_mayer
        ret = i2c->intrmsk;
1962 8ecc7913 j_mayer
        break;
1963 8ecc7913 j_mayer
    case 0x0E:
1964 8ecc7913 j_mayer
        ret = i2c->xfrcnt;
1965 8ecc7913 j_mayer
        break;
1966 8ecc7913 j_mayer
    case 0x0F:
1967 8ecc7913 j_mayer
        ret = i2c->xtcntlss;
1968 8ecc7913 j_mayer
        break;
1969 8ecc7913 j_mayer
    case 0x10:
1970 8ecc7913 j_mayer
        ret = i2c->directcntl;
1971 8ecc7913 j_mayer
        break;
1972 8ecc7913 j_mayer
    default:
1973 8ecc7913 j_mayer
        ret = 0x00;
1974 8ecc7913 j_mayer
        break;
1975 8ecc7913 j_mayer
    }
1976 8ecc7913 j_mayer
#ifdef DEBUG_I2C
1977 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " %02x\n", __func__, addr, ret);
1978 8ecc7913 j_mayer
#endif
1979 8ecc7913 j_mayer
1980 8ecc7913 j_mayer
    return ret;
1981 8ecc7913 j_mayer
}
1982 8ecc7913 j_mayer
1983 8ecc7913 j_mayer
static void ppc4xx_i2c_writeb (void *opaque,
1984 8ecc7913 j_mayer
                               target_phys_addr_t addr, uint32_t value)
1985 8ecc7913 j_mayer
{
1986 8ecc7913 j_mayer
    ppc4xx_i2c_t *i2c;
1987 8ecc7913 j_mayer
1988 8ecc7913 j_mayer
#ifdef DEBUG_I2C
1989 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1990 8ecc7913 j_mayer
#endif
1991 8ecc7913 j_mayer
    i2c = opaque;
1992 8ecc7913 j_mayer
    switch (addr - i2c->base) {
1993 8ecc7913 j_mayer
    case 0x00:
1994 8ecc7913 j_mayer
        i2c->mdata = value;
1995 8ecc7913 j_mayer
        //        i2c_sendbyte(&i2c->mdata);
1996 8ecc7913 j_mayer
        break;
1997 8ecc7913 j_mayer
    case 0x02:
1998 8ecc7913 j_mayer
        i2c->sdata = value;
1999 8ecc7913 j_mayer
        break;
2000 8ecc7913 j_mayer
    case 0x04:
2001 8ecc7913 j_mayer
        i2c->lmadr = value;
2002 8ecc7913 j_mayer
        break;
2003 8ecc7913 j_mayer
    case 0x05:
2004 8ecc7913 j_mayer
        i2c->hmadr = value;
2005 8ecc7913 j_mayer
        break;
2006 8ecc7913 j_mayer
    case 0x06:
2007 8ecc7913 j_mayer
        i2c->cntl = value;
2008 8ecc7913 j_mayer
        break;
2009 8ecc7913 j_mayer
    case 0x07:
2010 8ecc7913 j_mayer
        i2c->mdcntl = value & 0xDF;
2011 8ecc7913 j_mayer
        break;
2012 8ecc7913 j_mayer
    case 0x08:
2013 8ecc7913 j_mayer
        i2c->sts &= ~(value & 0x0A);
2014 8ecc7913 j_mayer
        break;
2015 8ecc7913 j_mayer
    case 0x09:
2016 8ecc7913 j_mayer
        i2c->extsts &= ~(value & 0x8F);
2017 8ecc7913 j_mayer
        break;
2018 8ecc7913 j_mayer
    case 0x0A:
2019 8ecc7913 j_mayer
        i2c->lsadr = value;
2020 8ecc7913 j_mayer
        break;
2021 8ecc7913 j_mayer
    case 0x0B:
2022 8ecc7913 j_mayer
        i2c->hsadr = value;
2023 8ecc7913 j_mayer
        break;
2024 8ecc7913 j_mayer
    case 0x0C:
2025 8ecc7913 j_mayer
        i2c->clkdiv = value;
2026 8ecc7913 j_mayer
        break;
2027 8ecc7913 j_mayer
    case 0x0D:
2028 8ecc7913 j_mayer
        i2c->intrmsk = value;
2029 8ecc7913 j_mayer
        break;
2030 8ecc7913 j_mayer
    case 0x0E:
2031 8ecc7913 j_mayer
        i2c->xfrcnt = value & 0x77;
2032 8ecc7913 j_mayer
        break;
2033 8ecc7913 j_mayer
    case 0x0F:
2034 8ecc7913 j_mayer
        i2c->xtcntlss = value;
2035 8ecc7913 j_mayer
        break;
2036 8ecc7913 j_mayer
    case 0x10:
2037 8ecc7913 j_mayer
        i2c->directcntl = value & 0x7;
2038 8ecc7913 j_mayer
        break;
2039 8ecc7913 j_mayer
    }
2040 8ecc7913 j_mayer
}
2041 8ecc7913 j_mayer
2042 8ecc7913 j_mayer
static uint32_t ppc4xx_i2c_readw (void *opaque, target_phys_addr_t addr)
2043 8ecc7913 j_mayer
{
2044 8ecc7913 j_mayer
    uint32_t ret;
2045 8ecc7913 j_mayer
2046 8ecc7913 j_mayer
#ifdef DEBUG_I2C
2047 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
2048 8ecc7913 j_mayer
#endif
2049 8ecc7913 j_mayer
    ret = ppc4xx_i2c_readb(opaque, addr) << 8;
2050 8ecc7913 j_mayer
    ret |= ppc4xx_i2c_readb(opaque, addr + 1);
2051 8ecc7913 j_mayer
2052 8ecc7913 j_mayer
    return ret;
2053 8ecc7913 j_mayer
}
2054 8ecc7913 j_mayer
2055 8ecc7913 j_mayer
static void ppc4xx_i2c_writew (void *opaque,
2056 8ecc7913 j_mayer
                               target_phys_addr_t addr, uint32_t value)
2057 8ecc7913 j_mayer
{
2058 8ecc7913 j_mayer
#ifdef DEBUG_I2C
2059 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
2060 8ecc7913 j_mayer
#endif
2061 8ecc7913 j_mayer
    ppc4xx_i2c_writeb(opaque, addr, value >> 8);
2062 8ecc7913 j_mayer
    ppc4xx_i2c_writeb(opaque, addr + 1, value);
2063 8ecc7913 j_mayer
}
2064 8ecc7913 j_mayer
2065 8ecc7913 j_mayer
static uint32_t ppc4xx_i2c_readl (void *opaque, target_phys_addr_t addr)
2066 8ecc7913 j_mayer
{
2067 8ecc7913 j_mayer
    uint32_t ret;
2068 8ecc7913 j_mayer
2069 8ecc7913 j_mayer
#ifdef DEBUG_I2C
2070 8ecc7913 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
2071 8ecc7913 j_mayer
#endif
2072 8ecc7913 j_mayer
    ret = ppc4xx_i2c_readb(opaque, addr) << 24;
2073 8ecc7913 j_mayer
    ret |= ppc4xx_i2c_readb(opaque, addr + 1) << 16;
2074 8ecc7913 j_mayer
    ret |= ppc4xx_i2c_readb(opaque, addr + 2) << 8;
2075 8ecc7913 j_mayer
    ret |= ppc4xx_i2c_readb(opaque, addr + 3);
2076 8ecc7913 j_mayer
2077 8ecc7913 j_mayer
    return ret;
2078 8ecc7913 j_mayer
}
2079 8ecc7913 j_mayer
2080 8ecc7913 j_mayer
static void ppc4xx_i2c_writel (void *opaque,
2081 8ecc7913 j_mayer
                               target_phys_addr_t addr, uint32_t value)
2082 8ecc7913 j_mayer
{
2083 8ecc7913 j_mayer
#ifdef DEBUG_I2C
2084 8ecc7913 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
2085 8ecc7913 j_mayer
#endif
2086 8ecc7913 j_mayer
    ppc4xx_i2c_writeb(opaque, addr, value >> 24);
2087 8ecc7913 j_mayer
    ppc4xx_i2c_writeb(opaque, addr + 1, value >> 16);
2088 8ecc7913 j_mayer
    ppc4xx_i2c_writeb(opaque, addr + 2, value >> 8);
2089 8ecc7913 j_mayer
    ppc4xx_i2c_writeb(opaque, addr + 3, value);
2090 8ecc7913 j_mayer
}
2091 8ecc7913 j_mayer
2092 8ecc7913 j_mayer
static CPUReadMemoryFunc *i2c_read[] = {
2093 8ecc7913 j_mayer
    &ppc4xx_i2c_readb,
2094 8ecc7913 j_mayer
    &ppc4xx_i2c_readw,
2095 8ecc7913 j_mayer
    &ppc4xx_i2c_readl,
2096 8ecc7913 j_mayer
};
2097 8ecc7913 j_mayer
2098 8ecc7913 j_mayer
static CPUWriteMemoryFunc *i2c_write[] = {
2099 8ecc7913 j_mayer
    &ppc4xx_i2c_writeb,
2100 8ecc7913 j_mayer
    &ppc4xx_i2c_writew,
2101 8ecc7913 j_mayer
    &ppc4xx_i2c_writel,
2102 8ecc7913 j_mayer
};
2103 8ecc7913 j_mayer
2104 8ecc7913 j_mayer
static void ppc4xx_i2c_reset (void *opaque)
2105 8ecc7913 j_mayer
{
2106 8ecc7913 j_mayer
    ppc4xx_i2c_t *i2c;
2107 8ecc7913 j_mayer
2108 8ecc7913 j_mayer
    i2c = opaque;
2109 8ecc7913 j_mayer
    i2c->mdata = 0x00;
2110 8ecc7913 j_mayer
    i2c->sdata = 0x00;
2111 8ecc7913 j_mayer
    i2c->cntl = 0x00;
2112 8ecc7913 j_mayer
    i2c->mdcntl = 0x00;
2113 8ecc7913 j_mayer
    i2c->sts = 0x00;
2114 8ecc7913 j_mayer
    i2c->extsts = 0x00;
2115 8ecc7913 j_mayer
    i2c->clkdiv = 0x00;
2116 8ecc7913 j_mayer
    i2c->xfrcnt = 0x00;
2117 8ecc7913 j_mayer
    i2c->directcntl = 0x0F;
2118 8ecc7913 j_mayer
}
2119 8ecc7913 j_mayer
2120 9c02f1a2 j_mayer
void ppc405_i2c_init (CPUState *env, ppc4xx_mmio_t *mmio,
2121 9c02f1a2 j_mayer
                      target_phys_addr_t offset, qemu_irq irq)
2122 8ecc7913 j_mayer
{
2123 8ecc7913 j_mayer
    ppc4xx_i2c_t *i2c;
2124 8ecc7913 j_mayer
2125 8ecc7913 j_mayer
    i2c = qemu_mallocz(sizeof(ppc4xx_i2c_t));
2126 8ecc7913 j_mayer
    if (i2c != NULL) {
2127 9c02f1a2 j_mayer
        i2c->base = offset;
2128 9c02f1a2 j_mayer
        i2c->irq = irq;
2129 8ecc7913 j_mayer
        ppc4xx_i2c_reset(i2c);
2130 8ecc7913 j_mayer
#ifdef DEBUG_I2C
2131 9c02f1a2 j_mayer
        printf("%s: offset=" PADDRX "\n", __func__, offset);
2132 8ecc7913 j_mayer
#endif
2133 8ecc7913 j_mayer
        ppc4xx_mmio_register(env, mmio, offset, 0x011,
2134 8ecc7913 j_mayer
                             i2c_read, i2c_write, i2c);
2135 8ecc7913 j_mayer
        qemu_register_reset(ppc4xx_i2c_reset, i2c);
2136 8ecc7913 j_mayer
    }
2137 8ecc7913 j_mayer
}
2138 8ecc7913 j_mayer
2139 8ecc7913 j_mayer
/*****************************************************************************/
2140 9c02f1a2 j_mayer
/* General purpose timers */
2141 9c02f1a2 j_mayer
typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;
2142 9c02f1a2 j_mayer
struct ppc4xx_gpt_t {
2143 9c02f1a2 j_mayer
    target_phys_addr_t base;
2144 9c02f1a2 j_mayer
    int64_t tb_offset;
2145 9c02f1a2 j_mayer
    uint32_t tb_freq;
2146 9c02f1a2 j_mayer
    struct QEMUTimer *timer;
2147 9c02f1a2 j_mayer
    qemu_irq irqs[5];
2148 9c02f1a2 j_mayer
    uint32_t oe;
2149 9c02f1a2 j_mayer
    uint32_t ol;
2150 9c02f1a2 j_mayer
    uint32_t im;
2151 9c02f1a2 j_mayer
    uint32_t is;
2152 9c02f1a2 j_mayer
    uint32_t ie;
2153 9c02f1a2 j_mayer
    uint32_t comp[5];
2154 9c02f1a2 j_mayer
    uint32_t mask[5];
2155 9c02f1a2 j_mayer
};
2156 9c02f1a2 j_mayer
2157 9c02f1a2 j_mayer
static uint32_t ppc4xx_gpt_readb (void *opaque, target_phys_addr_t addr)
2158 9c02f1a2 j_mayer
{
2159 9c02f1a2 j_mayer
#ifdef DEBUG_GPT
2160 9c02f1a2 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
2161 9c02f1a2 j_mayer
#endif
2162 9c02f1a2 j_mayer
    /* XXX: generate a bus fault */
2163 9c02f1a2 j_mayer
    return -1;
2164 9c02f1a2 j_mayer
}
2165 9c02f1a2 j_mayer
2166 9c02f1a2 j_mayer
static void ppc4xx_gpt_writeb (void *opaque,
2167 9c02f1a2 j_mayer
                               target_phys_addr_t addr, uint32_t value)
2168 9c02f1a2 j_mayer
{
2169 9c02f1a2 j_mayer
#ifdef DEBUG_I2C
2170 9c02f1a2 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
2171 9c02f1a2 j_mayer
#endif
2172 9c02f1a2 j_mayer
    /* XXX: generate a bus fault */
2173 9c02f1a2 j_mayer
}
2174 9c02f1a2 j_mayer
2175 9c02f1a2 j_mayer
static uint32_t ppc4xx_gpt_readw (void *opaque, target_phys_addr_t addr)
2176 9c02f1a2 j_mayer
{
2177 9c02f1a2 j_mayer
#ifdef DEBUG_GPT
2178 9c02f1a2 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
2179 9c02f1a2 j_mayer
#endif
2180 9c02f1a2 j_mayer
    /* XXX: generate a bus fault */
2181 9c02f1a2 j_mayer
    return -1;
2182 9c02f1a2 j_mayer
}
2183 9c02f1a2 j_mayer
2184 9c02f1a2 j_mayer
static void ppc4xx_gpt_writew (void *opaque,
2185 9c02f1a2 j_mayer
                               target_phys_addr_t addr, uint32_t value)
2186 9c02f1a2 j_mayer
{
2187 9c02f1a2 j_mayer
#ifdef DEBUG_I2C
2188 9c02f1a2 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
2189 9c02f1a2 j_mayer
#endif
2190 9c02f1a2 j_mayer
    /* XXX: generate a bus fault */
2191 9c02f1a2 j_mayer
}
2192 9c02f1a2 j_mayer
2193 9c02f1a2 j_mayer
static int ppc4xx_gpt_compare (ppc4xx_gpt_t *gpt, int n)
2194 9c02f1a2 j_mayer
{
2195 9c02f1a2 j_mayer
    /* XXX: TODO */
2196 9c02f1a2 j_mayer
    return 0;
2197 9c02f1a2 j_mayer
}
2198 9c02f1a2 j_mayer
2199 9c02f1a2 j_mayer
static void ppc4xx_gpt_set_output (ppc4xx_gpt_t *gpt, int n, int level)
2200 9c02f1a2 j_mayer
{
2201 9c02f1a2 j_mayer
    /* XXX: TODO */
2202 9c02f1a2 j_mayer
}
2203 9c02f1a2 j_mayer
2204 9c02f1a2 j_mayer
static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt)
2205 9c02f1a2 j_mayer
{
2206 9c02f1a2 j_mayer
    uint32_t mask;
2207 9c02f1a2 j_mayer
    int i;
2208 9c02f1a2 j_mayer
2209 9c02f1a2 j_mayer
    mask = 0x80000000;
2210 9c02f1a2 j_mayer
    for (i = 0; i < 5; i++) {
2211 9c02f1a2 j_mayer
        if (gpt->oe & mask) {
2212 9c02f1a2 j_mayer
            /* Output is enabled */
2213 9c02f1a2 j_mayer
            if (ppc4xx_gpt_compare(gpt, i)) {
2214 9c02f1a2 j_mayer
                /* Comparison is OK */
2215 9c02f1a2 j_mayer
                ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask);
2216 9c02f1a2 j_mayer
            } else {
2217 9c02f1a2 j_mayer
                /* Comparison is KO */
2218 9c02f1a2 j_mayer
                ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask ? 0 : 1);
2219 9c02f1a2 j_mayer
            }
2220 9c02f1a2 j_mayer
        }
2221 9c02f1a2 j_mayer
        mask = mask >> 1;
2222 9c02f1a2 j_mayer
    }
2223 9c02f1a2 j_mayer
}
2224 9c02f1a2 j_mayer
2225 9c02f1a2 j_mayer
static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
2226 9c02f1a2 j_mayer
{
2227 9c02f1a2 j_mayer
    uint32_t mask;
2228 9c02f1a2 j_mayer
    int i;
2229 9c02f1a2 j_mayer
2230 9c02f1a2 j_mayer
    mask = 0x00008000;
2231 9c02f1a2 j_mayer
    for (i = 0; i < 5; i++) {
2232 9c02f1a2 j_mayer
        if (gpt->is & gpt->im & mask)
2233 9c02f1a2 j_mayer
            qemu_irq_raise(gpt->irqs[i]);
2234 9c02f1a2 j_mayer
        else
2235 9c02f1a2 j_mayer
            qemu_irq_lower(gpt->irqs[i]);
2236 9c02f1a2 j_mayer
        mask = mask >> 1;
2237 9c02f1a2 j_mayer
    }
2238 9c02f1a2 j_mayer
}
2239 9c02f1a2 j_mayer
2240 9c02f1a2 j_mayer
static void ppc4xx_gpt_compute_timer (ppc4xx_gpt_t *gpt)
2241 9c02f1a2 j_mayer
{
2242 9c02f1a2 j_mayer
    /* XXX: TODO */
2243 9c02f1a2 j_mayer
}
2244 9c02f1a2 j_mayer
2245 9c02f1a2 j_mayer
static uint32_t ppc4xx_gpt_readl (void *opaque, target_phys_addr_t addr)
2246 9c02f1a2 j_mayer
{
2247 9c02f1a2 j_mayer
    ppc4xx_gpt_t *gpt;
2248 9c02f1a2 j_mayer
    uint32_t ret;
2249 9c02f1a2 j_mayer
    int idx;
2250 9c02f1a2 j_mayer
2251 9c02f1a2 j_mayer
#ifdef DEBUG_GPT
2252 9c02f1a2 j_mayer
    printf("%s: addr " PADDRX "\n", __func__, addr);
2253 9c02f1a2 j_mayer
#endif
2254 9c02f1a2 j_mayer
    gpt = opaque;
2255 9c02f1a2 j_mayer
    switch (addr - gpt->base) {
2256 9c02f1a2 j_mayer
    case 0x00:
2257 9c02f1a2 j_mayer
        /* Time base counter */
2258 9c02f1a2 j_mayer
        ret = muldiv64(qemu_get_clock(vm_clock) + gpt->tb_offset,
2259 9c02f1a2 j_mayer
                       gpt->tb_freq, ticks_per_sec);
2260 9c02f1a2 j_mayer
        break;
2261 9c02f1a2 j_mayer
    case 0x10:
2262 9c02f1a2 j_mayer
        /* Output enable */
2263 9c02f1a2 j_mayer
        ret = gpt->oe;
2264 9c02f1a2 j_mayer
        break;
2265 9c02f1a2 j_mayer
    case 0x14:
2266 9c02f1a2 j_mayer
        /* Output level */
2267 9c02f1a2 j_mayer
        ret = gpt->ol;
2268 9c02f1a2 j_mayer
        break;
2269 9c02f1a2 j_mayer
    case 0x18:
2270 9c02f1a2 j_mayer
        /* Interrupt mask */
2271 9c02f1a2 j_mayer
        ret = gpt->im;
2272 9c02f1a2 j_mayer
        break;
2273 9c02f1a2 j_mayer
    case 0x1C:
2274 9c02f1a2 j_mayer
    case 0x20:
2275 9c02f1a2 j_mayer
        /* Interrupt status */
2276 9c02f1a2 j_mayer
        ret = gpt->is;
2277 9c02f1a2 j_mayer
        break;
2278 9c02f1a2 j_mayer
    case 0x24:
2279 9c02f1a2 j_mayer
        /* Interrupt enable */
2280 9c02f1a2 j_mayer
        ret = gpt->ie;
2281 9c02f1a2 j_mayer
        break;
2282 9c02f1a2 j_mayer
    case 0x80 ... 0x90:
2283 9c02f1a2 j_mayer
        /* Compare timer */
2284 9c02f1a2 j_mayer
        idx = ((addr - gpt->base) - 0x80) >> 2;
2285 9c02f1a2 j_mayer
        ret = gpt->comp[idx];
2286 9c02f1a2 j_mayer
        break;
2287 9c02f1a2 j_mayer
    case 0xC0 ... 0xD0:
2288 9c02f1a2 j_mayer
        /* Compare mask */
2289 9c02f1a2 j_mayer
        idx = ((addr - gpt->base) - 0xC0) >> 2;
2290 9c02f1a2 j_mayer
        ret = gpt->mask[idx];
2291 9c02f1a2 j_mayer
        break;
2292 9c02f1a2 j_mayer
    default:
2293 9c02f1a2 j_mayer
        ret = -1;
2294 9c02f1a2 j_mayer
        break;
2295 9c02f1a2 j_mayer
    }
2296 9c02f1a2 j_mayer
2297 9c02f1a2 j_mayer
    return ret;
2298 9c02f1a2 j_mayer
}
2299 9c02f1a2 j_mayer
2300 9c02f1a2 j_mayer
static void ppc4xx_gpt_writel (void *opaque,
2301 9c02f1a2 j_mayer
                               target_phys_addr_t addr, uint32_t value)
2302 9c02f1a2 j_mayer
{
2303 9c02f1a2 j_mayer
    ppc4xx_gpt_t *gpt;
2304 9c02f1a2 j_mayer
    int idx;
2305 9c02f1a2 j_mayer
2306 9c02f1a2 j_mayer
#ifdef DEBUG_I2C
2307 9c02f1a2 j_mayer
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
2308 9c02f1a2 j_mayer
#endif
2309 9c02f1a2 j_mayer
    gpt = opaque;
2310 9c02f1a2 j_mayer
    switch (addr - gpt->base) {
2311 9c02f1a2 j_mayer
    case 0x00:
2312 9c02f1a2 j_mayer
        /* Time base counter */
2313 9c02f1a2 j_mayer
        gpt->tb_offset = muldiv64(value, ticks_per_sec, gpt->tb_freq)
2314 9c02f1a2 j_mayer
            - qemu_get_clock(vm_clock);
2315 9c02f1a2 j_mayer
        ppc4xx_gpt_compute_timer(gpt);
2316 9c02f1a2 j_mayer
        break;
2317 9c02f1a2 j_mayer
    case 0x10:
2318 9c02f1a2 j_mayer
        /* Output enable */
2319 9c02f1a2 j_mayer
        gpt->oe = value & 0xF8000000;
2320 9c02f1a2 j_mayer
        ppc4xx_gpt_set_outputs(gpt);
2321 9c02f1a2 j_mayer
        break;
2322 9c02f1a2 j_mayer
    case 0x14:
2323 9c02f1a2 j_mayer
        /* Output level */
2324 9c02f1a2 j_mayer
        gpt->ol = value & 0xF8000000;
2325 9c02f1a2 j_mayer
        ppc4xx_gpt_set_outputs(gpt);
2326 9c02f1a2 j_mayer
        break;
2327 9c02f1a2 j_mayer
    case 0x18:
2328 9c02f1a2 j_mayer
        /* Interrupt mask */
2329 9c02f1a2 j_mayer
        gpt->im = value & 0x0000F800;
2330 9c02f1a2 j_mayer
        break;
2331 9c02f1a2 j_mayer
    case 0x1C:
2332 9c02f1a2 j_mayer
        /* Interrupt status set */
2333 9c02f1a2 j_mayer
        gpt->is |= value & 0x0000F800;
2334 9c02f1a2 j_mayer
        ppc4xx_gpt_set_irqs(gpt);
2335 9c02f1a2 j_mayer
        break;
2336 9c02f1a2 j_mayer
    case 0x20:
2337 9c02f1a2 j_mayer
        /* Interrupt status clear */
2338 9c02f1a2 j_mayer
        gpt->is &= ~(value & 0x0000F800);
2339 9c02f1a2 j_mayer
        ppc4xx_gpt_set_irqs(gpt);
2340 9c02f1a2 j_mayer
        break;
2341 9c02f1a2 j_mayer
    case 0x24:
2342 9c02f1a2 j_mayer
        /* Interrupt enable */
2343 9c02f1a2 j_mayer
        gpt->ie = value & 0x0000F800;
2344 9c02f1a2 j_mayer
        ppc4xx_gpt_set_irqs(gpt);
2345 9c02f1a2 j_mayer
        break;
2346 9c02f1a2 j_mayer
    case 0x80 ... 0x90:
2347 9c02f1a2 j_mayer
        /* Compare timer */
2348 9c02f1a2 j_mayer
        idx = ((addr - gpt->base) - 0x80) >> 2;
2349 9c02f1a2 j_mayer
        gpt->comp[idx] = value & 0xF8000000;
2350 9c02f1a2 j_mayer
        ppc4xx_gpt_compute_timer(gpt);
2351 9c02f1a2 j_mayer
        break;
2352 9c02f1a2 j_mayer
    case 0xC0 ... 0xD0:
2353 9c02f1a2 j_mayer
        /* Compare mask */
2354 9c02f1a2 j_mayer
        idx = ((addr - gpt->base) - 0xC0) >> 2;
2355 9c02f1a2 j_mayer
        gpt->mask[idx] = value & 0xF8000000;
2356 9c02f1a2 j_mayer
        ppc4xx_gpt_compute_timer(gpt);
2357 9c02f1a2 j_mayer
        break;
2358 9c02f1a2 j_mayer
    }
2359 9c02f1a2 j_mayer
}
2360 9c02f1a2 j_mayer
2361 9c02f1a2 j_mayer
static CPUReadMemoryFunc *gpt_read[] = {
2362 9c02f1a2 j_mayer
    &ppc4xx_gpt_readb,
2363 9c02f1a2 j_mayer
    &ppc4xx_gpt_readw,
2364 9c02f1a2 j_mayer
    &ppc4xx_gpt_readl,
2365 9c02f1a2 j_mayer
};
2366 9c02f1a2 j_mayer
2367 9c02f1a2 j_mayer
static CPUWriteMemoryFunc *gpt_write[] = {
2368 9c02f1a2 j_mayer
    &ppc4xx_gpt_writeb,
2369 9c02f1a2 j_mayer
    &ppc4xx_gpt_writew,
2370 9c02f1a2 j_mayer
    &ppc4xx_gpt_writel,
2371 9c02f1a2 j_mayer
};
2372 9c02f1a2 j_mayer
2373 9c02f1a2 j_mayer
static void ppc4xx_gpt_cb (void *opaque)
2374 9c02f1a2 j_mayer
{
2375 9c02f1a2 j_mayer
    ppc4xx_gpt_t *gpt;
2376 9c02f1a2 j_mayer
2377 9c02f1a2 j_mayer
    gpt = opaque;
2378 9c02f1a2 j_mayer
    ppc4xx_gpt_set_irqs(gpt);
2379 9c02f1a2 j_mayer
    ppc4xx_gpt_set_outputs(gpt);
2380 9c02f1a2 j_mayer
    ppc4xx_gpt_compute_timer(gpt);
2381 9c02f1a2 j_mayer
}
2382 9c02f1a2 j_mayer
2383 9c02f1a2 j_mayer
static void ppc4xx_gpt_reset (void *opaque)
2384 9c02f1a2 j_mayer
{
2385 9c02f1a2 j_mayer
    ppc4xx_gpt_t *gpt;
2386 9c02f1a2 j_mayer
    int i;
2387 9c02f1a2 j_mayer
2388 9c02f1a2 j_mayer
    gpt = opaque;
2389 9c02f1a2 j_mayer
    qemu_del_timer(gpt->timer);
2390 9c02f1a2 j_mayer
    gpt->oe = 0x00000000;
2391 9c02f1a2 j_mayer
    gpt->ol = 0x00000000;
2392 9c02f1a2 j_mayer
    gpt->im = 0x00000000;
2393 9c02f1a2 j_mayer
    gpt->is = 0x00000000;
2394 9c02f1a2 j_mayer
    gpt->ie = 0x00000000;
2395 9c02f1a2 j_mayer
    for (i = 0; i < 5; i++) {
2396 9c02f1a2 j_mayer
        gpt->comp[i] = 0x00000000;
2397 9c02f1a2 j_mayer
        gpt->mask[i] = 0x00000000;
2398 9c02f1a2 j_mayer
    }
2399 9c02f1a2 j_mayer
}
2400 9c02f1a2 j_mayer
2401 9c02f1a2 j_mayer
void ppc4xx_gpt_init (CPUState *env, ppc4xx_mmio_t *mmio,
2402 9c02f1a2 j_mayer
                      target_phys_addr_t offset, qemu_irq irqs[5])
2403 9c02f1a2 j_mayer
{
2404 9c02f1a2 j_mayer
    ppc4xx_gpt_t *gpt;
2405 9c02f1a2 j_mayer
    int i;
2406 9c02f1a2 j_mayer
2407 9c02f1a2 j_mayer
    gpt = qemu_mallocz(sizeof(ppc4xx_gpt_t));
2408 9c02f1a2 j_mayer
    if (gpt != NULL) {
2409 9c02f1a2 j_mayer
        gpt->base = offset;
2410 9c02f1a2 j_mayer
        for (i = 0; i < 5; i++)
2411 9c02f1a2 j_mayer
            gpt->irqs[i] = irqs[i];
2412 9c02f1a2 j_mayer
        gpt->timer = qemu_new_timer(vm_clock, &ppc4xx_gpt_cb, gpt);
2413 9c02f1a2 j_mayer
        ppc4xx_gpt_reset(gpt);
2414 9c02f1a2 j_mayer
#ifdef DEBUG_GPT
2415 9c02f1a2 j_mayer
        printf("%s: offset=" PADDRX "\n", __func__, offset);
2416 9c02f1a2 j_mayer
#endif
2417 9c02f1a2 j_mayer
        ppc4xx_mmio_register(env, mmio, offset, 0x0D4,
2418 9c02f1a2 j_mayer
                             gpt_read, gpt_write, gpt);
2419 9c02f1a2 j_mayer
        qemu_register_reset(ppc4xx_gpt_reset, gpt);
2420 9c02f1a2 j_mayer
    }
2421 9c02f1a2 j_mayer
}
2422 9c02f1a2 j_mayer
2423 9c02f1a2 j_mayer
/*****************************************************************************/
2424 9c02f1a2 j_mayer
/* MAL */
2425 9c02f1a2 j_mayer
enum {
2426 9c02f1a2 j_mayer
    MAL0_CFG      = 0x180,
2427 9c02f1a2 j_mayer
    MAL0_ESR      = 0x181,
2428 9c02f1a2 j_mayer
    MAL0_IER      = 0x182,
2429 9c02f1a2 j_mayer
    MAL0_TXCASR   = 0x184,
2430 9c02f1a2 j_mayer
    MAL0_TXCARR   = 0x185,
2431 9c02f1a2 j_mayer
    MAL0_TXEOBISR = 0x186,
2432 9c02f1a2 j_mayer
    MAL0_TXDEIR   = 0x187,
2433 9c02f1a2 j_mayer
    MAL0_RXCASR   = 0x190,
2434 9c02f1a2 j_mayer
    MAL0_RXCARR   = 0x191,
2435 9c02f1a2 j_mayer
    MAL0_RXEOBISR = 0x192,
2436 9c02f1a2 j_mayer
    MAL0_RXDEIR   = 0x193,
2437 9c02f1a2 j_mayer
    MAL0_TXCTP0R  = 0x1A0,
2438 9c02f1a2 j_mayer
    MAL0_TXCTP1R  = 0x1A1,
2439 9c02f1a2 j_mayer
    MAL0_TXCTP2R  = 0x1A2,
2440 9c02f1a2 j_mayer
    MAL0_TXCTP3R  = 0x1A3,
2441 9c02f1a2 j_mayer
    MAL0_RXCTP0R  = 0x1C0,
2442 9c02f1a2 j_mayer
    MAL0_RXCTP1R  = 0x1C1,
2443 9c02f1a2 j_mayer
    MAL0_RCBS0    = 0x1E0,
2444 9c02f1a2 j_mayer
    MAL0_RCBS1    = 0x1E1,
2445 9c02f1a2 j_mayer
};
2446 9c02f1a2 j_mayer
2447 9c02f1a2 j_mayer
typedef struct ppc40x_mal_t ppc40x_mal_t;
2448 9c02f1a2 j_mayer
struct ppc40x_mal_t {
2449 9c02f1a2 j_mayer
    qemu_irq irqs[4];
2450 9c02f1a2 j_mayer
    uint32_t cfg;
2451 9c02f1a2 j_mayer
    uint32_t esr;
2452 9c02f1a2 j_mayer
    uint32_t ier;
2453 9c02f1a2 j_mayer
    uint32_t txcasr;
2454 9c02f1a2 j_mayer
    uint32_t txcarr;
2455 9c02f1a2 j_mayer
    uint32_t txeobisr;
2456 9c02f1a2 j_mayer
    uint32_t txdeir;
2457 9c02f1a2 j_mayer
    uint32_t rxcasr;
2458 9c02f1a2 j_mayer
    uint32_t rxcarr;
2459 9c02f1a2 j_mayer
    uint32_t rxeobisr;
2460 9c02f1a2 j_mayer
    uint32_t rxdeir;
2461 9c02f1a2 j_mayer
    uint32_t txctpr[4];
2462 9c02f1a2 j_mayer
    uint32_t rxctpr[2];
2463 9c02f1a2 j_mayer
    uint32_t rcbs[2];
2464 9c02f1a2 j_mayer
};
2465 9c02f1a2 j_mayer
2466 9c02f1a2 j_mayer
static void ppc40x_mal_reset (void *opaque);
2467 9c02f1a2 j_mayer
2468 9c02f1a2 j_mayer
static target_ulong dcr_read_mal (void *opaque, int dcrn)
2469 9c02f1a2 j_mayer
{
2470 9c02f1a2 j_mayer
    ppc40x_mal_t *mal;
2471 9c02f1a2 j_mayer
    target_ulong ret;
2472 9c02f1a2 j_mayer
2473 9c02f1a2 j_mayer
    mal = opaque;
2474 9c02f1a2 j_mayer
    switch (dcrn) {
2475 9c02f1a2 j_mayer
    case MAL0_CFG:
2476 9c02f1a2 j_mayer
        ret = mal->cfg;
2477 9c02f1a2 j_mayer
        break;
2478 9c02f1a2 j_mayer
    case MAL0_ESR:
2479 9c02f1a2 j_mayer
        ret = mal->esr;
2480 9c02f1a2 j_mayer
        break;
2481 9c02f1a2 j_mayer
    case MAL0_IER:
2482 9c02f1a2 j_mayer
        ret = mal->ier;
2483 9c02f1a2 j_mayer
        break;
2484 9c02f1a2 j_mayer
    case MAL0_TXCASR:
2485 9c02f1a2 j_mayer
        ret = mal->txcasr;
2486 9c02f1a2 j_mayer
        break;
2487 9c02f1a2 j_mayer
    case MAL0_TXCARR:
2488 9c02f1a2 j_mayer
        ret = mal->txcarr;
2489 9c02f1a2 j_mayer
        break;
2490 9c02f1a2 j_mayer
    case MAL0_TXEOBISR:
2491 9c02f1a2 j_mayer
        ret = mal->txeobisr;
2492 9c02f1a2 j_mayer
        break;
2493 9c02f1a2 j_mayer
    case MAL0_TXDEIR:
2494 9c02f1a2 j_mayer
        ret = mal->txdeir;
2495 9c02f1a2 j_mayer
        break;
2496 9c02f1a2 j_mayer
    case MAL0_RXCASR:
2497 9c02f1a2 j_mayer
        ret = mal->rxcasr;
2498 9c02f1a2 j_mayer
        break;
2499 9c02f1a2 j_mayer
    case MAL0_RXCARR:
2500 9c02f1a2 j_mayer
        ret = mal->rxcarr;
2501 9c02f1a2 j_mayer
        break;
2502 9c02f1a2 j_mayer
    case MAL0_RXEOBISR:
2503 9c02f1a2 j_mayer
        ret = mal->rxeobisr;
2504 9c02f1a2 j_mayer
        break;
2505 9c02f1a2 j_mayer
    case MAL0_RXDEIR:
2506 9c02f1a2 j_mayer
        ret = mal->rxdeir;
2507 9c02f1a2 j_mayer
        break;
2508 9c02f1a2 j_mayer
    case MAL0_TXCTP0R:
2509 9c02f1a2 j_mayer
        ret = mal->txctpr[0];
2510 9c02f1a2 j_mayer
        break;
2511 9c02f1a2 j_mayer
    case MAL0_TXCTP1R:
2512 9c02f1a2 j_mayer
        ret = mal->txctpr[1];
2513 9c02f1a2 j_mayer
        break;
2514 9c02f1a2 j_mayer
    case MAL0_TXCTP2R:
2515 9c02f1a2 j_mayer
        ret = mal->txctpr[2];
2516 9c02f1a2 j_mayer
        break;
2517 9c02f1a2 j_mayer
    case MAL0_TXCTP3R:
2518 9c02f1a2 j_mayer
        ret = mal->txctpr[3];
2519 9c02f1a2 j_mayer
        break;
2520 9c02f1a2 j_mayer
    case MAL0_RXCTP0R:
2521 9c02f1a2 j_mayer
        ret = mal->rxctpr[0];
2522 9c02f1a2 j_mayer
        break;
2523 9c02f1a2 j_mayer
    case MAL0_RXCTP1R:
2524 9c02f1a2 j_mayer
        ret = mal->rxctpr[1];
2525 9c02f1a2 j_mayer
        break;
2526 9c02f1a2 j_mayer
    case MAL0_RCBS0:
2527 9c02f1a2 j_mayer
        ret = mal->rcbs[0];
2528 9c02f1a2 j_mayer
        break;
2529 9c02f1a2 j_mayer
    case MAL0_RCBS1:
2530 9c02f1a2 j_mayer
        ret = mal->rcbs[1];
2531 9c02f1a2 j_mayer
        break;
2532 9c02f1a2 j_mayer
    default:
2533 9c02f1a2 j_mayer
        ret = 0;
2534 9c02f1a2 j_mayer
        break;
2535 9c02f1a2 j_mayer
    }
2536 9c02f1a2 j_mayer
2537 9c02f1a2 j_mayer
    return ret;
2538 9c02f1a2 j_mayer
}
2539 9c02f1a2 j_mayer
2540 9c02f1a2 j_mayer
static void dcr_write_mal (void *opaque, int dcrn, target_ulong val)
2541 9c02f1a2 j_mayer
{
2542 9c02f1a2 j_mayer
    ppc40x_mal_t *mal;
2543 9c02f1a2 j_mayer
    int idx;
2544 9c02f1a2 j_mayer
2545 9c02f1a2 j_mayer
    mal = opaque;
2546 9c02f1a2 j_mayer
    switch (dcrn) {
2547 9c02f1a2 j_mayer
    case MAL0_CFG:
2548 9c02f1a2 j_mayer
        if (val & 0x80000000)
2549 9c02f1a2 j_mayer
            ppc40x_mal_reset(mal);
2550 9c02f1a2 j_mayer
        mal->cfg = val & 0x00FFC087;
2551 9c02f1a2 j_mayer
        break;
2552 9c02f1a2 j_mayer
    case MAL0_ESR:
2553 9c02f1a2 j_mayer
        /* Read/clear */
2554 9c02f1a2 j_mayer
        mal->esr &= ~val;
2555 9c02f1a2 j_mayer
        break;
2556 9c02f1a2 j_mayer
    case MAL0_IER:
2557 9c02f1a2 j_mayer
        mal->ier = val & 0x0000001F;
2558 9c02f1a2 j_mayer
        break;
2559 9c02f1a2 j_mayer
    case MAL0_TXCASR:
2560 9c02f1a2 j_mayer
        mal->txcasr = val & 0xF0000000;
2561 9c02f1a2 j_mayer
        break;
2562 9c02f1a2 j_mayer
    case MAL0_TXCARR:
2563 9c02f1a2 j_mayer
        mal->txcarr = val & 0xF0000000;
2564 9c02f1a2 j_mayer
        break;
2565 9c02f1a2 j_mayer
    case MAL0_TXEOBISR:
2566 9c02f1a2 j_mayer
        /* Read/clear */
2567 9c02f1a2 j_mayer
        mal->txeobisr &= ~val;
2568 9c02f1a2 j_mayer
        break;
2569 9c02f1a2 j_mayer
    case MAL0_TXDEIR:
2570 9c02f1a2 j_mayer
        /* Read/clear */
2571 9c02f1a2 j_mayer
        mal->txdeir &= ~val;
2572 9c02f1a2 j_mayer
        break;
2573 9c02f1a2 j_mayer
    case MAL0_RXCASR:
2574 9c02f1a2 j_mayer
        mal->rxcasr = val & 0xC0000000;
2575 9c02f1a2 j_mayer
        break;
2576 9c02f1a2 j_mayer
    case MAL0_RXCARR:
2577 9c02f1a2 j_mayer
        mal->rxcarr = val & 0xC0000000;
2578 9c02f1a2 j_mayer
        break;
2579 9c02f1a2 j_mayer
    case MAL0_RXEOBISR:
2580 9c02f1a2 j_mayer
        /* Read/clear */
2581 9c02f1a2 j_mayer
        mal->rxeobisr &= ~val;
2582 9c02f1a2 j_mayer
        break;
2583 9c02f1a2 j_mayer
    case MAL0_RXDEIR:
2584 9c02f1a2 j_mayer
        /* Read/clear */
2585 9c02f1a2 j_mayer
        mal->rxdeir &= ~val;
2586 9c02f1a2 j_mayer
        break;
2587 9c02f1a2 j_mayer
    case MAL0_TXCTP0R:
2588 9c02f1a2 j_mayer
        idx = 0;
2589 9c02f1a2 j_mayer
        goto update_tx_ptr;
2590 9c02f1a2 j_mayer
    case MAL0_TXCTP1R:
2591 9c02f1a2 j_mayer
        idx = 1;
2592 9c02f1a2 j_mayer
        goto update_tx_ptr;
2593 9c02f1a2 j_mayer
    case MAL0_TXCTP2R:
2594 9c02f1a2 j_mayer
        idx = 2;
2595 9c02f1a2 j_mayer
        goto update_tx_ptr;
2596 9c02f1a2 j_mayer
    case MAL0_TXCTP3R:
2597 9c02f1a2 j_mayer
        idx = 3;
2598 9c02f1a2 j_mayer
    update_tx_ptr:
2599 9c02f1a2 j_mayer
        mal->txctpr[idx] = val;
2600 9c02f1a2 j_mayer
        break;
2601 9c02f1a2 j_mayer
    case MAL0_RXCTP0R:
2602 9c02f1a2 j_mayer
        idx = 0;
2603 9c02f1a2 j_mayer
        goto update_rx_ptr;
2604 9c02f1a2 j_mayer
    case MAL0_RXCTP1R:
2605 9c02f1a2 j_mayer
        idx = 1;
2606 9c02f1a2 j_mayer
    update_rx_ptr:
2607 9c02f1a2 j_mayer
        mal->rxctpr[idx] = val;
2608 9c02f1a2 j_mayer
        break;
2609 9c02f1a2 j_mayer
    case MAL0_RCBS0:
2610 9c02f1a2 j_mayer
        idx = 0;
2611 9c02f1a2 j_mayer
        goto update_rx_size;
2612 9c02f1a2 j_mayer
    case MAL0_RCBS1:
2613 9c02f1a2 j_mayer
        idx = 1;
2614 9c02f1a2 j_mayer
    update_rx_size:
2615 9c02f1a2 j_mayer
        mal->rcbs[idx] = val & 0x000000FF;
2616 9c02f1a2 j_mayer
        break;
2617 9c02f1a2 j_mayer
    }
2618 9c02f1a2 j_mayer
}
2619 9c02f1a2 j_mayer
2620 9c02f1a2 j_mayer
static void ppc40x_mal_reset (void *opaque)
2621 9c02f1a2 j_mayer
{
2622 9c02f1a2 j_mayer
    ppc40x_mal_t *mal;
2623 9c02f1a2 j_mayer
2624 9c02f1a2 j_mayer
    mal = opaque;
2625 9c02f1a2 j_mayer
    mal->cfg = 0x0007C000;
2626 9c02f1a2 j_mayer
    mal->esr = 0x00000000;
2627 9c02f1a2 j_mayer
    mal->ier = 0x00000000;
2628 9c02f1a2 j_mayer
    mal->rxcasr = 0x00000000;
2629 9c02f1a2 j_mayer
    mal->rxdeir = 0x00000000;
2630 9c02f1a2 j_mayer
    mal->rxeobisr = 0x00000000;
2631 9c02f1a2 j_mayer
    mal->txcasr = 0x00000000;
2632 9c02f1a2 j_mayer
    mal->txdeir = 0x00000000;
2633 9c02f1a2 j_mayer
    mal->txeobisr = 0x00000000;
2634 9c02f1a2 j_mayer
}
2635 9c02f1a2 j_mayer
2636 9c02f1a2 j_mayer
void ppc405_mal_init (CPUState *env, qemu_irq irqs[4])
2637 9c02f1a2 j_mayer
{
2638 9c02f1a2 j_mayer
    ppc40x_mal_t *mal;
2639 9c02f1a2 j_mayer
    int i;
2640 9c02f1a2 j_mayer
2641 9c02f1a2 j_mayer
    mal = qemu_mallocz(sizeof(ppc40x_mal_t));
2642 9c02f1a2 j_mayer
    if (mal != NULL) {
2643 9c02f1a2 j_mayer
        for (i = 0; i < 4; i++)
2644 9c02f1a2 j_mayer
            mal->irqs[i] = irqs[i];
2645 9c02f1a2 j_mayer
        ppc40x_mal_reset(mal);
2646 9c02f1a2 j_mayer
        qemu_register_reset(&ppc40x_mal_reset, mal);
2647 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_CFG,
2648 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2649 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_ESR,
2650 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2651 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_IER,
2652 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2653 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXCASR,
2654 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2655 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXCARR,
2656 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2657 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXEOBISR,
2658 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2659 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXDEIR,
2660 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2661 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RXCASR,
2662 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2663 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RXCARR,
2664 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2665 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RXEOBISR,
2666 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2667 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RXDEIR,
2668 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2669 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXCTP0R,
2670 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2671 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXCTP1R,
2672 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2673 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXCTP2R,
2674 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2675 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_TXCTP3R,
2676 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2677 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RXCTP0R,
2678 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2679 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RXCTP1R,
2680 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2681 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RCBS0,
2682 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2683 9c02f1a2 j_mayer
        ppc_dcr_register(env, MAL0_RCBS1,
2684 9c02f1a2 j_mayer
                         mal, &dcr_read_mal, &dcr_write_mal);
2685 9c02f1a2 j_mayer
    }
2686 9c02f1a2 j_mayer
}
2687 9c02f1a2 j_mayer
2688 9c02f1a2 j_mayer
/*****************************************************************************/
2689 8ecc7913 j_mayer
/* SPR */
2690 8ecc7913 j_mayer
void ppc40x_core_reset (CPUState *env)
2691 8ecc7913 j_mayer
{
2692 8ecc7913 j_mayer
    target_ulong dbsr;
2693 8ecc7913 j_mayer
2694 8ecc7913 j_mayer
    printf("Reset PowerPC core\n");
2695 8ecc7913 j_mayer
    cpu_ppc_reset(env);
2696 8ecc7913 j_mayer
    dbsr = env->spr[SPR_40x_DBSR];
2697 8ecc7913 j_mayer
    dbsr &= ~0x00000300;
2698 8ecc7913 j_mayer
    dbsr |= 0x00000100;
2699 8ecc7913 j_mayer
    env->spr[SPR_40x_DBSR] = dbsr;
2700 8ecc7913 j_mayer
    cpu_loop_exit();
2701 8ecc7913 j_mayer
}
2702 8ecc7913 j_mayer
2703 8ecc7913 j_mayer
void ppc40x_chip_reset (CPUState *env)
2704 8ecc7913 j_mayer
{
2705 8ecc7913 j_mayer
    target_ulong dbsr;
2706 8ecc7913 j_mayer
2707 8ecc7913 j_mayer
    printf("Reset PowerPC chip\n");
2708 8ecc7913 j_mayer
    cpu_ppc_reset(env);
2709 8ecc7913 j_mayer
    /* XXX: TODO reset all internal peripherals */
2710 8ecc7913 j_mayer
    dbsr = env->spr[SPR_40x_DBSR];
2711 8ecc7913 j_mayer
    dbsr &= ~0x00000300;
2712 04f20795 j_mayer
    dbsr |= 0x00000200;
2713 8ecc7913 j_mayer
    env->spr[SPR_40x_DBSR] = dbsr;
2714 8ecc7913 j_mayer
    cpu_loop_exit();
2715 8ecc7913 j_mayer
}
2716 8ecc7913 j_mayer
2717 8ecc7913 j_mayer
void ppc40x_system_reset (CPUState *env)
2718 8ecc7913 j_mayer
{
2719 8ecc7913 j_mayer
    printf("Reset PowerPC system\n");
2720 8ecc7913 j_mayer
    qemu_system_reset_request();
2721 8ecc7913 j_mayer
}
2722 8ecc7913 j_mayer
2723 8ecc7913 j_mayer
void store_40x_dbcr0 (CPUState *env, uint32_t val)
2724 8ecc7913 j_mayer
{
2725 8ecc7913 j_mayer
    switch ((val >> 28) & 0x3) {
2726 8ecc7913 j_mayer
    case 0x0:
2727 8ecc7913 j_mayer
        /* No action */
2728 8ecc7913 j_mayer
        break;
2729 8ecc7913 j_mayer
    case 0x1:
2730 8ecc7913 j_mayer
        /* Core reset */
2731 8ecc7913 j_mayer
        ppc40x_core_reset(env);
2732 8ecc7913 j_mayer
        break;
2733 8ecc7913 j_mayer
    case 0x2:
2734 8ecc7913 j_mayer
        /* Chip reset */
2735 8ecc7913 j_mayer
        ppc40x_chip_reset(env);
2736 8ecc7913 j_mayer
        break;
2737 8ecc7913 j_mayer
    case 0x3:
2738 8ecc7913 j_mayer
        /* System reset */
2739 8ecc7913 j_mayer
        ppc40x_system_reset(env);
2740 8ecc7913 j_mayer
        break;
2741 8ecc7913 j_mayer
    }
2742 8ecc7913 j_mayer
}
2743 8ecc7913 j_mayer
2744 8ecc7913 j_mayer
/*****************************************************************************/
2745 8ecc7913 j_mayer
/* PowerPC 405CR */
2746 8ecc7913 j_mayer
enum {
2747 8ecc7913 j_mayer
    PPC405CR_CPC0_PLLMR  = 0x0B0,
2748 8ecc7913 j_mayer
    PPC405CR_CPC0_CR0    = 0x0B1,
2749 8ecc7913 j_mayer
    PPC405CR_CPC0_CR1    = 0x0B2,
2750 8ecc7913 j_mayer
    PPC405CR_CPC0_PSR    = 0x0B4,
2751 8ecc7913 j_mayer
    PPC405CR_CPC0_JTAGID = 0x0B5,
2752 8ecc7913 j_mayer
    PPC405CR_CPC0_ER     = 0x0B9,
2753 8ecc7913 j_mayer
    PPC405CR_CPC0_FR     = 0x0BA,
2754 8ecc7913 j_mayer
    PPC405CR_CPC0_SR     = 0x0BB,
2755 8ecc7913 j_mayer
};
2756 8ecc7913 j_mayer
2757 04f20795 j_mayer
enum {
2758 04f20795 j_mayer
    PPC405CR_CPU_CLK   = 0,
2759 04f20795 j_mayer
    PPC405CR_TMR_CLK   = 1,
2760 04f20795 j_mayer
    PPC405CR_PLB_CLK   = 2,
2761 04f20795 j_mayer
    PPC405CR_SDRAM_CLK = 3,
2762 04f20795 j_mayer
    PPC405CR_OPB_CLK   = 4,
2763 04f20795 j_mayer
    PPC405CR_EXT_CLK   = 5,
2764 04f20795 j_mayer
    PPC405CR_UART_CLK  = 6,
2765 04f20795 j_mayer
    PPC405CR_CLK_NB    = 7,
2766 04f20795 j_mayer
};
2767 04f20795 j_mayer
2768 8ecc7913 j_mayer
typedef struct ppc405cr_cpc_t ppc405cr_cpc_t;
2769 8ecc7913 j_mayer
struct ppc405cr_cpc_t {
2770 04f20795 j_mayer
    clk_setup_t clk_setup[PPC405CR_CLK_NB];
2771 8ecc7913 j_mayer
    uint32_t sysclk;
2772 8ecc7913 j_mayer
    uint32_t psr;
2773 8ecc7913 j_mayer
    uint32_t cr0;
2774 8ecc7913 j_mayer
    uint32_t cr1;
2775 8ecc7913 j_mayer
    uint32_t jtagid;
2776 8ecc7913 j_mayer
    uint32_t pllmr;
2777 8ecc7913 j_mayer
    uint32_t er;
2778 8ecc7913 j_mayer
    uint32_t fr;
2779 8ecc7913 j_mayer
};
2780 8ecc7913 j_mayer
2781 8ecc7913 j_mayer
static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
2782 8ecc7913 j_mayer
{
2783 8ecc7913 j_mayer
    uint64_t VCO_out, PLL_out;
2784 8ecc7913 j_mayer
    uint32_t CPU_clk, TMR_clk, SDRAM_clk, PLB_clk, OPB_clk, EXT_clk, UART_clk;
2785 8ecc7913 j_mayer
    int M, D0, D1, D2;
2786 8ecc7913 j_mayer
2787 8ecc7913 j_mayer
    D0 = ((cpc->pllmr >> 26) & 0x3) + 1; /* CBDV */
2788 8ecc7913 j_mayer
    if (cpc->pllmr & 0x80000000) {
2789 8ecc7913 j_mayer
        D1 = (((cpc->pllmr >> 20) - 1) & 0xF) + 1; /* FBDV */
2790 8ecc7913 j_mayer
        D2 = 8 - ((cpc->pllmr >> 16) & 0x7); /* FWDVA */
2791 8ecc7913 j_mayer
        M = D0 * D1 * D2;
2792 8ecc7913 j_mayer
        VCO_out = cpc->sysclk * M;
2793 8ecc7913 j_mayer
        if (VCO_out < 400000000 || VCO_out > 800000000) {
2794 8ecc7913 j_mayer
            /* PLL cannot lock */
2795 8ecc7913 j_mayer
            cpc->pllmr &= ~0x80000000;
2796 8ecc7913 j_mayer
            goto bypass_pll;
2797 8ecc7913 j_mayer
        }
2798 8ecc7913 j_mayer
        PLL_out = VCO_out / D2;
2799 8ecc7913 j_mayer
    } else {
2800 8ecc7913 j_mayer
        /* Bypass PLL */
2801 8ecc7913 j_mayer
    bypass_pll:
2802 8ecc7913 j_mayer
        M = D0;
2803 8ecc7913 j_mayer
        PLL_out = cpc->sysclk * M;
2804 8ecc7913 j_mayer
    }
2805 8ecc7913 j_mayer
    CPU_clk = PLL_out;
2806 8ecc7913 j_mayer
    if (cpc->cr1 & 0x00800000)
2807 8ecc7913 j_mayer
        TMR_clk = cpc->sysclk; /* Should have a separate clock */
2808 8ecc7913 j_mayer
    else
2809 8ecc7913 j_mayer
        TMR_clk = CPU_clk;
2810 8ecc7913 j_mayer
    PLB_clk = CPU_clk / D0;
2811 8ecc7913 j_mayer
    SDRAM_clk = PLB_clk;
2812 8ecc7913 j_mayer
    D0 = ((cpc->pllmr >> 10) & 0x3) + 1;
2813 8ecc7913 j_mayer
    OPB_clk = PLB_clk / D0;
2814 8ecc7913 j_mayer
    D0 = ((cpc->pllmr >> 24) & 0x3) + 2;
2815 8ecc7913 j_mayer
    EXT_clk = PLB_clk / D0;
2816 8ecc7913 j_mayer
    D0 = ((cpc->cr0 >> 1) & 0x1F) + 1;
2817 8ecc7913 j_mayer
    UART_clk = CPU_clk / D0;
2818 8ecc7913 j_mayer
    /* Setup CPU clocks */
2819 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_CPU_CLK], CPU_clk);
2820 8ecc7913 j_mayer
    /* Setup time-base clock */
2821 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_TMR_CLK], TMR_clk);
2822 8ecc7913 j_mayer
    /* Setup PLB clock */
2823 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_PLB_CLK], PLB_clk);
2824 8ecc7913 j_mayer
    /* Setup SDRAM clock */
2825 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_SDRAM_CLK], SDRAM_clk);
2826 8ecc7913 j_mayer
    /* Setup OPB clock */
2827 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_OPB_CLK], OPB_clk);
2828 8ecc7913 j_mayer
    /* Setup external clock */
2829 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_EXT_CLK], EXT_clk);
2830 8ecc7913 j_mayer
    /* Setup UART clock */
2831 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405CR_UART_CLK], UART_clk);
2832 8ecc7913 j_mayer
}
2833 8ecc7913 j_mayer
2834 8ecc7913 j_mayer
static target_ulong dcr_read_crcpc (void *opaque, int dcrn)
2835 8ecc7913 j_mayer
{
2836 8ecc7913 j_mayer
    ppc405cr_cpc_t *cpc;
2837 8ecc7913 j_mayer
    target_ulong ret;
2838 8ecc7913 j_mayer
2839 8ecc7913 j_mayer
    cpc = opaque;
2840 8ecc7913 j_mayer
    switch (dcrn) {
2841 8ecc7913 j_mayer
    case PPC405CR_CPC0_PLLMR:
2842 8ecc7913 j_mayer
        ret = cpc->pllmr;
2843 8ecc7913 j_mayer
        break;
2844 8ecc7913 j_mayer
    case PPC405CR_CPC0_CR0:
2845 8ecc7913 j_mayer
        ret = cpc->cr0;
2846 8ecc7913 j_mayer
        break;
2847 8ecc7913 j_mayer
    case PPC405CR_CPC0_CR1:
2848 8ecc7913 j_mayer
        ret = cpc->cr1;
2849 8ecc7913 j_mayer
        break;
2850 8ecc7913 j_mayer
    case PPC405CR_CPC0_PSR:
2851 8ecc7913 j_mayer
        ret = cpc->psr;
2852 8ecc7913 j_mayer
        break;
2853 8ecc7913 j_mayer
    case PPC405CR_CPC0_JTAGID:
2854 8ecc7913 j_mayer
        ret = cpc->jtagid;
2855 8ecc7913 j_mayer
        break;
2856 8ecc7913 j_mayer
    case PPC405CR_CPC0_ER:
2857 8ecc7913 j_mayer
        ret = cpc->er;
2858 8ecc7913 j_mayer
        break;
2859 8ecc7913 j_mayer
    case PPC405CR_CPC0_FR:
2860 8ecc7913 j_mayer
        ret = cpc->fr;
2861 8ecc7913 j_mayer
        break;
2862 8ecc7913 j_mayer
    case PPC405CR_CPC0_SR:
2863 8ecc7913 j_mayer
        ret = ~(cpc->er | cpc->fr) & 0xFFFF0000;
2864 8ecc7913 j_mayer
        break;
2865 8ecc7913 j_mayer
    default:
2866 8ecc7913 j_mayer
        /* Avoid gcc warning */
2867 8ecc7913 j_mayer
        ret = 0;
2868 8ecc7913 j_mayer
        break;
2869 8ecc7913 j_mayer
    }
2870 8ecc7913 j_mayer
2871 8ecc7913 j_mayer
    return ret;
2872 8ecc7913 j_mayer
}
2873 8ecc7913 j_mayer
2874 8ecc7913 j_mayer
static void dcr_write_crcpc (void *opaque, int dcrn, target_ulong val)
2875 8ecc7913 j_mayer
{
2876 8ecc7913 j_mayer
    ppc405cr_cpc_t *cpc;
2877 8ecc7913 j_mayer
2878 8ecc7913 j_mayer
    cpc = opaque;
2879 8ecc7913 j_mayer
    switch (dcrn) {
2880 8ecc7913 j_mayer
    case PPC405CR_CPC0_PLLMR:
2881 8ecc7913 j_mayer
        cpc->pllmr = val & 0xFFF77C3F;
2882 8ecc7913 j_mayer
        break;
2883 8ecc7913 j_mayer
    case PPC405CR_CPC0_CR0:
2884 8ecc7913 j_mayer
        cpc->cr0 = val & 0x0FFFFFFE;
2885 8ecc7913 j_mayer
        break;
2886 8ecc7913 j_mayer
    case PPC405CR_CPC0_CR1:
2887 8ecc7913 j_mayer
        cpc->cr1 = val & 0x00800000;
2888 8ecc7913 j_mayer
        break;
2889 8ecc7913 j_mayer
    case PPC405CR_CPC0_PSR:
2890 8ecc7913 j_mayer
        /* Read-only */
2891 8ecc7913 j_mayer
        break;
2892 8ecc7913 j_mayer
    case PPC405CR_CPC0_JTAGID:
2893 8ecc7913 j_mayer
        /* Read-only */
2894 8ecc7913 j_mayer
        break;
2895 8ecc7913 j_mayer
    case PPC405CR_CPC0_ER:
2896 8ecc7913 j_mayer
        cpc->er = val & 0xBFFC0000;
2897 8ecc7913 j_mayer
        break;
2898 8ecc7913 j_mayer
    case PPC405CR_CPC0_FR:
2899 8ecc7913 j_mayer
        cpc->fr = val & 0xBFFC0000;
2900 8ecc7913 j_mayer
        break;
2901 8ecc7913 j_mayer
    case PPC405CR_CPC0_SR:
2902 8ecc7913 j_mayer
        /* Read-only */
2903 8ecc7913 j_mayer
        break;
2904 8ecc7913 j_mayer
    }
2905 8ecc7913 j_mayer
}
2906 8ecc7913 j_mayer
2907 8ecc7913 j_mayer
static void ppc405cr_cpc_reset (void *opaque)
2908 8ecc7913 j_mayer
{
2909 8ecc7913 j_mayer
    ppc405cr_cpc_t *cpc;
2910 8ecc7913 j_mayer
    int D;
2911 8ecc7913 j_mayer
2912 8ecc7913 j_mayer
    cpc = opaque;
2913 8ecc7913 j_mayer
    /* Compute PLLMR value from PSR settings */
2914 8ecc7913 j_mayer
    cpc->pllmr = 0x80000000;
2915 8ecc7913 j_mayer
    /* PFWD */
2916 8ecc7913 j_mayer
    switch ((cpc->psr >> 30) & 3) {
2917 8ecc7913 j_mayer
    case 0:
2918 8ecc7913 j_mayer
        /* Bypass */
2919 8ecc7913 j_mayer
        cpc->pllmr &= ~0x80000000;
2920 8ecc7913 j_mayer
        break;
2921 8ecc7913 j_mayer
    case 1:
2922 8ecc7913 j_mayer
        /* Divide by 3 */
2923 8ecc7913 j_mayer
        cpc->pllmr |= 5 << 16;
2924 8ecc7913 j_mayer
        break;
2925 8ecc7913 j_mayer
    case 2:
2926 8ecc7913 j_mayer
        /* Divide by 4 */
2927 8ecc7913 j_mayer
        cpc->pllmr |= 4 << 16;
2928 8ecc7913 j_mayer
        break;
2929 8ecc7913 j_mayer
    case 3:
2930 8ecc7913 j_mayer
        /* Divide by 6 */
2931 8ecc7913 j_mayer
        cpc->pllmr |= 2 << 16;
2932 8ecc7913 j_mayer
        break;
2933 8ecc7913 j_mayer
    }
2934 8ecc7913 j_mayer
    /* PFBD */
2935 8ecc7913 j_mayer
    D = (cpc->psr >> 28) & 3;
2936 8ecc7913 j_mayer
    cpc->pllmr |= (D + 1) << 20;
2937 8ecc7913 j_mayer
    /* PT   */
2938 8ecc7913 j_mayer
    D = (cpc->psr >> 25) & 7;
2939 8ecc7913 j_mayer
    switch (D) {
2940 8ecc7913 j_mayer
    case 0x2:
2941 8ecc7913 j_mayer
        cpc->pllmr |= 0x13;
2942 8ecc7913 j_mayer
        break;
2943 8ecc7913 j_mayer
    case 0x4:
2944 8ecc7913 j_mayer
        cpc->pllmr |= 0x15;
2945 8ecc7913 j_mayer
        break;
2946 8ecc7913 j_mayer
    case 0x5:
2947 8ecc7913 j_mayer
        cpc->pllmr |= 0x16;
2948 8ecc7913 j_mayer
        break;
2949 8ecc7913 j_mayer
    default:
2950 8ecc7913 j_mayer
        break;
2951 8ecc7913 j_mayer
    }
2952 8ecc7913 j_mayer
    /* PDC  */
2953 8ecc7913 j_mayer
    D = (cpc->psr >> 23) & 3;
2954 8ecc7913 j_mayer
    cpc->pllmr |= D << 26;
2955 8ecc7913 j_mayer
    /* ODP  */
2956 8ecc7913 j_mayer
    D = (cpc->psr >> 21) & 3;
2957 8ecc7913 j_mayer
    cpc->pllmr |= D << 10;
2958 8ecc7913 j_mayer
    /* EBPD */
2959 8ecc7913 j_mayer
    D = (cpc->psr >> 17) & 3;
2960 8ecc7913 j_mayer
    cpc->pllmr |= D << 24;
2961 8ecc7913 j_mayer
    cpc->cr0 = 0x0000003C;
2962 8ecc7913 j_mayer
    cpc->cr1 = 0x2B0D8800;
2963 8ecc7913 j_mayer
    cpc->er = 0x00000000;
2964 8ecc7913 j_mayer
    cpc->fr = 0x00000000;
2965 8ecc7913 j_mayer
    ppc405cr_clk_setup(cpc);
2966 8ecc7913 j_mayer
}
2967 8ecc7913 j_mayer
2968 8ecc7913 j_mayer
static void ppc405cr_clk_init (ppc405cr_cpc_t *cpc)
2969 8ecc7913 j_mayer
{
2970 8ecc7913 j_mayer
    int D;
2971 8ecc7913 j_mayer
2972 8ecc7913 j_mayer
    /* XXX: this should be read from IO pins */
2973 8ecc7913 j_mayer
    cpc->psr = 0x00000000; /* 8 bits ROM */
2974 8ecc7913 j_mayer
    /* PFWD */
2975 8ecc7913 j_mayer
    D = 0x2; /* Divide by 4 */
2976 8ecc7913 j_mayer
    cpc->psr |= D << 30;
2977 8ecc7913 j_mayer
    /* PFBD */
2978 8ecc7913 j_mayer
    D = 0x1; /* Divide by 2 */
2979 8ecc7913 j_mayer
    cpc->psr |= D << 28;
2980 8ecc7913 j_mayer
    /* PDC */
2981 8ecc7913 j_mayer
    D = 0x1; /* Divide by 2 */
2982 8ecc7913 j_mayer
    cpc->psr |= D << 23;
2983 8ecc7913 j_mayer
    /* PT */
2984 8ecc7913 j_mayer
    D = 0x5; /* M = 16 */
2985 8ecc7913 j_mayer
    cpc->psr |= D << 25;
2986 8ecc7913 j_mayer
    /* ODP */
2987 8ecc7913 j_mayer
    D = 0x1; /* Divide by 2 */
2988 8ecc7913 j_mayer
    cpc->psr |= D << 21;
2989 8ecc7913 j_mayer
    /* EBDP */
2990 8ecc7913 j_mayer
    D = 0x2; /* Divide by 4 */
2991 8ecc7913 j_mayer
    cpc->psr |= D << 17;
2992 8ecc7913 j_mayer
}
2993 8ecc7913 j_mayer
2994 8ecc7913 j_mayer
static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7],
2995 8ecc7913 j_mayer
                               uint32_t sysclk)
2996 8ecc7913 j_mayer
{
2997 8ecc7913 j_mayer
    ppc405cr_cpc_t *cpc;
2998 8ecc7913 j_mayer
2999 8ecc7913 j_mayer
    cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t));
3000 8ecc7913 j_mayer
    if (cpc != NULL) {
3001 04f20795 j_mayer
        memcpy(cpc->clk_setup, clk_setup,
3002 04f20795 j_mayer
               PPC405CR_CLK_NB * sizeof(clk_setup_t));
3003 8ecc7913 j_mayer
        cpc->sysclk = sysclk;
3004 8ecc7913 j_mayer
        cpc->jtagid = 0x42051049;
3005 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_PSR, cpc,
3006 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3007 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_CR0, cpc,
3008 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3009 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_CR1, cpc,
3010 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3011 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_JTAGID, cpc,
3012 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3013 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_PLLMR, cpc,
3014 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3015 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_ER, cpc,
3016 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3017 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_FR, cpc,
3018 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3019 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405CR_CPC0_SR, cpc,
3020 8ecc7913 j_mayer
                         &dcr_read_crcpc, &dcr_write_crcpc);
3021 8ecc7913 j_mayer
        ppc405cr_clk_init(cpc);
3022 8ecc7913 j_mayer
        qemu_register_reset(ppc405cr_cpc_reset, cpc);
3023 8ecc7913 j_mayer
        ppc405cr_cpc_reset(cpc);
3024 8ecc7913 j_mayer
    }
3025 8ecc7913 j_mayer
}
3026 8ecc7913 j_mayer
3027 71db710f blueswir1
CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
3028 71db710f blueswir1
                         target_phys_addr_t ram_sizes[4],
3029 8ecc7913 j_mayer
                         uint32_t sysclk, qemu_irq **picp,
3030 04f20795 j_mayer
                         ram_addr_t *offsetp, int do_init)
3031 8ecc7913 j_mayer
{
3032 04f20795 j_mayer
    clk_setup_t clk_setup[PPC405CR_CLK_NB];
3033 8ecc7913 j_mayer
    qemu_irq dma_irqs[4];
3034 8ecc7913 j_mayer
    CPUState *env;
3035 8ecc7913 j_mayer
    ppc4xx_mmio_t *mmio;
3036 8ecc7913 j_mayer
    qemu_irq *pic, *irqs;
3037 8ecc7913 j_mayer
    ram_addr_t offset;
3038 8ecc7913 j_mayer
    int i;
3039 8ecc7913 j_mayer
3040 8ecc7913 j_mayer
    memset(clk_setup, 0, sizeof(clk_setup));
3041 04f20795 j_mayer
    env = ppc405_init("405cr", &clk_setup[PPC405CR_CPU_CLK],
3042 04f20795 j_mayer
                      &clk_setup[PPC405CR_TMR_CLK], sysclk);
3043 8ecc7913 j_mayer
    /* Memory mapped devices registers */
3044 8ecc7913 j_mayer
    mmio = ppc4xx_mmio_init(env, 0xEF600000);
3045 8ecc7913 j_mayer
    /* PLB arbitrer */
3046 8ecc7913 j_mayer
    ppc4xx_plb_init(env);
3047 8ecc7913 j_mayer
    /* PLB to OPB bridge */
3048 8ecc7913 j_mayer
    ppc4xx_pob_init(env);
3049 8ecc7913 j_mayer
    /* OBP arbitrer */
3050 8ecc7913 j_mayer
    ppc4xx_opba_init(env, mmio, 0x600);
3051 8ecc7913 j_mayer
    /* Universal interrupt controller */
3052 8ecc7913 j_mayer
    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
3053 8ecc7913 j_mayer
    irqs[PPCUIC_OUTPUT_INT] =
3054 8ecc7913 j_mayer
        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_INT];
3055 8ecc7913 j_mayer
    irqs[PPCUIC_OUTPUT_CINT] =
3056 8ecc7913 j_mayer
        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_CINT];
3057 8ecc7913 j_mayer
    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
3058 8ecc7913 j_mayer
    *picp = pic;
3059 8ecc7913 j_mayer
    /* SDRAM controller */
3060 04f20795 j_mayer
    ppc405_sdram_init(env, pic[14], 1, ram_bases, ram_sizes, do_init);
3061 8ecc7913 j_mayer
    offset = 0;
3062 8ecc7913 j_mayer
    for (i = 0; i < 4; i++)
3063 8ecc7913 j_mayer
        offset += ram_sizes[i];
3064 8ecc7913 j_mayer
    /* External bus controller */
3065 8ecc7913 j_mayer
    ppc405_ebc_init(env);
3066 8ecc7913 j_mayer
    /* DMA controller */
3067 04f20795 j_mayer
    dma_irqs[0] = pic[26];
3068 04f20795 j_mayer
    dma_irqs[1] = pic[25];
3069 04f20795 j_mayer
    dma_irqs[2] = pic[24];
3070 04f20795 j_mayer
    dma_irqs[3] = pic[23];
3071 8ecc7913 j_mayer
    ppc405_dma_init(env, dma_irqs);
3072 8ecc7913 j_mayer
    /* Serial ports */
3073 8ecc7913 j_mayer
    if (serial_hds[0] != NULL) {
3074 04f20795 j_mayer
        ppc405_serial_init(env, mmio, 0x300, pic[31], serial_hds[0]);
3075 8ecc7913 j_mayer
    }
3076 8ecc7913 j_mayer
    if (serial_hds[1] != NULL) {
3077 04f20795 j_mayer
        ppc405_serial_init(env, mmio, 0x400, pic[30], serial_hds[1]);
3078 8ecc7913 j_mayer
    }
3079 8ecc7913 j_mayer
    /* IIC controller */
3080 9c02f1a2 j_mayer
    ppc405_i2c_init(env, mmio, 0x500, pic[29]);
3081 8ecc7913 j_mayer
    /* GPIO */
3082 8ecc7913 j_mayer
    ppc405_gpio_init(env, mmio, 0x700);
3083 8ecc7913 j_mayer
    /* CPU control */
3084 8ecc7913 j_mayer
    ppc405cr_cpc_init(env, clk_setup, sysclk);
3085 8ecc7913 j_mayer
    *offsetp = offset;
3086 8ecc7913 j_mayer
3087 8ecc7913 j_mayer
    return env;
3088 8ecc7913 j_mayer
}
3089 8ecc7913 j_mayer
3090 8ecc7913 j_mayer
/*****************************************************************************/
3091 8ecc7913 j_mayer
/* PowerPC 405EP */
3092 8ecc7913 j_mayer
/* CPU control */
3093 8ecc7913 j_mayer
enum {
3094 8ecc7913 j_mayer
    PPC405EP_CPC0_PLLMR0 = 0x0F0,
3095 8ecc7913 j_mayer
    PPC405EP_CPC0_BOOT   = 0x0F1,
3096 8ecc7913 j_mayer
    PPC405EP_CPC0_EPCTL  = 0x0F3,
3097 8ecc7913 j_mayer
    PPC405EP_CPC0_PLLMR1 = 0x0F4,
3098 8ecc7913 j_mayer
    PPC405EP_CPC0_UCR    = 0x0F5,
3099 8ecc7913 j_mayer
    PPC405EP_CPC0_SRR    = 0x0F6,
3100 8ecc7913 j_mayer
    PPC405EP_CPC0_JTAGID = 0x0F7,
3101 8ecc7913 j_mayer
    PPC405EP_CPC0_PCI    = 0x0F9,
3102 9c02f1a2 j_mayer
#if 0
3103 9c02f1a2 j_mayer
    PPC405EP_CPC0_ER     = xxx,
3104 9c02f1a2 j_mayer
    PPC405EP_CPC0_FR     = xxx,
3105 9c02f1a2 j_mayer
    PPC405EP_CPC0_SR     = xxx,
3106 9c02f1a2 j_mayer
#endif
3107 8ecc7913 j_mayer
};
3108 8ecc7913 j_mayer
3109 04f20795 j_mayer
enum {
3110 04f20795 j_mayer
    PPC405EP_CPU_CLK   = 0,
3111 04f20795 j_mayer
    PPC405EP_PLB_CLK   = 1,
3112 04f20795 j_mayer
    PPC405EP_OPB_CLK   = 2,
3113 04f20795 j_mayer
    PPC405EP_EBC_CLK   = 3,
3114 04f20795 j_mayer
    PPC405EP_MAL_CLK   = 4,
3115 04f20795 j_mayer
    PPC405EP_PCI_CLK   = 5,
3116 04f20795 j_mayer
    PPC405EP_UART0_CLK = 6,
3117 04f20795 j_mayer
    PPC405EP_UART1_CLK = 7,
3118 04f20795 j_mayer
    PPC405EP_CLK_NB    = 8,
3119 04f20795 j_mayer
};
3120 04f20795 j_mayer
3121 8ecc7913 j_mayer
typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
3122 8ecc7913 j_mayer
struct ppc405ep_cpc_t {
3123 8ecc7913 j_mayer
    uint32_t sysclk;
3124 04f20795 j_mayer
    clk_setup_t clk_setup[PPC405EP_CLK_NB];
3125 8ecc7913 j_mayer
    uint32_t boot;
3126 8ecc7913 j_mayer
    uint32_t epctl;
3127 8ecc7913 j_mayer
    uint32_t pllmr[2];
3128 8ecc7913 j_mayer
    uint32_t ucr;
3129 8ecc7913 j_mayer
    uint32_t srr;
3130 8ecc7913 j_mayer
    uint32_t jtagid;
3131 8ecc7913 j_mayer
    uint32_t pci;
3132 9c02f1a2 j_mayer
    /* Clock and power management */
3133 9c02f1a2 j_mayer
    uint32_t er;
3134 9c02f1a2 j_mayer
    uint32_t fr;
3135 9c02f1a2 j_mayer
    uint32_t sr;
3136 8ecc7913 j_mayer
};
3137 8ecc7913 j_mayer
3138 8ecc7913 j_mayer
static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
3139 8ecc7913 j_mayer
{
3140 8ecc7913 j_mayer
    uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
3141 8ecc7913 j_mayer
    uint32_t UART0_clk, UART1_clk;
3142 8ecc7913 j_mayer
    uint64_t VCO_out, PLL_out;
3143 8ecc7913 j_mayer
    int M, D;
3144 8ecc7913 j_mayer
3145 8ecc7913 j_mayer
    VCO_out = 0;
3146 8ecc7913 j_mayer
    if ((cpc->pllmr[1] & 0x80000000) && !(cpc->pllmr[1] & 0x40000000)) {
3147 8ecc7913 j_mayer
        M = (((cpc->pllmr[1] >> 20) - 1) & 0xF) + 1; /* FBMUL */
3148 8ecc7913 j_mayer
        //        printf("FBMUL %01x %d\n", (cpc->pllmr[1] >> 20) & 0xF, M);
3149 8ecc7913 j_mayer
        D = 8 - ((cpc->pllmr[1] >> 16) & 0x7); /* FWDA */
3150 8ecc7913 j_mayer
        //        printf("FWDA %01x %d\n", (cpc->pllmr[1] >> 16) & 0x7, D);
3151 8ecc7913 j_mayer
        VCO_out = cpc->sysclk * M * D;
3152 8ecc7913 j_mayer
        if (VCO_out < 500000000UL || VCO_out > 1000000000UL) {
3153 8ecc7913 j_mayer
            /* Error - unlock the PLL */
3154 8ecc7913 j_mayer
            printf("VCO out of range %" PRIu64 "\n", VCO_out);
3155 8ecc7913 j_mayer
#if 0
3156 8ecc7913 j_mayer
            cpc->pllmr[1] &= ~0x80000000;
3157 8ecc7913 j_mayer
            goto pll_bypass;
3158 8ecc7913 j_mayer
#endif
3159 8ecc7913 j_mayer
        }
3160 8ecc7913 j_mayer
        PLL_out = VCO_out / D;
3161 9c02f1a2 j_mayer
        /* Pretend the PLL is locked */
3162 9c02f1a2 j_mayer
        cpc->boot |= 0x00000001;
3163 8ecc7913 j_mayer
    } else {
3164 8ecc7913 j_mayer
#if 0
3165 8ecc7913 j_mayer
    pll_bypass:
3166 8ecc7913 j_mayer
#endif
3167 8ecc7913 j_mayer
        PLL_out = cpc->sysclk;
3168 9c02f1a2 j_mayer
        if (cpc->pllmr[1] & 0x40000000) {
3169 9c02f1a2 j_mayer
            /* Pretend the PLL is not locked */
3170 9c02f1a2 j_mayer
            cpc->boot &= ~0x00000001;
3171 9c02f1a2 j_mayer
        }
3172 8ecc7913 j_mayer
    }
3173 8ecc7913 j_mayer
    /* Now, compute all other clocks */
3174 8ecc7913 j_mayer
    D = ((cpc->pllmr[0] >> 20) & 0x3) + 1; /* CCDV */
3175 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3176 8ecc7913 j_mayer
    //    printf("CCDV %01x %d\n", (cpc->pllmr[0] >> 20) & 0x3, D);
3177 8ecc7913 j_mayer
#endif
3178 8ecc7913 j_mayer
    CPU_clk = PLL_out / D;
3179 8ecc7913 j_mayer
    D = ((cpc->pllmr[0] >> 16) & 0x3) + 1; /* CBDV */
3180 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3181 8ecc7913 j_mayer
    //    printf("CBDV %01x %d\n", (cpc->pllmr[0] >> 16) & 0x3, D);
3182 8ecc7913 j_mayer
#endif
3183 8ecc7913 j_mayer
    PLB_clk = CPU_clk / D;
3184 8ecc7913 j_mayer
    D = ((cpc->pllmr[0] >> 12) & 0x3) + 1; /* OPDV */
3185 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3186 8ecc7913 j_mayer
    //    printf("OPDV %01x %d\n", (cpc->pllmr[0] >> 12) & 0x3, D);
3187 8ecc7913 j_mayer
#endif
3188 8ecc7913 j_mayer
    OPB_clk = PLB_clk / D;
3189 8ecc7913 j_mayer
    D = ((cpc->pllmr[0] >> 8) & 0x3) + 2; /* EPDV */
3190 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3191 8ecc7913 j_mayer
    //    printf("EPDV %01x %d\n", (cpc->pllmr[0] >> 8) & 0x3, D);
3192 8ecc7913 j_mayer
#endif
3193 8ecc7913 j_mayer
    EBC_clk = PLB_clk / D;
3194 8ecc7913 j_mayer
    D = ((cpc->pllmr[0] >> 4) & 0x3) + 1; /* MPDV */
3195 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3196 8ecc7913 j_mayer
    //    printf("MPDV %01x %d\n", (cpc->pllmr[0] >> 4) & 0x3, D);
3197 8ecc7913 j_mayer
#endif
3198 8ecc7913 j_mayer
    MAL_clk = PLB_clk / D;
3199 8ecc7913 j_mayer
    D = (cpc->pllmr[0] & 0x3) + 1; /* PPDV */
3200 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3201 8ecc7913 j_mayer
    //    printf("PPDV %01x %d\n", cpc->pllmr[0] & 0x3, D);
3202 8ecc7913 j_mayer
#endif
3203 8ecc7913 j_mayer
    PCI_clk = PLB_clk / D;
3204 8ecc7913 j_mayer
    D = ((cpc->ucr - 1) & 0x7F) + 1; /* U0DIV */
3205 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3206 8ecc7913 j_mayer
    //    printf("U0DIV %01x %d\n", cpc->ucr & 0x7F, D);
3207 8ecc7913 j_mayer
#endif
3208 8ecc7913 j_mayer
    UART0_clk = PLL_out / D;
3209 8ecc7913 j_mayer
    D = (((cpc->ucr >> 8) - 1) & 0x7F) + 1; /* U1DIV */
3210 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3211 8ecc7913 j_mayer
    //    printf("U1DIV %01x %d\n", (cpc->ucr >> 8) & 0x7F, D);
3212 8ecc7913 j_mayer
#endif
3213 8ecc7913 j_mayer
    UART1_clk = PLL_out / D;
3214 8ecc7913 j_mayer
#ifdef DEBUG_CLOCKS
3215 8ecc7913 j_mayer
    printf("Setup PPC405EP clocks - sysclk %d VCO %" PRIu64
3216 8ecc7913 j_mayer
           " PLL out %" PRIu64 " Hz\n", cpc->sysclk, VCO_out, PLL_out);
3217 8ecc7913 j_mayer
    printf("CPU %d PLB %d OPB %d EBC %d MAL %d PCI %d UART0 %d UART1 %d\n",
3218 8ecc7913 j_mayer
           CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk,
3219 8ecc7913 j_mayer
           UART0_clk, UART1_clk);
3220 9c02f1a2 j_mayer
    printf("CB %p opaque %p\n", cpc->clk_setup[PPC405EP_CPU_CLK].cb,
3221 9c02f1a2 j_mayer
           cpc->clk_setup[PPC405EP_CPU_CLK].opaque);
3222 8ecc7913 j_mayer
#endif
3223 8ecc7913 j_mayer
    /* Setup CPU clocks */
3224 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_CPU_CLK], CPU_clk);
3225 8ecc7913 j_mayer
    /* Setup PLB clock */
3226 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_PLB_CLK], PLB_clk);
3227 8ecc7913 j_mayer
    /* Setup OPB clock */
3228 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_OPB_CLK], OPB_clk);
3229 8ecc7913 j_mayer
    /* Setup external clock */
3230 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_EBC_CLK], EBC_clk);
3231 8ecc7913 j_mayer
    /* Setup MAL clock */
3232 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_MAL_CLK], MAL_clk);
3233 8ecc7913 j_mayer
    /* Setup PCI clock */
3234 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_PCI_CLK], PCI_clk);
3235 8ecc7913 j_mayer
    /* Setup UART0 clock */
3236 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_UART0_CLK], UART0_clk);
3237 8ecc7913 j_mayer
    /* Setup UART1 clock */
3238 04f20795 j_mayer
    clk_setup(&cpc->clk_setup[PPC405EP_UART1_CLK], UART1_clk);
3239 8ecc7913 j_mayer
}
3240 8ecc7913 j_mayer
3241 8ecc7913 j_mayer
static target_ulong dcr_read_epcpc (void *opaque, int dcrn)
3242 8ecc7913 j_mayer
{
3243 8ecc7913 j_mayer
    ppc405ep_cpc_t *cpc;
3244 8ecc7913 j_mayer
    target_ulong ret;
3245 8ecc7913 j_mayer
3246 8ecc7913 j_mayer
    cpc = opaque;
3247 8ecc7913 j_mayer
    switch (dcrn) {
3248 8ecc7913 j_mayer
    case PPC405EP_CPC0_BOOT:
3249 8ecc7913 j_mayer
        ret = cpc->boot;
3250 8ecc7913 j_mayer
        break;
3251 8ecc7913 j_mayer
    case PPC405EP_CPC0_EPCTL:
3252 8ecc7913 j_mayer
        ret = cpc->epctl;
3253 8ecc7913 j_mayer
        break;
3254 8ecc7913 j_mayer
    case PPC405EP_CPC0_PLLMR0:
3255 8ecc7913 j_mayer
        ret = cpc->pllmr[0];
3256 8ecc7913 j_mayer
        break;
3257 8ecc7913 j_mayer
    case PPC405EP_CPC0_PLLMR1:
3258 8ecc7913 j_mayer
        ret = cpc->pllmr[1];
3259 8ecc7913 j_mayer
        break;
3260 8ecc7913 j_mayer
    case PPC405EP_CPC0_UCR:
3261 8ecc7913 j_mayer
        ret = cpc->ucr;
3262 8ecc7913 j_mayer
        break;
3263 8ecc7913 j_mayer
    case PPC405EP_CPC0_SRR:
3264 8ecc7913 j_mayer
        ret = cpc->srr;
3265 8ecc7913 j_mayer
        break;
3266 8ecc7913 j_mayer
    case PPC405EP_CPC0_JTAGID:
3267 8ecc7913 j_mayer
        ret = cpc->jtagid;
3268 8ecc7913 j_mayer
        break;
3269 8ecc7913 j_mayer
    case PPC405EP_CPC0_PCI:
3270 8ecc7913 j_mayer
        ret = cpc->pci;
3271 8ecc7913 j_mayer
        break;
3272 8ecc7913 j_mayer
    default:
3273 8ecc7913 j_mayer
        /* Avoid gcc warning */
3274 8ecc7913 j_mayer
        ret = 0;
3275 8ecc7913 j_mayer
        break;
3276 8ecc7913 j_mayer
    }
3277 8ecc7913 j_mayer
3278 8ecc7913 j_mayer
    return ret;
3279 8ecc7913 j_mayer
}
3280 8ecc7913 j_mayer
3281 8ecc7913 j_mayer
static void dcr_write_epcpc (void *opaque, int dcrn, target_ulong val)
3282 8ecc7913 j_mayer
{
3283 8ecc7913 j_mayer
    ppc405ep_cpc_t *cpc;
3284 8ecc7913 j_mayer
3285 8ecc7913 j_mayer
    cpc = opaque;
3286 8ecc7913 j_mayer
    switch (dcrn) {
3287 8ecc7913 j_mayer
    case PPC405EP_CPC0_BOOT:
3288 8ecc7913 j_mayer
        /* Read-only register */
3289 8ecc7913 j_mayer
        break;
3290 8ecc7913 j_mayer
    case PPC405EP_CPC0_EPCTL:
3291 8ecc7913 j_mayer
        /* Don't care for now */
3292 8ecc7913 j_mayer
        cpc->epctl = val & 0xC00000F3;
3293 8ecc7913 j_mayer
        break;
3294 8ecc7913 j_mayer
    case PPC405EP_CPC0_PLLMR0:
3295 8ecc7913 j_mayer
        cpc->pllmr[0] = val & 0x00633333;
3296 8ecc7913 j_mayer
        ppc405ep_compute_clocks(cpc);
3297 8ecc7913 j_mayer
        break;
3298 8ecc7913 j_mayer
    case PPC405EP_CPC0_PLLMR1:
3299 8ecc7913 j_mayer
        cpc->pllmr[1] = val & 0xC0F73FFF;
3300 8ecc7913 j_mayer
        ppc405ep_compute_clocks(cpc);
3301 8ecc7913 j_mayer
        break;
3302 8ecc7913 j_mayer
    case PPC405EP_CPC0_UCR:
3303 8ecc7913 j_mayer
        /* UART control - don't care for now */
3304 8ecc7913 j_mayer
        cpc->ucr = val & 0x003F7F7F;
3305 8ecc7913 j_mayer
        break;
3306 8ecc7913 j_mayer
    case PPC405EP_CPC0_SRR:
3307 8ecc7913 j_mayer
        cpc->srr = val;
3308 8ecc7913 j_mayer
        break;
3309 8ecc7913 j_mayer
    case PPC405EP_CPC0_JTAGID:
3310 8ecc7913 j_mayer
        /* Read-only */
3311 8ecc7913 j_mayer
        break;
3312 8ecc7913 j_mayer
    case PPC405EP_CPC0_PCI:
3313 8ecc7913 j_mayer
        cpc->pci = val;
3314 8ecc7913 j_mayer
        break;
3315 8ecc7913 j_mayer
    }
3316 8ecc7913 j_mayer
}
3317 8ecc7913 j_mayer
3318 8ecc7913 j_mayer
static void ppc405ep_cpc_reset (void *opaque)
3319 8ecc7913 j_mayer
{
3320 8ecc7913 j_mayer
    ppc405ep_cpc_t *cpc = opaque;
3321 8ecc7913 j_mayer
3322 8ecc7913 j_mayer
    cpc->boot = 0x00000010;     /* Boot from PCI - IIC EEPROM disabled */
3323 8ecc7913 j_mayer
    cpc->epctl = 0x00000000;
3324 8ecc7913 j_mayer
    cpc->pllmr[0] = 0x00011010;
3325 8ecc7913 j_mayer
    cpc->pllmr[1] = 0x40000000;
3326 8ecc7913 j_mayer
    cpc->ucr = 0x00000000;
3327 8ecc7913 j_mayer
    cpc->srr = 0x00040000;
3328 8ecc7913 j_mayer
    cpc->pci = 0x00000000;
3329 9c02f1a2 j_mayer
    cpc->er = 0x00000000;
3330 9c02f1a2 j_mayer
    cpc->fr = 0x00000000;
3331 9c02f1a2 j_mayer
    cpc->sr = 0x00000000;
3332 8ecc7913 j_mayer
    ppc405ep_compute_clocks(cpc);
3333 8ecc7913 j_mayer
}
3334 8ecc7913 j_mayer
3335 8ecc7913 j_mayer
/* XXX: sysclk should be between 25 and 100 MHz */
3336 8ecc7913 j_mayer
static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8],
3337 8ecc7913 j_mayer
                               uint32_t sysclk)
3338 8ecc7913 j_mayer
{
3339 8ecc7913 j_mayer
    ppc405ep_cpc_t *cpc;
3340 8ecc7913 j_mayer
3341 8ecc7913 j_mayer
    cpc = qemu_mallocz(sizeof(ppc405ep_cpc_t));
3342 8ecc7913 j_mayer
    if (cpc != NULL) {
3343 04f20795 j_mayer
        memcpy(cpc->clk_setup, clk_setup,
3344 04f20795 j_mayer
               PPC405EP_CLK_NB * sizeof(clk_setup_t));
3345 8ecc7913 j_mayer
        cpc->jtagid = 0x20267049;
3346 8ecc7913 j_mayer
        cpc->sysclk = sysclk;
3347 8ecc7913 j_mayer
        ppc405ep_cpc_reset(cpc);
3348 8ecc7913 j_mayer
        qemu_register_reset(&ppc405ep_cpc_reset, cpc);
3349 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
3350 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3351 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
3352 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3353 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_PLLMR0, cpc,
3354 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3355 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_PLLMR1, cpc,
3356 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3357 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_UCR, cpc,
3358 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3359 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_SRR, cpc,
3360 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3361 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_JTAGID, cpc,
3362 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3363 8ecc7913 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_PCI, cpc,
3364 8ecc7913 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3365 9c02f1a2 j_mayer
#if 0
3366 9c02f1a2 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_ER, cpc,
3367 9c02f1a2 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3368 9c02f1a2 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_FR, cpc,
3369 9c02f1a2 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3370 9c02f1a2 j_mayer
        ppc_dcr_register(env, PPC405EP_CPC0_SR, cpc,
3371 9c02f1a2 j_mayer
                         &dcr_read_epcpc, &dcr_write_epcpc);
3372 9c02f1a2 j_mayer
#endif
3373 8ecc7913 j_mayer
    }
3374 8ecc7913 j_mayer
}
3375 8ecc7913 j_mayer
3376 71db710f blueswir1
CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
3377 71db710f blueswir1
                         target_phys_addr_t ram_sizes[2],
3378 8ecc7913 j_mayer
                         uint32_t sysclk, qemu_irq **picp,
3379 04f20795 j_mayer
                         ram_addr_t *offsetp, int do_init)
3380 8ecc7913 j_mayer
{
3381 9c02f1a2 j_mayer
    clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
3382 9c02f1a2 j_mayer
    qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
3383 8ecc7913 j_mayer
    CPUState *env;
3384 8ecc7913 j_mayer
    ppc4xx_mmio_t *mmio;
3385 8ecc7913 j_mayer
    qemu_irq *pic, *irqs;
3386 8ecc7913 j_mayer
    ram_addr_t offset;
3387 8ecc7913 j_mayer
    int i;
3388 8ecc7913 j_mayer
3389 8ecc7913 j_mayer
    memset(clk_setup, 0, sizeof(clk_setup));
3390 8ecc7913 j_mayer
    /* init CPUs */
3391 04f20795 j_mayer
    env = ppc405_init("405ep", &clk_setup[PPC405EP_CPU_CLK],
3392 9c02f1a2 j_mayer
                      &tlb_clk_setup, sysclk);
3393 9c02f1a2 j_mayer
    clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
3394 9c02f1a2 j_mayer
    clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
3395 8ecc7913 j_mayer
    /* Internal devices init */
3396 8ecc7913 j_mayer
    /* Memory mapped devices registers */
3397 8ecc7913 j_mayer
    mmio = ppc4xx_mmio_init(env, 0xEF600000);
3398 8ecc7913 j_mayer
    /* PLB arbitrer */
3399 8ecc7913 j_mayer
    ppc4xx_plb_init(env);
3400 8ecc7913 j_mayer
    /* PLB to OPB bridge */
3401 8ecc7913 j_mayer
    ppc4xx_pob_init(env);
3402 8ecc7913 j_mayer
    /* OBP arbitrer */
3403 8ecc7913 j_mayer
    ppc4xx_opba_init(env, mmio, 0x600);
3404 8ecc7913 j_mayer
    /* Universal interrupt controller */
3405 8ecc7913 j_mayer
    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
3406 8ecc7913 j_mayer
    irqs[PPCUIC_OUTPUT_INT] =
3407 8ecc7913 j_mayer
        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_INT];
3408 8ecc7913 j_mayer
    irqs[PPCUIC_OUTPUT_CINT] =
3409 8ecc7913 j_mayer
        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_CINT];
3410 8ecc7913 j_mayer
    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
3411 8ecc7913 j_mayer
    *picp = pic;
3412 8ecc7913 j_mayer
    /* SDRAM controller */
3413 04f20795 j_mayer
    ppc405_sdram_init(env, pic[14], 2, ram_bases, ram_sizes, do_init);
3414 8ecc7913 j_mayer
    offset = 0;
3415 8ecc7913 j_mayer
    for (i = 0; i < 2; i++)
3416 8ecc7913 j_mayer
        offset += ram_sizes[i];
3417 8ecc7913 j_mayer
    /* External bus controller */
3418 8ecc7913 j_mayer
    ppc405_ebc_init(env);
3419 8ecc7913 j_mayer
    /* DMA controller */
3420 04f20795 j_mayer
    dma_irqs[0] = pic[26];
3421 04f20795 j_mayer
    dma_irqs[1] = pic[25];
3422 04f20795 j_mayer
    dma_irqs[2] = pic[24];
3423 04f20795 j_mayer
    dma_irqs[3] = pic[23];
3424 8ecc7913 j_mayer
    ppc405_dma_init(env, dma_irqs);
3425 8ecc7913 j_mayer
    /* IIC controller */
3426 9c02f1a2 j_mayer
    ppc405_i2c_init(env, mmio, 0x500, pic[29]);
3427 8ecc7913 j_mayer
    /* GPIO */
3428 8ecc7913 j_mayer
    ppc405_gpio_init(env, mmio, 0x700);
3429 8ecc7913 j_mayer
    /* Serial ports */
3430 8ecc7913 j_mayer
    if (serial_hds[0] != NULL) {
3431 04f20795 j_mayer
        ppc405_serial_init(env, mmio, 0x300, pic[31], serial_hds[0]);
3432 8ecc7913 j_mayer
    }
3433 8ecc7913 j_mayer
    if (serial_hds[1] != NULL) {
3434 04f20795 j_mayer
        ppc405_serial_init(env, mmio, 0x400, pic[30], serial_hds[1]);
3435 8ecc7913 j_mayer
    }
3436 8ecc7913 j_mayer
    /* OCM */
3437 8ecc7913 j_mayer
    ppc405_ocm_init(env, ram_sizes[0] + ram_sizes[1]);
3438 8ecc7913 j_mayer
    offset += 4096;
3439 9c02f1a2 j_mayer
    /* GPT */
3440 9c02f1a2 j_mayer
    gpt_irqs[0] = pic[12];
3441 9c02f1a2 j_mayer
    gpt_irqs[1] = pic[11];
3442 9c02f1a2 j_mayer
    gpt_irqs[2] = pic[10];
3443 9c02f1a2 j_mayer
    gpt_irqs[3] = pic[9];
3444 9c02f1a2 j_mayer
    gpt_irqs[4] = pic[8];
3445 9c02f1a2 j_mayer
    ppc4xx_gpt_init(env, mmio, 0x000, gpt_irqs);
3446 8ecc7913 j_mayer
    /* PCI */
3447 9c02f1a2 j_mayer
    /* Uses pic[28], pic[15], pic[13] */
3448 9c02f1a2 j_mayer
    /* MAL */
3449 9c02f1a2 j_mayer
    mal_irqs[0] = pic[20];
3450 9c02f1a2 j_mayer
    mal_irqs[1] = pic[19];
3451 9c02f1a2 j_mayer
    mal_irqs[2] = pic[18];
3452 9c02f1a2 j_mayer
    mal_irqs[3] = pic[17];
3453 9c02f1a2 j_mayer
    ppc405_mal_init(env, mal_irqs);
3454 9c02f1a2 j_mayer
    /* Ethernet */
3455 9c02f1a2 j_mayer
    /* Uses pic[22], pic[16], pic[14] */
3456 8ecc7913 j_mayer
    /* CPU control */
3457 8ecc7913 j_mayer
    ppc405ep_cpc_init(env, clk_setup, sysclk);
3458 8ecc7913 j_mayer
    *offsetp = offset;
3459 8ecc7913 j_mayer
3460 8ecc7913 j_mayer
    return env;
3461 8ecc7913 j_mayer
}