Statistics
| Branch: | Revision:

root / hw / ppc405_uc.c @ 36081602

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