Statistics
| Branch: | Revision:

root / target-ppc / hw.c @ 97eb5b14

History | View | Annotate | Download (24.8 kB)

1 9a64fbe4 bellard
/*
2 9a64fbe4 bellard
 * Hardware simulation for PPC target.
3 9a64fbe4 bellard
 * For now, this is only a 'minimal' collection of hacks needed to boot Linux.
4 9a64fbe4 bellard
 */
5 9a64fbe4 bellard
6 9a64fbe4 bellard
#include <stdlib.h>
7 9a64fbe4 bellard
#include <stdio.h>
8 9a64fbe4 bellard
#include <stdarg.h>
9 9a64fbe4 bellard
#include <string.h>
10 9a64fbe4 bellard
#include <ctype.h>
11 9a64fbe4 bellard
#include <unistd.h>
12 9a64fbe4 bellard
#include <fcntl.h>
13 9a64fbe4 bellard
#include <inttypes.h>
14 9a64fbe4 bellard
#include <unistd.h>
15 9a64fbe4 bellard
#include <time.h>
16 9a64fbe4 bellard
17 9a64fbe4 bellard
#include "cpu.h"
18 9a64fbe4 bellard
#include "vl.h"
19 9a64fbe4 bellard
20 9a64fbe4 bellard
//#define HARD_DEBUG_PPC_IO
21 9a64fbe4 bellard
#define DEBUG_PPC_IO
22 9a64fbe4 bellard
23 9a64fbe4 bellard
extern int loglevel;
24 9a64fbe4 bellard
extern FILE *logfile;
25 9a64fbe4 bellard
26 9a64fbe4 bellard
#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
27 9a64fbe4 bellard
#define DEBUG_PPC_IO
28 9a64fbe4 bellard
#endif
29 9a64fbe4 bellard
30 9a64fbe4 bellard
#if defined (HARD_DEBUG_PPC_IO)
31 9a64fbe4 bellard
#define PPC_IO_DPRINTF(fmt, args...)                     \
32 9a64fbe4 bellard
do {                                                     \
33 9a64fbe4 bellard
    if (loglevel > 0) {                                  \
34 9a64fbe4 bellard
        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
35 9a64fbe4 bellard
    } else {                                             \
36 9a64fbe4 bellard
        printf("%s : " fmt, __func__ , ##args);          \
37 9a64fbe4 bellard
    }                                                    \
38 9a64fbe4 bellard
} while (0)
39 9a64fbe4 bellard
#elif defined (DEBUG_PPC_IO)
40 9a64fbe4 bellard
#define PPC_IO_DPRINTF(fmt, args...)                     \
41 9a64fbe4 bellard
do {                                                     \
42 9a64fbe4 bellard
    if (loglevel > 0) {                                  \
43 9a64fbe4 bellard
        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
44 9a64fbe4 bellard
    }                                                    \
45 9a64fbe4 bellard
} while (0)
46 9a64fbe4 bellard
#else
47 9a64fbe4 bellard
#define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
48 9a64fbe4 bellard
#endif
49 9a64fbe4 bellard
50 9a64fbe4 bellard
#if defined (USE_OPEN_FIRMWARE)
51 9a64fbe4 bellard
#include "of.h"
52 9a64fbe4 bellard
#else
53 9a64fbe4 bellard
#define NVRAM_SIZE 0x2000
54 9a64fbe4 bellard
#endif
55 9a64fbe4 bellard
56 9a64fbe4 bellard
/* IO ports emulation */
57 9a64fbe4 bellard
#define PPC_IO_BASE 0x80000000
58 9a64fbe4 bellard
59 9a64fbe4 bellard
static void PPC_io_writeb (uint32_t addr, uint32_t value)
60 9a64fbe4 bellard
{
61 9a64fbe4 bellard
    /* Don't polute serial port output */
62 9a64fbe4 bellard
    if ((addr < 0x800003F0 || addr > 0x80000400) &&
63 9a64fbe4 bellard
        (addr < 0x80000074 || addr > 0x80000077) &&
64 9a64fbe4 bellard
        (addr < 0x80000020 || addr > 0x80000021) &&
65 9a64fbe4 bellard
        (addr < 0x800000a0 || addr > 0x800000a1) &&
66 9a64fbe4 bellard
        (addr < 0x800001f0 || addr > 0x800001f7) &&
67 9a64fbe4 bellard
        (addr < 0x80000170 || addr > 0x80000177)) {
68 9a64fbe4 bellard
        PPC_IO_DPRINTF("0x%08x => 0x%02x\n", addr - PPC_IO_BASE, value);
69 9a64fbe4 bellard
    }
70 9a64fbe4 bellard
    cpu_outb(NULL, addr - PPC_IO_BASE, value);
71 9a64fbe4 bellard
}
72 9a64fbe4 bellard
73 9a64fbe4 bellard
static uint32_t PPC_io_readb (uint32_t addr)
74 9a64fbe4 bellard
{
75 9a64fbe4 bellard
    uint32_t ret = cpu_inb(NULL, addr - PPC_IO_BASE);
76 9a64fbe4 bellard
77 9a64fbe4 bellard
    if ((addr < 0x800003F0 || addr > 0x80000400) &&
78 9a64fbe4 bellard
        (addr < 0x80000074 || addr > 0x80000077) &&
79 9a64fbe4 bellard
        (addr < 0x80000020 || addr > 0x80000021) &&
80 9a64fbe4 bellard
        (addr < 0x800000a0 || addr > 0x800000a1) &&
81 9a64fbe4 bellard
        (addr < 0x800001f0 || addr > 0x800001f7) &&
82 9a64fbe4 bellard
        (addr < 0x80000170 || addr > 0x80000177) &&
83 9a64fbe4 bellard
        (addr < 0x8000060 || addr > 0x8000064)) {
84 9a64fbe4 bellard
//        PPC_IO_DPRINTF("0x%08x <= 0x%02x\n", addr - PPC_IO_BASE, ret);
85 9a64fbe4 bellard
    }
86 9a64fbe4 bellard
87 9a64fbe4 bellard
    return ret;
88 9a64fbe4 bellard
}
89 9a64fbe4 bellard
90 9a64fbe4 bellard
static void PPC_io_writew (uint32_t addr, uint32_t value)
91 9a64fbe4 bellard
{
92 9a64fbe4 bellard
    if ((addr < 0x800001f0 || addr > 0x800001f7) &&
93 9a64fbe4 bellard
        (addr < 0x80000170 || addr > 0x80000177)) {
94 9a64fbe4 bellard
        PPC_IO_DPRINTF("0x%08x => 0x%04x\n", addr - PPC_IO_BASE, value);
95 9a64fbe4 bellard
    }
96 9a64fbe4 bellard
    cpu_outw(NULL, addr - PPC_IO_BASE, value);
97 9a64fbe4 bellard
}
98 9a64fbe4 bellard
99 9a64fbe4 bellard
static uint32_t PPC_io_readw (uint32_t addr)
100 9a64fbe4 bellard
{
101 9a64fbe4 bellard
    uint32_t ret = cpu_inw(NULL, addr - PPC_IO_BASE);
102 9a64fbe4 bellard
103 9a64fbe4 bellard
    if ((addr < 0x800001f0 || addr > 0x800001f7) &&
104 9a64fbe4 bellard
        (addr < 0x80000170 || addr > 0x80000177)) {
105 9a64fbe4 bellard
        PPC_IO_DPRINTF("0x%08x <= 0x%04x\n", addr - PPC_IO_BASE, ret);
106 9a64fbe4 bellard
    }
107 9a64fbe4 bellard
108 9a64fbe4 bellard
    return ret;
109 9a64fbe4 bellard
}
110 9a64fbe4 bellard
111 9a64fbe4 bellard
static void PPC_io_writel (uint32_t addr, uint32_t value)
112 9a64fbe4 bellard
{
113 9a64fbe4 bellard
    PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, value);
114 9a64fbe4 bellard
    cpu_outl(NULL, addr - PPC_IO_BASE, value);
115 9a64fbe4 bellard
}
116 9a64fbe4 bellard
117 9a64fbe4 bellard
static uint32_t PPC_io_readl (uint32_t addr)
118 9a64fbe4 bellard
{
119 9a64fbe4 bellard
    uint32_t ret = cpu_inl(NULL, addr - PPC_IO_BASE);
120 9a64fbe4 bellard
121 9a64fbe4 bellard
    PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, ret);
122 9a64fbe4 bellard
123 9a64fbe4 bellard
    return ret;
124 9a64fbe4 bellard
}
125 9a64fbe4 bellard
126 9a64fbe4 bellard
static CPUWriteMemoryFunc *PPC_io_write[] = {
127 9a64fbe4 bellard
    &PPC_io_writeb,
128 9a64fbe4 bellard
    &PPC_io_writew,
129 9a64fbe4 bellard
    &PPC_io_writel,
130 9a64fbe4 bellard
};
131 9a64fbe4 bellard
132 9a64fbe4 bellard
static CPUReadMemoryFunc *PPC_io_read[] = {
133 9a64fbe4 bellard
    &PPC_io_readb,
134 9a64fbe4 bellard
    &PPC_io_readw,
135 9a64fbe4 bellard
    &PPC_io_readl,
136 9a64fbe4 bellard
};
137 9a64fbe4 bellard
138 9a64fbe4 bellard
uint32_t pic_intack_read(CPUState *env);
139 9a64fbe4 bellard
140 9a64fbe4 bellard
/* Read-only register (?) */
141 9a64fbe4 bellard
static void _PPC_ioB_write (uint32_t addr, uint32_t value)
142 9a64fbe4 bellard
{
143 9a64fbe4 bellard
    PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr, value);
144 9a64fbe4 bellard
}
145 9a64fbe4 bellard
146 9a64fbe4 bellard
static uint32_t _PPC_ioB_read (uint32_t addr)
147 9a64fbe4 bellard
{
148 9a64fbe4 bellard
    uint32_t retval = 0;
149 9a64fbe4 bellard
150 9a64fbe4 bellard
    if (addr == 0xBFFFFFF0)
151 9a64fbe4 bellard
        retval = pic_intack_read(NULL);
152 9a64fbe4 bellard
    PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr, retval);
153 9a64fbe4 bellard
154 9a64fbe4 bellard
    return retval;
155 9a64fbe4 bellard
}
156 9a64fbe4 bellard
157 9a64fbe4 bellard
static CPUWriteMemoryFunc *PPC_ioB_write[] = {
158 9a64fbe4 bellard
    &_PPC_ioB_write,
159 9a64fbe4 bellard
    &_PPC_ioB_write,
160 9a64fbe4 bellard
    &_PPC_ioB_write,
161 9a64fbe4 bellard
};
162 9a64fbe4 bellard
163 9a64fbe4 bellard
static CPUReadMemoryFunc *PPC_ioB_read[] = {
164 9a64fbe4 bellard
    &_PPC_ioB_read,
165 9a64fbe4 bellard
    &_PPC_ioB_read,
166 9a64fbe4 bellard
    &_PPC_ioB_read,
167 9a64fbe4 bellard
};
168 9a64fbe4 bellard
169 9a64fbe4 bellard
#if 0
170 9a64fbe4 bellard
static CPUWriteMemoryFunc *PPC_io3_write[] = {
171 9a64fbe4 bellard
    &PPC_io3_writeb,
172 9a64fbe4 bellard
    &PPC_io3_writew,
173 9a64fbe4 bellard
    &PPC_io3_writel,
174 9a64fbe4 bellard
};
175 9a64fbe4 bellard

176 9a64fbe4 bellard
static CPUReadMemoryFunc *PPC_io3_read[] = {
177 9a64fbe4 bellard
    &PPC_io3_readb,
178 9a64fbe4 bellard
    &PPC_io3_readw,
179 9a64fbe4 bellard
    &PPC_io3_readl,
180 9a64fbe4 bellard
};
181 9a64fbe4 bellard
#endif
182 9a64fbe4 bellard
183 9a64fbe4 bellard
/* Fake super-io ports for PREP platform (Intel 82378ZB) */
184 9a64fbe4 bellard
static uint8_t PREP_fake_io[2];
185 9a64fbe4 bellard
static uint8_t NVRAM_lock;
186 9a64fbe4 bellard
187 9a64fbe4 bellard
static void PREP_io_write (CPUState *env, uint32_t addr, uint32_t val)
188 9a64fbe4 bellard
{
189 9a64fbe4 bellard
    PREP_fake_io[addr - 0x0398] = val;
190 9a64fbe4 bellard
}
191 9a64fbe4 bellard
192 9a64fbe4 bellard
static uint32_t PREP_io_read (CPUState *env, uint32_t addr)
193 9a64fbe4 bellard
{
194 9a64fbe4 bellard
    return PREP_fake_io[addr - 0x0398];
195 9a64fbe4 bellard
}
196 9a64fbe4 bellard
197 9a64fbe4 bellard
static uint8_t syscontrol;
198 9a64fbe4 bellard
199 9a64fbe4 bellard
static void PREP_io_800_writeb (CPUState *env, uint32_t addr, uint32_t val)
200 9a64fbe4 bellard
{
201 9a64fbe4 bellard
    switch (addr) {
202 9a64fbe4 bellard
    case 0x0092:
203 9a64fbe4 bellard
        /* Special port 92 */
204 9a64fbe4 bellard
        /* Check soft reset asked */
205 9a64fbe4 bellard
        if (val & 0x80) {
206 9a64fbe4 bellard
            printf("Soft reset asked... Stop emulation\n");
207 9a64fbe4 bellard
            abort();
208 9a64fbe4 bellard
        }
209 9a64fbe4 bellard
        /* Check LE mode */
210 9a64fbe4 bellard
        if (val & 0x40) {
211 9a64fbe4 bellard
            printf("Little Endian mode isn't supported (yet ?)\n");
212 9a64fbe4 bellard
            abort();
213 9a64fbe4 bellard
        }
214 9a64fbe4 bellard
        break;
215 9a64fbe4 bellard
    case 0x0808:
216 9a64fbe4 bellard
        /* Hardfile light register: don't care */
217 9a64fbe4 bellard
        break;
218 9a64fbe4 bellard
    case 0x0810:
219 9a64fbe4 bellard
        /* Password protect 1 register */
220 9a64fbe4 bellard
        NVRAM_lock ^= 0x01;
221 9a64fbe4 bellard
        break;
222 9a64fbe4 bellard
    case 0x0812:
223 9a64fbe4 bellard
        /* Password protect 2 register */
224 9a64fbe4 bellard
        NVRAM_lock ^= 0x02;
225 9a64fbe4 bellard
        break;
226 9a64fbe4 bellard
    case 0x0814:
227 9a64fbe4 bellard
        /* L2 invalidate register: don't care */
228 9a64fbe4 bellard
        break;
229 9a64fbe4 bellard
    case 0x081C:
230 9a64fbe4 bellard
        /* system control register */
231 9a64fbe4 bellard
        syscontrol = val;
232 9a64fbe4 bellard
        break;
233 9a64fbe4 bellard
    case 0x0850:
234 9a64fbe4 bellard
        /* I/O map type register */
235 9a64fbe4 bellard
        if (val & 0x80) {
236 9a64fbe4 bellard
            printf("No support for non-continuous I/O map mode\n");
237 9a64fbe4 bellard
            abort();
238 9a64fbe4 bellard
        }
239 9a64fbe4 bellard
        break;
240 9a64fbe4 bellard
    default:
241 9a64fbe4 bellard
        break;
242 9a64fbe4 bellard
    }
243 9a64fbe4 bellard
}
244 9a64fbe4 bellard
245 9a64fbe4 bellard
static uint32_t PREP_io_800_readb (CPUState *env, uint32_t addr)
246 9a64fbe4 bellard
{
247 9a64fbe4 bellard
    uint32_t retval = 0xFF;
248 9a64fbe4 bellard
249 9a64fbe4 bellard
    switch (addr) {
250 9a64fbe4 bellard
    case 0x0092:
251 9a64fbe4 bellard
        /* Special port 92 */
252 9a64fbe4 bellard
        retval = 0x40;
253 9a64fbe4 bellard
        break;
254 9a64fbe4 bellard
    case 0x080C:
255 9a64fbe4 bellard
        /* Equipment present register:
256 9a64fbe4 bellard
         *  no L2 cache
257 9a64fbe4 bellard
         *  no upgrade processor
258 9a64fbe4 bellard
         *  no cards in PCI slots
259 9a64fbe4 bellard
         *  SCSI fuse is bad
260 9a64fbe4 bellard
         */
261 9a64fbe4 bellard
        retval = 0xFC;
262 9a64fbe4 bellard
        break;
263 9a64fbe4 bellard
    case 0x0818:
264 9a64fbe4 bellard
        /* Keylock */
265 9a64fbe4 bellard
        retval = 0x00;
266 9a64fbe4 bellard
        break;
267 9a64fbe4 bellard
    case 0x081C:
268 9a64fbe4 bellard
        /* system control register
269 9a64fbe4 bellard
         * 7 - 6 / 1 - 0: L2 cache enable
270 9a64fbe4 bellard
         */
271 9a64fbe4 bellard
        retval = syscontrol;
272 9a64fbe4 bellard
        break;
273 9a64fbe4 bellard
    case 0x0823:
274 9a64fbe4 bellard
        /* */
275 9a64fbe4 bellard
        retval = 0x03; /* no L2 cache */
276 9a64fbe4 bellard
        break;
277 9a64fbe4 bellard
    case 0x0850:
278 9a64fbe4 bellard
        /* I/O map type register */
279 9a64fbe4 bellard
        retval = 0x00;
280 9a64fbe4 bellard
        break;
281 9a64fbe4 bellard
    default:
282 9a64fbe4 bellard
        break;
283 9a64fbe4 bellard
    }
284 9a64fbe4 bellard
285 9a64fbe4 bellard
    return retval;
286 9a64fbe4 bellard
}
287 9a64fbe4 bellard
288 9a64fbe4 bellard
/* M48T59 NVRAM/RTC emulation */
289 9a64fbe4 bellard
static uint8_t NVRAM[NVRAM_SIZE];
290 9a64fbe4 bellard
291 9a64fbe4 bellard
/* RTC */
292 9a64fbe4 bellard
static time_t time_offset;
293 9a64fbe4 bellard
294 9a64fbe4 bellard
time_t get_time (void)
295 9a64fbe4 bellard
{
296 9a64fbe4 bellard
    return time(NULL) + time_offset;
297 9a64fbe4 bellard
}
298 9a64fbe4 bellard
299 9a64fbe4 bellard
void set_time_offset (time_t new_time)
300 9a64fbe4 bellard
{
301 9a64fbe4 bellard
    time_t now = time(NULL);
302 9a64fbe4 bellard
303 9a64fbe4 bellard
    time_offset = new_time - now;
304 9a64fbe4 bellard
}
305 9a64fbe4 bellard
306 9a64fbe4 bellard
static void NVRAM_init (void)
307 9a64fbe4 bellard
{
308 9a64fbe4 bellard
    /* NVRAM header */
309 9a64fbe4 bellard
    /* 0x00: NVRAM size in kB */
310 9a64fbe4 bellard
    NVRAM[0x00] = (NVRAM_SIZE >> 12) & 0xFF;
311 9a64fbe4 bellard
    NVRAM[0x01] = (NVRAM_SIZE >> 10) & 0xFF;
312 9a64fbe4 bellard
    /* 0x02: NVRAM version */
313 9a64fbe4 bellard
    NVRAM[0x02] = 0x01;
314 9a64fbe4 bellard
    /* 0x03: NVRAM revision */
315 9a64fbe4 bellard
    NVRAM[0x03] = 0x00;
316 9a64fbe4 bellard
    /* 0x04: checksum 0 => OS area   */
317 9a64fbe4 bellard
    /* 0x06: checksum of config area */
318 9a64fbe4 bellard
    /* 0x08: last OS */
319 9a64fbe4 bellard
    NVRAM[0x08] = 0x00; /* Unknown */
320 9a64fbe4 bellard
    /* 0x09: endian */
321 9a64fbe4 bellard
    NVRAM[0x09] = 'B';
322 9a64fbe4 bellard
    /* 0x0B: PM mode */
323 9a64fbe4 bellard
    NVRAM[0x0B] = 0x00;
324 9a64fbe4 bellard
    /* Restart block description record */
325 9a64fbe4 bellard
    /* 0x0C: restart block version */
326 9a64fbe4 bellard
    NVRAM[0x0C] = 0x00;
327 9a64fbe4 bellard
    NVRAM[0x0D] = 0x01;
328 9a64fbe4 bellard
    /* 0x0E: restart block revision */
329 9a64fbe4 bellard
    NVRAM[0x0E] = 0x00;
330 9a64fbe4 bellard
    NVRAM[0x0F] = 0x00;
331 9a64fbe4 bellard
    /* 0x1C: checksum of restart block */
332 9a64fbe4 bellard
    /* 0x20: restart address */
333 9a64fbe4 bellard
    NVRAM[0x20] = 0x00;
334 9a64fbe4 bellard
    NVRAM[0x21] = 0x00;
335 9a64fbe4 bellard
    NVRAM[0x22] = 0x00;
336 9a64fbe4 bellard
    NVRAM[0x23] = 0x00;
337 9a64fbe4 bellard
    /* 0x24: save area address */
338 9a64fbe4 bellard
    NVRAM[0x24] = 0x00;
339 9a64fbe4 bellard
    NVRAM[0x25] = 0x00;
340 9a64fbe4 bellard
    NVRAM[0x26] = 0x00;
341 9a64fbe4 bellard
    NVRAM[0x27] = 0x00;
342 9a64fbe4 bellard
    /* 0x28: save area length */
343 9a64fbe4 bellard
    NVRAM[0x28] = 0x00;
344 9a64fbe4 bellard
    NVRAM[0x29] = 0x00;
345 9a64fbe4 bellard
    NVRAM[0x2A] = 0x00;
346 9a64fbe4 bellard
    NVRAM[0x2B] = 0x00;
347 9a64fbe4 bellard
    /* Security section */
348 9a64fbe4 bellard
    /* Set all to zero */
349 9a64fbe4 bellard
    /* 0xC4: pointer to global environment area */
350 9a64fbe4 bellard
    NVRAM[0xC4] = 0x00;
351 9a64fbe4 bellard
    NVRAM[0xC5] = 0x00;
352 9a64fbe4 bellard
    NVRAM[0xC6] = 0x01;
353 9a64fbe4 bellard
    NVRAM[0xC7] = 0x00;
354 9a64fbe4 bellard
    /* 0xC8: size of global environment area */
355 9a64fbe4 bellard
    NVRAM[0xC8] = 0x00;
356 9a64fbe4 bellard
    NVRAM[0xC9] = 0x00;
357 9a64fbe4 bellard
    NVRAM[0xCA] = 0x07;
358 9a64fbe4 bellard
    NVRAM[0xCB] = 0x00;
359 9a64fbe4 bellard
    /* 0xD4: pointer to configuration area */
360 9a64fbe4 bellard
    NVRAM[0xD4] = 0x00;
361 9a64fbe4 bellard
    NVRAM[0xD5] = 0x00;
362 9a64fbe4 bellard
    NVRAM[0xD6] = 0x08;
363 9a64fbe4 bellard
    NVRAM[0xD7] = 0x00;
364 9a64fbe4 bellard
    /* 0xD8: size of configuration area */
365 9a64fbe4 bellard
    NVRAM[0xD8] = 0x00;
366 9a64fbe4 bellard
    NVRAM[0xD9] = 0x00;
367 9a64fbe4 bellard
    NVRAM[0xDA] = 0x08;
368 9a64fbe4 bellard
    NVRAM[0xDB] = 0x00;
369 9a64fbe4 bellard
    /* 0xE8: pointer to OS specific area */
370 9a64fbe4 bellard
    NVRAM[0xE8] = 0x00;
371 9a64fbe4 bellard
    NVRAM[0xE9] = 0x00;
372 9a64fbe4 bellard
    NVRAM[0xEA] = 0x10;
373 9a64fbe4 bellard
    NVRAM[0xEB] = 0x00;
374 9a64fbe4 bellard
    /* 0xD8: size of OS specific area */
375 9a64fbe4 bellard
    NVRAM[0xEC] = 0x00;
376 9a64fbe4 bellard
    NVRAM[0xED] = 0x00;
377 9a64fbe4 bellard
    NVRAM[0xEE] = 0x0F;
378 9a64fbe4 bellard
    NVRAM[0xEF] = 0xF0;
379 9a64fbe4 bellard
    /* CRC */
380 9a64fbe4 bellard
    /* RTC init */
381 9a64fbe4 bellard
    NVRAM[0x1FFC] = 0x50;
382 9a64fbe4 bellard
}
383 9a64fbe4 bellard
384 9a64fbe4 bellard
static uint16_t NVRAM_addr;
385 9a64fbe4 bellard
386 9a64fbe4 bellard
/* Direct access to NVRAM */
387 9a64fbe4 bellard
void NVRAM_write (CPUState *env, uint32_t addr, uint32_t val)
388 9a64fbe4 bellard
{
389 9a64fbe4 bellard
    switch (addr) {
390 9a64fbe4 bellard
    case 0x1FF0:
391 9a64fbe4 bellard
        /* flags register */
392 9a64fbe4 bellard
        break;
393 9a64fbe4 bellard
    case 0x1FF1:
394 9a64fbe4 bellard
        /* unused */
395 9a64fbe4 bellard
        break;
396 9a64fbe4 bellard
    case 0x1FF2:
397 9a64fbe4 bellard
        /* alarm seconds */
398 9a64fbe4 bellard
        break;
399 9a64fbe4 bellard
    case 0x1FF3:
400 9a64fbe4 bellard
        /* alarm minutes */
401 9a64fbe4 bellard
        break;
402 9a64fbe4 bellard
    case 0x1FF4:
403 9a64fbe4 bellard
        /* alarm hours */
404 9a64fbe4 bellard
        break;
405 9a64fbe4 bellard
    case 0x1FF5:
406 9a64fbe4 bellard
        /* alarm date */
407 9a64fbe4 bellard
        break;
408 9a64fbe4 bellard
    case 0x1FF6:
409 9a64fbe4 bellard
        /* interrupts */
410 9a64fbe4 bellard
        break;
411 9a64fbe4 bellard
    case 0x1FF7:
412 9a64fbe4 bellard
        /* watchdog */
413 9a64fbe4 bellard
        break;
414 9a64fbe4 bellard
    case 0x1FF8:
415 9a64fbe4 bellard
        /* control */
416 9a64fbe4 bellard
        break;
417 9a64fbe4 bellard
    case 0x1FF9:
418 9a64fbe4 bellard
        /* seconds (BCD) */
419 9a64fbe4 bellard
        break;
420 9a64fbe4 bellard
    case 0x1FFA:
421 9a64fbe4 bellard
        /* minutes (BCD) */
422 9a64fbe4 bellard
        break;
423 9a64fbe4 bellard
    case 0x1FFB:
424 9a64fbe4 bellard
        /* hours (BCD) */
425 9a64fbe4 bellard
        break;
426 9a64fbe4 bellard
    case 0x1FFC:
427 9a64fbe4 bellard
        /* day of the week / century */
428 9a64fbe4 bellard
        NVRAM[0x1FFC] = val & 0x50;
429 9a64fbe4 bellard
        break;
430 9a64fbe4 bellard
    case 0x1FFD:
431 9a64fbe4 bellard
        /* date */
432 9a64fbe4 bellard
        break;
433 9a64fbe4 bellard
    case 0x1FFE:
434 9a64fbe4 bellard
        /* month */
435 9a64fbe4 bellard
        break;
436 9a64fbe4 bellard
    case 0x1FFF:
437 9a64fbe4 bellard
        /* year */
438 9a64fbe4 bellard
        break;
439 9a64fbe4 bellard
    default:
440 9a64fbe4 bellard
        if (addr < NVRAM_SIZE)
441 9a64fbe4 bellard
            NVRAM[addr] = val & 0xFF;
442 9a64fbe4 bellard
        break;
443 9a64fbe4 bellard
    }
444 9a64fbe4 bellard
}
445 9a64fbe4 bellard
446 9a64fbe4 bellard
uint32_t NVRAM_read (CPUState *env, uint32_t addr)
447 9a64fbe4 bellard
{
448 9a64fbe4 bellard
    struct tm tm;
449 9a64fbe4 bellard
    time_t t;
450 9a64fbe4 bellard
    uint32_t retval = 0xFF;
451 9a64fbe4 bellard
452 9a64fbe4 bellard
    switch (addr) {
453 9a64fbe4 bellard
    case 0x1FF0:
454 9a64fbe4 bellard
        /* flags register */
455 9a64fbe4 bellard
        break;
456 9a64fbe4 bellard
    case 0x1FF1:
457 9a64fbe4 bellard
        /* unused */
458 9a64fbe4 bellard
        break;
459 9a64fbe4 bellard
    case 0x1FF2:
460 9a64fbe4 bellard
        /* alarm seconds */
461 9a64fbe4 bellard
        break;
462 9a64fbe4 bellard
    case 0x1FF3:
463 9a64fbe4 bellard
        /* alarm minutes */
464 9a64fbe4 bellard
        break;
465 9a64fbe4 bellard
    case 0x1FF4:
466 9a64fbe4 bellard
        /* alarm hours */
467 9a64fbe4 bellard
        break;
468 9a64fbe4 bellard
    case 0x1FF5:
469 9a64fbe4 bellard
        /* alarm date */
470 9a64fbe4 bellard
        break;
471 9a64fbe4 bellard
    case 0x1FF6:
472 9a64fbe4 bellard
        /* interrupts */
473 9a64fbe4 bellard
        break;
474 9a64fbe4 bellard
    case 0x1FF7:
475 9a64fbe4 bellard
        /* watchdog */
476 9a64fbe4 bellard
        break;
477 9a64fbe4 bellard
    case 0x1FF8:
478 9a64fbe4 bellard
        /* control */
479 9a64fbe4 bellard
        break;
480 9a64fbe4 bellard
    case 0x1FF9:
481 9a64fbe4 bellard
        /* seconds (BCD) */
482 9a64fbe4 bellard
        t = get_time();
483 9a64fbe4 bellard
        localtime_r(&t, &tm);
484 9a64fbe4 bellard
        retval = ((tm.tm_sec / 10) << 4) | (tm.tm_sec % 10);
485 9a64fbe4 bellard
//            printf("return seconds=%d\n", tm.tm_sec);
486 9a64fbe4 bellard
        break;
487 9a64fbe4 bellard
    case 0x1FFA:
488 9a64fbe4 bellard
        /* minutes (BCD) */
489 9a64fbe4 bellard
        t = get_time();
490 9a64fbe4 bellard
        localtime_r(&t, &tm);
491 9a64fbe4 bellard
        retval = ((tm.tm_min / 10) << 4) | (tm.tm_min % 10);
492 9a64fbe4 bellard
        break;
493 9a64fbe4 bellard
    case 0x1FFB:
494 9a64fbe4 bellard
        /* hours (BCD) */
495 9a64fbe4 bellard
        t = get_time();
496 9a64fbe4 bellard
        localtime_r(&t, &tm);
497 9a64fbe4 bellard
        retval = ((tm.tm_hour / 10) << 4) | (tm.tm_hour % 10);
498 9a64fbe4 bellard
        break;
499 9a64fbe4 bellard
    case 0x1FFC:
500 9a64fbe4 bellard
        /* day of the week / century */
501 9a64fbe4 bellard
        t = get_time();
502 9a64fbe4 bellard
        localtime_r(&t, &tm);
503 9a64fbe4 bellard
        retval = (NVRAM[0x1FFC] & 0x50) | tm.tm_wday;
504 9a64fbe4 bellard
        break;
505 9a64fbe4 bellard
    case 0x1FFD:
506 9a64fbe4 bellard
        /* date */
507 9a64fbe4 bellard
        t = get_time();
508 9a64fbe4 bellard
        localtime_r(&t, &tm);
509 9a64fbe4 bellard
        retval = ((tm.tm_mday / 10) << 4) | (tm.tm_mday % 10);
510 9a64fbe4 bellard
        break;
511 9a64fbe4 bellard
    case 0x1FFE:
512 9a64fbe4 bellard
        /* month */
513 9a64fbe4 bellard
        t = get_time();
514 9a64fbe4 bellard
        localtime_r(&t, &tm);
515 9a64fbe4 bellard
        retval = ((tm.tm_mon / 10) << 4) | (tm.tm_mon % 10);
516 9a64fbe4 bellard
        break;
517 9a64fbe4 bellard
    case 0x1FFF:
518 9a64fbe4 bellard
        /* year */
519 9a64fbe4 bellard
        t = get_time();
520 9a64fbe4 bellard
        localtime_r(&t, &tm);
521 9a64fbe4 bellard
        retval = ((tm.tm_year / 10) << 4) | (tm.tm_year % 10);
522 9a64fbe4 bellard
        break;
523 9a64fbe4 bellard
    default:
524 9a64fbe4 bellard
        if (NVRAM_addr < NVRAM_SIZE)
525 9a64fbe4 bellard
            retval = NVRAM[NVRAM_addr];
526 9a64fbe4 bellard
        break;
527 9a64fbe4 bellard
    }
528 9a64fbe4 bellard
529 9a64fbe4 bellard
    return retval;
530 9a64fbe4 bellard
}
531 9a64fbe4 bellard
532 9a64fbe4 bellard
/* IO access to NVRAM */
533 9a64fbe4 bellard
static void NVRAM_writeb (CPUState *env, uint32_t addr, uint32_t val)
534 9a64fbe4 bellard
{
535 9a64fbe4 bellard
    switch (addr) {
536 9a64fbe4 bellard
    case 0x74:
537 9a64fbe4 bellard
        NVRAM_addr &= ~0x00FF;
538 9a64fbe4 bellard
        NVRAM_addr |= val;
539 9a64fbe4 bellard
        break;
540 9a64fbe4 bellard
    case 0x75:
541 9a64fbe4 bellard
        NVRAM_addr &= ~0xFF00;
542 9a64fbe4 bellard
        NVRAM_addr |= val << 8;
543 9a64fbe4 bellard
        break;
544 9a64fbe4 bellard
    case 0x77:
545 9a64fbe4 bellard
        NVRAM_write(env, NVRAM_addr, val);
546 9a64fbe4 bellard
        NVRAM_addr = 0x0000;
547 9a64fbe4 bellard
        break;
548 9a64fbe4 bellard
    default:
549 9a64fbe4 bellard
        break;
550 9a64fbe4 bellard
    }
551 9a64fbe4 bellard
}
552 9a64fbe4 bellard
553 9a64fbe4 bellard
static uint32_t NVRAM_readb (CPUState *env, uint32_t addr)
554 9a64fbe4 bellard
{
555 9a64fbe4 bellard
    if (addr == 0x77)
556 9a64fbe4 bellard
        return NVRAM_read(env, NVRAM_addr);
557 9a64fbe4 bellard
558 9a64fbe4 bellard
    return 0xFF;
559 9a64fbe4 bellard
}
560 9a64fbe4 bellard
561 9a64fbe4 bellard
int load_initrd (const char *filename, uint8_t *addr)
562 9a64fbe4 bellard
{
563 9a64fbe4 bellard
    int fd, size;
564 9a64fbe4 bellard
565 9a64fbe4 bellard
    printf("Load initrd\n");
566 9a64fbe4 bellard
    fd = open(filename, O_RDONLY);
567 9a64fbe4 bellard
    if (fd < 0)
568 9a64fbe4 bellard
        return -1;
569 9a64fbe4 bellard
    size = read(fd, addr, 16 * 1024 * 1024);
570 9a64fbe4 bellard
    if (size < 0)
571 9a64fbe4 bellard
        goto fail;
572 9a64fbe4 bellard
    close(fd);
573 9a64fbe4 bellard
    printf("Load initrd: %d\n", size);
574 9a64fbe4 bellard
    return size;
575 9a64fbe4 bellard
 fail:
576 9a64fbe4 bellard
    close(fd);
577 9a64fbe4 bellard
    printf("Load initrd failed\n");
578 9a64fbe4 bellard
    return -1;
579 9a64fbe4 bellard
}
580 9a64fbe4 bellard
581 9a64fbe4 bellard
/* Quick hack for PPC memory infos... */
582 9a64fbe4 bellard
static void put_long (void *addr, uint32_t l)
583 9a64fbe4 bellard
{
584 9a64fbe4 bellard
    char *pos = addr;
585 9a64fbe4 bellard
    pos[0] = (l >> 24) & 0xFF;
586 9a64fbe4 bellard
    pos[1] = (l >> 16) & 0xFF;
587 9a64fbe4 bellard
    pos[2] = (l >> 8) & 0xFF;
588 9a64fbe4 bellard
    pos[3] = l & 0xFF;
589 9a64fbe4 bellard
}
590 9a64fbe4 bellard
591 9a64fbe4 bellard
/* bootloader infos are in the form:
592 9a64fbe4 bellard
 * uint32_t TAG
593 9a64fbe4 bellard
 * uint32_t TAG_size (from TAG to next TAG).
594 9a64fbe4 bellard
 * datas
595 9a64fbe4 bellard
 * ....
596 9a64fbe4 bellard
 */
597 9a64fbe4 bellard
#if !defined (USE_OPEN_FIRMWARE)
598 9a64fbe4 bellard
static void *set_bootinfo_tag (void *addr, uint32_t tag, uint32_t size,
599 9a64fbe4 bellard
                               void *data)
600 9a64fbe4 bellard
{
601 9a64fbe4 bellard
    char *pos = addr;
602 9a64fbe4 bellard
603 9a64fbe4 bellard
    put_long(pos, tag);
604 9a64fbe4 bellard
    pos += 4;
605 9a64fbe4 bellard
    put_long(pos, size + 8);
606 9a64fbe4 bellard
    pos += 4;
607 9a64fbe4 bellard
    memcpy(pos, data, size);
608 9a64fbe4 bellard
    pos += size;
609 9a64fbe4 bellard
610 9a64fbe4 bellard
    return pos;
611 9a64fbe4 bellard
}
612 9a64fbe4 bellard
#endif
613 9a64fbe4 bellard
614 9a64fbe4 bellard
typedef struct boot_dev_t {
615 9a64fbe4 bellard
    const unsigned char *name;
616 9a64fbe4 bellard
    int major;
617 9a64fbe4 bellard
    int minor;
618 9a64fbe4 bellard
} boot_dev_t;
619 9a64fbe4 bellard
620 9a64fbe4 bellard
static boot_dev_t boot_devs[] = 
621 9a64fbe4 bellard
{
622 9a64fbe4 bellard
    { "/dev/fd0", 2, 0, },
623 9a64fbe4 bellard
    { "/dev/fd1", 2, 1, },
624 9a64fbe4 bellard
    { "/dev/hda1", 3, 1, },
625 9a64fbe4 bellard
//    { "/dev/ide/host0/bus0/target0/lun0/part1", 3, 1, },
626 9a64fbe4 bellard
    { "/dev/hdc", 22, 0, },
627 9a64fbe4 bellard
    { "/dev/ram0 init=/linuxrc", 1, 0, },
628 9a64fbe4 bellard
};
629 9a64fbe4 bellard
630 9a64fbe4 bellard
/* BATU:
631 9a64fbe4 bellard
 * BEPI  : bloc virtual address
632 9a64fbe4 bellard
 * BL    : area size bits (128 kB is 0, 256 1, 512 3, ...
633 9a64fbe4 bellard
 * Vs/Vp
634 9a64fbe4 bellard
 * BATL:
635 9a64fbe4 bellard
 * BPRN  : bloc real address align on 4MB boundary
636 9a64fbe4 bellard
 * WIMG  : cache access mode : not used
637 9a64fbe4 bellard
 * PP    : protection bits
638 9a64fbe4 bellard
 */
639 9a64fbe4 bellard
static void setup_BAT (CPUPPCState *env, int BAT,
640 9a64fbe4 bellard
                       uint32_t virtual, uint32_t physical,
641 9a64fbe4 bellard
                       uint32_t size, int Vs, int Vp, int PP)
642 9a64fbe4 bellard
{
643 9a64fbe4 bellard
    uint32_t sz_bits, tmp_sz, align, tmp;
644 9a64fbe4 bellard
    
645 9a64fbe4 bellard
    sz_bits = 0;
646 9a64fbe4 bellard
    align = 131072;
647 9a64fbe4 bellard
    for (tmp_sz = size / 131072; tmp_sz != 1; tmp_sz = tmp_sz >> 1) {
648 9a64fbe4 bellard
        sz_bits = (sz_bits << 1) + 1;
649 9a64fbe4 bellard
        align = align << 1;
650 9a64fbe4 bellard
    }
651 9a64fbe4 bellard
    tmp = virtual & ~(align - 1);  /* Align virtual area start */
652 9a64fbe4 bellard
    tmp |= sz_bits << 2;           /* Fix BAT size             */
653 9a64fbe4 bellard
    tmp |= Vs << 1;                /* Supervisor access        */
654 9a64fbe4 bellard
    tmp |= Vp;                     /* User access              */
655 9a64fbe4 bellard
    env->DBAT[0][BAT] = tmp;
656 9a64fbe4 bellard
    env->IBAT[0][BAT] = tmp;
657 9a64fbe4 bellard
    tmp = physical & ~(align - 1); /* Align physical area start */
658 9a64fbe4 bellard
    tmp |= 0;                      /* Don't care about WIMG     */
659 9a64fbe4 bellard
    tmp |= PP;                     /* Protection                */
660 9a64fbe4 bellard
    env->DBAT[1][BAT] = tmp;
661 9a64fbe4 bellard
    env->IBAT[1][BAT] = tmp;
662 9a64fbe4 bellard
    printf("Set BATU0 to 0x%08x BATL0 to 0x%08x\n",
663 9a64fbe4 bellard
           env->DBAT[0][BAT], env->DBAT[1][BAT]);
664 9a64fbe4 bellard
}
665 9a64fbe4 bellard
666 9a64fbe4 bellard
static void VGA_printf (uint8_t *s)
667 9a64fbe4 bellard
{
668 9a64fbe4 bellard
    uint16_t *arg_ptr;
669 9a64fbe4 bellard
    unsigned int format_width, i;
670 9a64fbe4 bellard
    int in_format;
671 9a64fbe4 bellard
    uint16_t arg, digit, nibble;
672 9a64fbe4 bellard
    uint8_t c;
673 9a64fbe4 bellard
674 9a64fbe4 bellard
    arg_ptr = (uint16_t *)(&s);
675 9a64fbe4 bellard
    in_format = 0;
676 9a64fbe4 bellard
    format_width = 0;
677 9a64fbe4 bellard
    while ((c = *s) != '\0') {
678 9a64fbe4 bellard
        if (c == '%') {
679 9a64fbe4 bellard
            in_format = 1;
680 9a64fbe4 bellard
            format_width = 0;
681 9a64fbe4 bellard
        } else if (in_format) {
682 9a64fbe4 bellard
            if ((c >= '0') && (c <= '9')) {
683 9a64fbe4 bellard
                format_width = (format_width * 10) + (c - '0');
684 9a64fbe4 bellard
            } else if (c == 'x') {
685 9a64fbe4 bellard
                arg_ptr++; // increment to next arg
686 9a64fbe4 bellard
                arg = *arg_ptr;
687 9a64fbe4 bellard
                if (format_width == 0)
688 9a64fbe4 bellard
                    format_width = 4;
689 9a64fbe4 bellard
                digit = format_width - 1;
690 9a64fbe4 bellard
                for (i = 0; i < format_width; i++) {
691 9a64fbe4 bellard
                    nibble = (arg >> (4 * digit)) & 0x000f;
692 9a64fbe4 bellard
                    if (nibble <= 9)
693 9a64fbe4 bellard
                        PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + '0');
694 9a64fbe4 bellard
                    else
695 9a64fbe4 bellard
                        PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + 'A');
696 9a64fbe4 bellard
                    digit--;
697 9a64fbe4 bellard
                }
698 9a64fbe4 bellard
                in_format = 0;
699 9a64fbe4 bellard
            }
700 9a64fbe4 bellard
            //else if (c == 'd') {
701 9a64fbe4 bellard
            //  in_format = 0;
702 9a64fbe4 bellard
            //  }
703 9a64fbe4 bellard
        } else {
704 9a64fbe4 bellard
            PPC_io_writeb(PPC_IO_BASE + 0x500, c);
705 9a64fbe4 bellard
        }
706 9a64fbe4 bellard
        s++;
707 9a64fbe4 bellard
    }
708 9a64fbe4 bellard
}
709 9a64fbe4 bellard
710 9a64fbe4 bellard
static void VGA_init (void)
711 9a64fbe4 bellard
{
712 9a64fbe4 bellard
    /* Basic VGA init, inspired by plex86 VGAbios */
713 9a64fbe4 bellard
    printf("Init VGA...\n");
714 9a64fbe4 bellard
    /* switch to color mode and enable CPU access 480 lines */
715 9a64fbe4 bellard
    PPC_io_writeb(PPC_IO_BASE + 0x3C2, 0xC3);
716 9a64fbe4 bellard
    /* more than 64k 3C4/04 */
717 9a64fbe4 bellard
    PPC_io_writeb(PPC_IO_BASE + 0x3C4, 0x04);
718 9a64fbe4 bellard
    PPC_io_writeb(PPC_IO_BASE + 0x3C5, 0x02);
719 9a64fbe4 bellard
    VGA_printf("PPC VGA BIOS...\n");
720 9a64fbe4 bellard
}
721 9a64fbe4 bellard
722 9a64fbe4 bellard
void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
723 9a64fbe4 bellard
                  uint32_t kernel_addr, uint32_t kernel_size,
724 9a64fbe4 bellard
                  uint32_t stack_addr, int boot_device)
725 9a64fbe4 bellard
{
726 9a64fbe4 bellard
    char *p;
727 9a64fbe4 bellard
#if !defined (USE_OPEN_FIRMWARE)
728 9a64fbe4 bellard
    char *tmp;
729 9a64fbe4 bellard
    uint32_t tmpi[2];
730 9a64fbe4 bellard
#endif
731 9a64fbe4 bellard
    int PPC_io_memory;
732 9a64fbe4 bellard
    
733 9a64fbe4 bellard
#if defined (USE_OPEN_FIRMWARE)
734 9a64fbe4 bellard
    setup_memory(env, mem_size);
735 9a64fbe4 bellard
#endif
736 9a64fbe4 bellard
    /* Register 64 kB of IO space */
737 9a64fbe4 bellard
    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
738 9a64fbe4 bellard
    cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory);
739 9a64fbe4 bellard
    /* Register fake IO ports for PREP */
740 9a64fbe4 bellard
    register_ioport_read(0x398, 2, PREP_io_read, 1);
741 9a64fbe4 bellard
    register_ioport_write(0x398, 2, PREP_io_write, 1);
742 9a64fbe4 bellard
    /* System control ports */
743 9a64fbe4 bellard
    register_ioport_write(0x0092, 0x1, PREP_io_800_writeb, 1);
744 9a64fbe4 bellard
    register_ioport_read(0x0800, 0x52, PREP_io_800_readb, 1);
745 9a64fbe4 bellard
    register_ioport_write(0x0800, 0x52, PREP_io_800_writeb, 1);
746 9a64fbe4 bellard
    /* PCI intack location */
747 9a64fbe4 bellard
    PPC_io_memory = cpu_register_io_memory(0, PPC_ioB_read, PPC_ioB_write);
748 9a64fbe4 bellard
    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
749 9a64fbe4 bellard
    /* NVRAM ports */
750 9a64fbe4 bellard
    NVRAM_init();
751 9a64fbe4 bellard
    register_ioport_read(0x0074, 0x04, NVRAM_readb, 1);
752 9a64fbe4 bellard
    register_ioport_write(0x0074, 0x04, NVRAM_writeb, 1);
753 9a64fbe4 bellard
754 9a64fbe4 bellard
    /* Fake bootloader */
755 9a64fbe4 bellard
    env->nip = kernel_addr + (3 * sizeof(uint32_t));
756 9a64fbe4 bellard
    /* Set up msr according to PREP specification */
757 9a64fbe4 bellard
    msr_ee = 0;
758 9a64fbe4 bellard
    msr_fp = 1;
759 9a64fbe4 bellard
    msr_pr = 0; /* Start in supervisor mode */
760 9a64fbe4 bellard
    msr_me = 1;
761 9a64fbe4 bellard
    msr_fe0 = msr_fe1 = 0;
762 9a64fbe4 bellard
    msr_ip = 0;
763 9a64fbe4 bellard
    msr_ir = msr_dr = 1;
764 9a64fbe4 bellard
//    msr_sf = 0;
765 9a64fbe4 bellard
    msr_le = msr_ile = 0;
766 9a64fbe4 bellard
    env->gpr[1] = stack_addr; /* Let's have a stack */
767 9a64fbe4 bellard
    env->gpr[2] = 0;
768 9a64fbe4 bellard
    env->gpr[8] = kernel_addr;
769 9a64fbe4 bellard
    /* There is a bug in  2.4 kernels:
770 9a64fbe4 bellard
     * if a decrementer exception is pending when it enables msr_ee,
771 9a64fbe4 bellard
     * it's not ready to handle it...
772 9a64fbe4 bellard
     */
773 9a64fbe4 bellard
    env->decr = 0xFFFFFFFF;
774 9a64fbe4 bellard
    p = (void *)(phys_ram_base + kernel_addr);
775 9a64fbe4 bellard
#if !defined (USE_OPEN_FIRMWARE)
776 9a64fbe4 bellard
    /* Let's register the whole memory available only in supervisor mode */
777 9a64fbe4 bellard
    setup_BAT(env, 0, 0x00000000, 0x00000000, mem_size, 1, 0, 2);
778 9a64fbe4 bellard
    /* Avoid open firmware init call (to get a console)
779 9a64fbe4 bellard
     * This will make the kernel think we are a PREP machine...
780 9a64fbe4 bellard
     */
781 9a64fbe4 bellard
    put_long(p, 0xdeadc0de);
782 9a64fbe4 bellard
    /* Build a real stack room */
783 9a64fbe4 bellard
    p = (void *)(phys_ram_base + stack_addr);
784 9a64fbe4 bellard
    put_long(p, stack_addr);
785 9a64fbe4 bellard
    p -= 32;
786 9a64fbe4 bellard
    env->gpr[1] -= 32;
787 9a64fbe4 bellard
    /* Pretend there are no residual data */
788 9a64fbe4 bellard
    env->gpr[3] = 0;
789 9a64fbe4 bellard
#if 1
790 9a64fbe4 bellard
    {
791 9a64fbe4 bellard
        int size;
792 9a64fbe4 bellard
        env->gpr[4] = 0x00800000;
793 9a64fbe4 bellard
        size = load_initrd("initrd",
794 9a64fbe4 bellard
                           (void *)((uint32_t)phys_ram_base + env->gpr[4]));
795 9a64fbe4 bellard
        if (size < 0) {
796 9a64fbe4 bellard
            /* No initrd */
797 9a64fbe4 bellard
            env->gpr[4] = env->gpr[5] = 0;
798 9a64fbe4 bellard
        } else {
799 9a64fbe4 bellard
            env->gpr[5] = size;
800 9a64fbe4 bellard
            boot_device = 'e';
801 9a64fbe4 bellard
        }
802 9a64fbe4 bellard
        printf("Initrd loaded at 0x%08x (%d)\n", env->gpr[4], env->gpr[5]);
803 9a64fbe4 bellard
    }
804 9a64fbe4 bellard
#else
805 9a64fbe4 bellard
    env->gpr[4] = env->gpr[5] = 0;
806 9a64fbe4 bellard
#endif
807 9a64fbe4 bellard
    /* We have to put bootinfos after the BSS
808 9a64fbe4 bellard
     * The BSS starts after the kernel end.
809 9a64fbe4 bellard
     */
810 9a64fbe4 bellard
#if 0
811 9a64fbe4 bellard
    p = (void *)(((uint32_t)phys_ram_base + kernel_addr +
812 9a64fbe4 bellard
                  kernel_size + (1 << 20) - 1) & ~((1 << 20) - 1));
813 9a64fbe4 bellard
#else
814 9a64fbe4 bellard
    p = (void *)((uint32_t)phys_ram_base + kernel_addr + 0x400000);
815 9a64fbe4 bellard
#endif
816 9a64fbe4 bellard
    if (loglevel > 0) {
817 9a64fbe4 bellard
        fprintf(logfile, "bootinfos: %p 0x%08x\n",
818 9a64fbe4 bellard
                p, (uint32_t)p - (uint32_t)phys_ram_base);
819 9a64fbe4 bellard
    } else {
820 9a64fbe4 bellard
        printf("bootinfos: %p 0x%08x\n",
821 9a64fbe4 bellard
               p, (uint32_t)p - (uint32_t)phys_ram_base);
822 9a64fbe4 bellard
    }
823 9a64fbe4 bellard
    /* Command line: let's put it after bootinfos */
824 9a64fbe4 bellard
#if 0
825 9a64fbe4 bellard
    sprintf(p + 0x1000, "console=ttyS0,9600 root=%02x%02x mem=%dM",
826 9a64fbe4 bellard
            boot_devs[boot_device - 'a'].major,
827 9a64fbe4 bellard
            boot_devs[boot_device - 'a'].minor,
828 9a64fbe4 bellard
            phys_ram_size >> 20);
829 9a64fbe4 bellard
#else
830 9a64fbe4 bellard
    sprintf(p + 0x1000, "console=ttyS0,9600 console=tty0 root=%s mem=%dM load_ramdisk=1",
831 9a64fbe4 bellard
            boot_devs[boot_device - 'a'].name,
832 9a64fbe4 bellard
            phys_ram_size >> 20);
833 9a64fbe4 bellard
#endif
834 9a64fbe4 bellard
    env->gpr[6] = (uint32_t)p + 0x1000 - (uint32_t)phys_ram_base;
835 9a64fbe4 bellard
    env->gpr[7] = env->gpr[6] + strlen(p + 0x1000);
836 9a64fbe4 bellard
    if (loglevel > 0) {
837 9a64fbe4 bellard
        fprintf(logfile, "cmdline: %p 0x%08x [%s]\n",
838 9a64fbe4 bellard
                p + 0x1000, env->gpr[6], p + 0x1000);
839 9a64fbe4 bellard
    } else {
840 9a64fbe4 bellard
        printf("cmdline: %p 0x%08x [%s]\n",
841 9a64fbe4 bellard
               p + 0x1000, env->gpr[6], p + 0x1000);
842 9a64fbe4 bellard
    }
843 9a64fbe4 bellard
    /* BI_FIRST */
844 9a64fbe4 bellard
    p = set_bootinfo_tag(p, 0x1010, 0, 0);
845 9a64fbe4 bellard
    /* BI_CMD_LINE */
846 9a64fbe4 bellard
    p = set_bootinfo_tag(p, 0x1012, env->gpr[7] - env->gpr[6],
847 9a64fbe4 bellard
                         (void *)(env->gpr[6] + (uint32_t)phys_ram_base));
848 9a64fbe4 bellard
    /* BI_MEM_SIZE */
849 9a64fbe4 bellard
    tmp = (void *)tmpi;
850 9a64fbe4 bellard
    tmp[0] = (phys_ram_size >> 24) & 0xFF;
851 9a64fbe4 bellard
    tmp[1] = (phys_ram_size >> 16) & 0xFF;
852 9a64fbe4 bellard
    tmp[2] = (phys_ram_size >> 8) & 0xFF;
853 9a64fbe4 bellard
    tmp[3] = phys_ram_size & 0xFF;
854 9a64fbe4 bellard
    p = set_bootinfo_tag(p, 0x1017, 4, tmpi);
855 9a64fbe4 bellard
    /* BI_INITRD */
856 9a64fbe4 bellard
    tmp[0] = (env->gpr[4] >> 24) & 0xFF;
857 9a64fbe4 bellard
    tmp[1] = (env->gpr[4] >> 16) & 0xFF;
858 9a64fbe4 bellard
    tmp[2] = (env->gpr[4] >> 8) & 0xFF;
859 9a64fbe4 bellard
    tmp[3] = env->gpr[4] & 0xFF;
860 9a64fbe4 bellard
    tmp[4] = (env->gpr[5] >> 24) & 0xFF;
861 9a64fbe4 bellard
    tmp[5] = (env->gpr[5] >> 16) & 0xFF;
862 9a64fbe4 bellard
    tmp[6] = (env->gpr[5] >> 8) & 0xFF;
863 9a64fbe4 bellard
    tmp[7] = env->gpr[5] & 0xFF;
864 9a64fbe4 bellard
    p = set_bootinfo_tag(p, 0x1014, 8, tmpi);
865 9a64fbe4 bellard
    /* BI_LAST */
866 9a64fbe4 bellard
    p = set_bootinfo_tag(p, 0x1011, 0, 0);
867 9a64fbe4 bellard
#else
868 9a64fbe4 bellard
    /* Set up MMU:
869 9a64fbe4 bellard
     * kernel is loaded at kernel_addr and wants to be seen at 0x01000000
870 9a64fbe4 bellard
     */
871 9a64fbe4 bellard
    setup_BAT(env, 0, 0x01000000, kernel_addr, 0x00400000, 1, 0, 2);
872 9a64fbe4 bellard
    {
873 9a64fbe4 bellard
#if 0
874 9a64fbe4 bellard
        uint32_t offset = 
875 9a64fbe4 bellard
            *((uint32_t *)((uint32_t)phys_ram_base + kernel_addr));
876 9a64fbe4 bellard
#else
877 9a64fbe4 bellard
        uint32_t offset = 12;
878 9a64fbe4 bellard
#endif
879 9a64fbe4 bellard
        env->nip = 0x01000000 | (kernel_addr + offset);
880 9a64fbe4 bellard
        printf("Start address: 0x%08x\n", env->nip);
881 9a64fbe4 bellard
    }
882 9a64fbe4 bellard
    env->gpr[1] = env->nip + (1 << 22);
883 9a64fbe4 bellard
    p = (void *)(phys_ram_base + stack_addr);
884 9a64fbe4 bellard
    put_long(p - 32, stack_addr);
885 9a64fbe4 bellard
    env->gpr[1] -= 32;
886 9a64fbe4 bellard
    printf("Kernel starts at 0x%08x stack 0x%08x\n", env->nip, env->gpr[1]);
887 9a64fbe4 bellard
    /* We want all lower address not to be translated */
888 9a64fbe4 bellard
    setup_BAT(env, 1, 0x00000000, 0x00000000, 0x010000000, 1, 1, 2);
889 9a64fbe4 bellard
    /* We also need a BAT to access OF */
890 9a64fbe4 bellard
    setup_BAT(env, 2, 0xFFFE0000, mem_size - 131072, 131072, 1, 0, 1);
891 9a64fbe4 bellard
    /* Setup OF entry point */
892 9a64fbe4 bellard
    {
893 9a64fbe4 bellard
        char *p;
894 9a64fbe4 bellard
        p = (char *)phys_ram_base + mem_size - 131072;
895 9a64fbe4 bellard
        /* Special opcode to call OF */
896 9a64fbe4 bellard
        *p++ = 0x18; *p++ = 0x00; *p++ = 0x00; *p++ = 0x02;
897 9a64fbe4 bellard
        /* blr */
898 9a64fbe4 bellard
        *p++ = 0x4E; *p++ = 0x80; *p++ = 0x00; *p++ = 0x20;
899 9a64fbe4 bellard
    }
900 9a64fbe4 bellard
    env->gpr[5] = 0xFFFE0000;
901 9a64fbe4 bellard
    /* Register translations */
902 9a64fbe4 bellard
    {
903 9a64fbe4 bellard
        OF_transl_t translations[3] = {
904 9a64fbe4 bellard
            { 0x01000000, 0x00400000, kernel_addr, 0x00000002, },
905 9a64fbe4 bellard
            { 0x00000000, 0x01000000, 0x00000000, 0x00000002, },
906 9a64fbe4 bellard
            { 0xFFFE0000, 0x00020000, mem_size - (128 * 1024),
907 9a64fbe4 bellard
              0x00000001, },
908 9a64fbe4 bellard
        };
909 9a64fbe4 bellard
        OF_register_translations(3, translations);
910 9a64fbe4 bellard
    }
911 9a64fbe4 bellard
    /* Quite artificial, for now */
912 9a64fbe4 bellard
    OF_register_bus("isa", "isa");
913 9a64fbe4 bellard
    OF_register_serial("isa", "serial", 4, 0x3f8);
914 9a64fbe4 bellard
    OF_register_stdio("serial", "serial");
915 9a64fbe4 bellard
    /* Set up RTAS service */
916 9a64fbe4 bellard
    RTAS_init();
917 9a64fbe4 bellard
    /* Command line: let's put it just over the stack */
918 9a64fbe4 bellard
#if 1
919 9a64fbe4 bellard
    sprintf(p, "console=ttyS0,9600 root=%02x%02x mem=%dM",
920 9a64fbe4 bellard
            boot_devs[boot_device - 'a'].major,
921 9a64fbe4 bellard
            boot_devs[boot_device - 'a'].minor,
922 9a64fbe4 bellard
            phys_ram_size >> 20);
923 9a64fbe4 bellard
#else
924 9a64fbe4 bellard
    sprintf(p, "console=ttyS0,9600 root=%s mem=%dM ne2000=0x300,9",
925 9a64fbe4 bellard
            boot_devs[boot_device - 'a'].name,
926 9a64fbe4 bellard
            phys_ram_size >> 20);
927 9a64fbe4 bellard
#endif
928 9a64fbe4 bellard
    OF_register_bootargs(p);
929 9a64fbe4 bellard
#endif
930 9a64fbe4 bellard
}
931 9a64fbe4 bellard
932 9a64fbe4 bellard
void PPC_end_init (void)
933 9a64fbe4 bellard
{
934 9a64fbe4 bellard
    VGA_init();
935 9a64fbe4 bellard
}