Statistics
| Branch: | Revision:

root / hw / sun4m.c @ 7fc42b4b

History | View | Annotate | Download (19.6 kB)

1 420557e8 bellard
/*
2 420557e8 bellard
 * QEMU Sun4m System Emulator
3 5fafdf24 ths
 *
4 b81b3b10 bellard
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5fafdf24 ths
 *
6 420557e8 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 420557e8 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 420557e8 bellard
 * in the Software without restriction, including without limitation the rights
9 420557e8 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 420557e8 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 420557e8 bellard
 * furnished to do so, subject to the following conditions:
12 420557e8 bellard
 *
13 420557e8 bellard
 * The above copyright notice and this permission notice shall be included in
14 420557e8 bellard
 * all copies or substantial portions of the Software.
15 420557e8 bellard
 *
16 420557e8 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 420557e8 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 420557e8 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 420557e8 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 420557e8 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 420557e8 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 420557e8 bellard
 * THE SOFTWARE.
23 420557e8 bellard
 */
24 420557e8 bellard
#include "vl.h"
25 b3a23197 blueswir1
//#define DEBUG_IRQ
26 420557e8 bellard
27 36cd9210 blueswir1
/*
28 36cd9210 blueswir1
 * Sun4m architecture was used in the following machines:
29 36cd9210 blueswir1
 *
30 36cd9210 blueswir1
 * SPARCserver 6xxMP/xx
31 36cd9210 blueswir1
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
32 36cd9210 blueswir1
 * SPARCstation LX/ZX (4/30)
33 36cd9210 blueswir1
 * SPARCstation Voyager
34 36cd9210 blueswir1
 * SPARCstation 10/xx, SPARCserver 10/xx
35 36cd9210 blueswir1
 * SPARCstation 5, SPARCserver 5
36 36cd9210 blueswir1
 * SPARCstation 20/xx, SPARCserver 20
37 36cd9210 blueswir1
 * SPARCstation 4
38 36cd9210 blueswir1
 *
39 36cd9210 blueswir1
 * See for example: http://www.sunhelp.org/faq/sunref1.html
40 36cd9210 blueswir1
 */
41 36cd9210 blueswir1
42 b3a23197 blueswir1
#ifdef DEBUG_IRQ
43 b3a23197 blueswir1
#define DPRINTF(fmt, args...)                           \
44 b3a23197 blueswir1
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
45 b3a23197 blueswir1
#else
46 b3a23197 blueswir1
#define DPRINTF(fmt, args...)
47 b3a23197 blueswir1
#endif
48 b3a23197 blueswir1
49 420557e8 bellard
#define KERNEL_LOAD_ADDR     0x00004000
50 b6f479d3 bellard
#define CMDLINE_ADDR         0x007ff000
51 713c45fa bellard
#define INITRD_LOAD_ADDR     0x00800000
52 aa6ad6fe blueswir1
#define PROM_SIZE_MAX        (512 * 1024)
53 40ce0a9a blueswir1
#define PROM_PADDR           0xff0000000ULL
54 40ce0a9a blueswir1
#define PROM_VADDR           0xffd00000
55 f930d07e blueswir1
#define PROM_FILENAME        "openbios-sparc32"
56 b8174937 bellard
57 ba3c64fb bellard
#define MAX_CPUS 16
58 b3a23197 blueswir1
#define MAX_PILS 16
59 420557e8 bellard
60 36cd9210 blueswir1
struct hwdef {
61 5dcb6b91 blueswir1
    target_phys_addr_t iommu_base, slavio_base;
62 5dcb6b91 blueswir1
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
63 5dcb6b91 blueswir1
    target_phys_addr_t serial_base, fd_base;
64 5dcb6b91 blueswir1
    target_phys_addr_t dma_base, esp_base, le_base;
65 5dcb6b91 blueswir1
    target_phys_addr_t tcx_base, cs_base, power_base;
66 36cd9210 blueswir1
    long vram_size, nvram_size;
67 36cd9210 blueswir1
    // IRQ numbers are not PIL ones, but master interrupt controller register
68 36cd9210 blueswir1
    // bit numbers
69 d7edfd27 blueswir1
    int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
70 36cd9210 blueswir1
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
71 36cd9210 blueswir1
    int machine_id; // For NVRAM
72 e0353fe2 blueswir1
    uint32_t intbit_to_level[32];
73 36cd9210 blueswir1
};
74 36cd9210 blueswir1
75 420557e8 bellard
/* TSC handling */
76 420557e8 bellard
77 420557e8 bellard
uint64_t cpu_get_tsc()
78 420557e8 bellard
{
79 420557e8 bellard
    return qemu_get_clock(vm_clock);
80 420557e8 bellard
}
81 420557e8 bellard
82 6f7e9aec bellard
int DMA_get_channel_mode (int nchan)
83 6f7e9aec bellard
{
84 6f7e9aec bellard
    return 0;
85 6f7e9aec bellard
}
86 6f7e9aec bellard
int DMA_read_memory (int nchan, void *buf, int pos, int size)
87 6f7e9aec bellard
{
88 6f7e9aec bellard
    return 0;
89 6f7e9aec bellard
}
90 6f7e9aec bellard
int DMA_write_memory (int nchan, void *buf, int pos, int size)
91 6f7e9aec bellard
{
92 6f7e9aec bellard
    return 0;
93 6f7e9aec bellard
}
94 6f7e9aec bellard
void DMA_hold_DREQ (int nchan) {}
95 6f7e9aec bellard
void DMA_release_DREQ (int nchan) {}
96 6f7e9aec bellard
void DMA_schedule(int nchan) {}
97 6f7e9aec bellard
void DMA_run (void) {}
98 6f7e9aec bellard
void DMA_init (int high_page_enable) {}
99 6f7e9aec bellard
void DMA_register_channel (int nchan,
100 6f7e9aec bellard
                           DMA_transfer_handler transfer_handler,
101 6f7e9aec bellard
                           void *opaque)
102 6f7e9aec bellard
{
103 6f7e9aec bellard
}
104 6f7e9aec bellard
105 819385c5 bellard
static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
106 6f7e9aec bellard
{
107 819385c5 bellard
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
108 819385c5 bellard
    m48t59_write(nvram, addr++, value & 0xff);
109 6f7e9aec bellard
}
110 6f7e9aec bellard
111 819385c5 bellard
static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
112 6f7e9aec bellard
{
113 819385c5 bellard
    m48t59_write(nvram, addr++, value >> 24);
114 819385c5 bellard
    m48t59_write(nvram, addr++, (value >> 16) & 0xff);
115 819385c5 bellard
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
116 819385c5 bellard
    m48t59_write(nvram, addr++, value & 0xff);
117 6f7e9aec bellard
}
118 6f7e9aec bellard
119 819385c5 bellard
static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
120 6f7e9aec bellard
                       const unsigned char *str, uint32_t max)
121 6f7e9aec bellard
{
122 6f7e9aec bellard
    unsigned int i;
123 6f7e9aec bellard
124 6f7e9aec bellard
    for (i = 0; i < max && str[i] != '\0'; i++) {
125 819385c5 bellard
        m48t59_write(nvram, addr + i, str[i]);
126 6f7e9aec bellard
    }
127 819385c5 bellard
    m48t59_write(nvram, addr + max - 1, '\0');
128 6f7e9aec bellard
}
129 420557e8 bellard
130 66508601 blueswir1
static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr,
131 66508601 blueswir1
                                const unsigned char *str)
132 66508601 blueswir1
{
133 66508601 blueswir1
    uint32_t len;
134 66508601 blueswir1
135 66508601 blueswir1
    len = strlen(str) + 1;
136 66508601 blueswir1
    nvram_set_string(nvram, addr, str, len);
137 66508601 blueswir1
138 66508601 blueswir1
    return addr + len;
139 66508601 blueswir1
}
140 66508601 blueswir1
141 66508601 blueswir1
static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
142 66508601 blueswir1
                                    uint32_t end)
143 66508601 blueswir1
{
144 66508601 blueswir1
    unsigned int i, sum;
145 66508601 blueswir1
146 66508601 blueswir1
    // Length divided by 16
147 66508601 blueswir1
    m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff);
148 66508601 blueswir1
    m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff);
149 66508601 blueswir1
    // Checksum
150 66508601 blueswir1
    sum = m48t59_read(nvram, start);
151 66508601 blueswir1
    for (i = 0; i < 14; i++) {
152 66508601 blueswir1
        sum += m48t59_read(nvram, start + 2 + i);
153 66508601 blueswir1
        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
154 66508601 blueswir1
    }
155 66508601 blueswir1
    m48t59_write(nvram, start + 1, sum & 0xff);
156 66508601 blueswir1
}
157 66508601 blueswir1
158 6f7e9aec bellard
extern int nographic;
159 6f7e9aec bellard
160 819385c5 bellard
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
161 6ac0e82d balrog
                       const char *boot_device, uint32_t RAM_size,
162 f930d07e blueswir1
                       uint32_t kernel_size,
163 f930d07e blueswir1
                       int width, int height, int depth,
164 36cd9210 blueswir1
                       int machine_id)
165 e80cfcfc bellard
{
166 e80cfcfc bellard
    unsigned char tmp = 0;
167 66508601 blueswir1
    unsigned int i, j;
168 66508601 blueswir1
    uint32_t start, end;
169 e80cfcfc bellard
170 6f7e9aec bellard
    // Try to match PPC NVRAM
171 6f7e9aec bellard
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
172 6f7e9aec bellard
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
173 6f7e9aec bellard
    // NVRAM_size, arch not applicable
174 ba3c64fb bellard
    m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
175 ba3c64fb bellard
    m48t59_write(nvram, 0x2E, 0);
176 819385c5 bellard
    m48t59_write(nvram, 0x2F, nographic & 0xff);
177 6f7e9aec bellard
    nvram_set_lword(nvram,  0x30, RAM_size);
178 6ac0e82d balrog
    m48t59_write(nvram, 0x34, boot_device[0] & 0xff);
179 6f7e9aec bellard
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
180 6f7e9aec bellard
    nvram_set_lword(nvram,  0x3C, kernel_size);
181 b6f479d3 bellard
    if (cmdline) {
182 f930d07e blueswir1
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
183 f930d07e blueswir1
        nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
184 6f7e9aec bellard
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
185 b6f479d3 bellard
    }
186 6f7e9aec bellard
    // initrd_image, initrd_size passed differently
187 6f7e9aec bellard
    nvram_set_word(nvram,   0x54, width);
188 6f7e9aec bellard
    nvram_set_word(nvram,   0x56, height);
189 6f7e9aec bellard
    nvram_set_word(nvram,   0x58, depth);
190 b6f479d3 bellard
191 66508601 blueswir1
    // OpenBIOS nvram variables
192 66508601 blueswir1
    // Variable partition
193 66508601 blueswir1
    start = 252;
194 66508601 blueswir1
    m48t59_write(nvram, start, 0x70);
195 66508601 blueswir1
    nvram_set_string(nvram, start + 4, "system", 12);
196 66508601 blueswir1
197 66508601 blueswir1
    end = start + 16;
198 66508601 blueswir1
    for (i = 0; i < nb_prom_envs; i++)
199 66508601 blueswir1
        end = nvram_set_var(nvram, end, prom_envs[i]);
200 66508601 blueswir1
201 66508601 blueswir1
    m48t59_write(nvram, end++ , 0);
202 66508601 blueswir1
    end = start + ((end - start + 15) & ~15);
203 66508601 blueswir1
    nvram_finish_partition(nvram, start, end);
204 66508601 blueswir1
205 66508601 blueswir1
    // free partition
206 66508601 blueswir1
    start = end;
207 66508601 blueswir1
    m48t59_write(nvram, start, 0x7f);
208 66508601 blueswir1
    nvram_set_string(nvram, start + 4, "free", 12);
209 66508601 blueswir1
210 66508601 blueswir1
    end = 0x1fd0;
211 66508601 blueswir1
    nvram_finish_partition(nvram, start, end);
212 66508601 blueswir1
213 6f7e9aec bellard
    // Sun4m specific use
214 66508601 blueswir1
    start = i = 0x1fd8;
215 819385c5 bellard
    m48t59_write(nvram, i++, 0x01);
216 36cd9210 blueswir1
    m48t59_write(nvram, i++, machine_id);
217 e80cfcfc bellard
    j = 0;
218 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
219 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
220 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
221 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
222 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
223 819385c5 bellard
    m48t59_write(nvram, i, macaddr[j]);
224 e80cfcfc bellard
225 e80cfcfc bellard
    /* Calculate checksum */
226 66508601 blueswir1
    for (i = start; i < start + 15; i++) {
227 66508601 blueswir1
        tmp ^= m48t59_read(nvram, i);
228 e80cfcfc bellard
    }
229 66508601 blueswir1
    m48t59_write(nvram, start + 15, tmp);
230 e80cfcfc bellard
}
231 e80cfcfc bellard
232 e80cfcfc bellard
static void *slavio_intctl;
233 e80cfcfc bellard
234 e80cfcfc bellard
void pic_info()
235 e80cfcfc bellard
{
236 e80cfcfc bellard
    slavio_pic_info(slavio_intctl);
237 e80cfcfc bellard
}
238 e80cfcfc bellard
239 e80cfcfc bellard
void irq_info()
240 e80cfcfc bellard
{
241 e80cfcfc bellard
    slavio_irq_info(slavio_intctl);
242 e80cfcfc bellard
}
243 e80cfcfc bellard
244 327ac2e7 blueswir1
void cpu_check_irqs(CPUState *env)
245 327ac2e7 blueswir1
{
246 327ac2e7 blueswir1
    if (env->pil_in && (env->interrupt_index == 0 ||
247 327ac2e7 blueswir1
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
248 327ac2e7 blueswir1
        unsigned int i;
249 327ac2e7 blueswir1
250 327ac2e7 blueswir1
        for (i = 15; i > 0; i--) {
251 327ac2e7 blueswir1
            if (env->pil_in & (1 << i)) {
252 327ac2e7 blueswir1
                int old_interrupt = env->interrupt_index;
253 327ac2e7 blueswir1
254 327ac2e7 blueswir1
                env->interrupt_index = TT_EXTINT | i;
255 327ac2e7 blueswir1
                if (old_interrupt != env->interrupt_index)
256 327ac2e7 blueswir1
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
257 327ac2e7 blueswir1
                break;
258 327ac2e7 blueswir1
            }
259 327ac2e7 blueswir1
        }
260 327ac2e7 blueswir1
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
261 327ac2e7 blueswir1
        env->interrupt_index = 0;
262 327ac2e7 blueswir1
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
263 327ac2e7 blueswir1
    }
264 327ac2e7 blueswir1
}
265 327ac2e7 blueswir1
266 b3a23197 blueswir1
static void cpu_set_irq(void *opaque, int irq, int level)
267 b3a23197 blueswir1
{
268 b3a23197 blueswir1
    CPUState *env = opaque;
269 b3a23197 blueswir1
270 b3a23197 blueswir1
    if (level) {
271 b3a23197 blueswir1
        DPRINTF("Raise CPU IRQ %d\n", irq);
272 b3a23197 blueswir1
        env->halted = 0;
273 327ac2e7 blueswir1
        env->pil_in |= 1 << irq;
274 327ac2e7 blueswir1
        cpu_check_irqs(env);
275 b3a23197 blueswir1
    } else {
276 b3a23197 blueswir1
        DPRINTF("Lower CPU IRQ %d\n", irq);
277 327ac2e7 blueswir1
        env->pil_in &= ~(1 << irq);
278 327ac2e7 blueswir1
        cpu_check_irqs(env);
279 b3a23197 blueswir1
    }
280 b3a23197 blueswir1
}
281 b3a23197 blueswir1
282 b3a23197 blueswir1
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
283 b3a23197 blueswir1
{
284 b3a23197 blueswir1
}
285 b3a23197 blueswir1
286 3475187d bellard
static void *slavio_misc;
287 3475187d bellard
288 3475187d bellard
void qemu_system_powerdown(void)
289 3475187d bellard
{
290 3475187d bellard
    slavio_set_power_fail(slavio_misc, 1);
291 3475187d bellard
}
292 3475187d bellard
293 c68ea704 bellard
static void main_cpu_reset(void *opaque)
294 c68ea704 bellard
{
295 c68ea704 bellard
    CPUState *env = opaque;
296 3d29fbef blueswir1
297 3d29fbef blueswir1
    cpu_reset(env);
298 3d29fbef blueswir1
    env->halted = 0;
299 3d29fbef blueswir1
}
300 3d29fbef blueswir1
301 3d29fbef blueswir1
static void secondary_cpu_reset(void *opaque)
302 3d29fbef blueswir1
{
303 3d29fbef blueswir1
    CPUState *env = opaque;
304 3d29fbef blueswir1
305 c68ea704 bellard
    cpu_reset(env);
306 3d29fbef blueswir1
    env->halted = 1;
307 c68ea704 bellard
}
308 c68ea704 bellard
309 b3ceef24 blueswir1
static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
310 b3ceef24 blueswir1
                           DisplayState *ds, const char *cpu_model)
311 36cd9210 blueswir1
312 420557e8 bellard
{
313 ba3c64fb bellard
    CPUState *env, *envs[MAX_CPUS];
314 713c45fa bellard
    unsigned int i;
315 b3ceef24 blueswir1
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
316 62724a37 blueswir1
    const sparc_def_t *def;
317 b3a23197 blueswir1
    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
318 d7edfd27 blueswir1
        *espdma_irq, *ledma_irq;
319 2d069bab blueswir1
    qemu_irq *esp_reset, *le_reset;
320 420557e8 bellard
321 ba3c64fb bellard
    /* init CPUs */
322 62724a37 blueswir1
    sparc_find_by_name(cpu_model, &def);
323 62724a37 blueswir1
    if (def == NULL) {
324 62724a37 blueswir1
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
325 62724a37 blueswir1
        exit(1);
326 62724a37 blueswir1
    }
327 b3a23197 blueswir1
328 ba3c64fb bellard
    for(i = 0; i < smp_cpus; i++) {
329 ba3c64fb bellard
        env = cpu_init();
330 952a328f blueswir1
        cpu_sparc_register(env, def, i);
331 ba3c64fb bellard
        envs[i] = env;
332 3d29fbef blueswir1
        if (i == 0) {
333 3d29fbef blueswir1
            qemu_register_reset(main_cpu_reset, env);
334 3d29fbef blueswir1
        } else {
335 3d29fbef blueswir1
            qemu_register_reset(secondary_cpu_reset, env);
336 ba3c64fb bellard
            env->halted = 1;
337 3d29fbef blueswir1
        }
338 ba3c64fb bellard
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
339 b3a23197 blueswir1
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
340 ba3c64fb bellard
    }
341 b3a23197 blueswir1
342 b3a23197 blueswir1
    for (i = smp_cpus; i < MAX_CPUS; i++)
343 b3a23197 blueswir1
        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
344 b3a23197 blueswir1
345 420557e8 bellard
    /* allocate RAM */
346 b3ceef24 blueswir1
    cpu_register_physical_memory(0, RAM_size, 0);
347 420557e8 bellard
348 36cd9210 blueswir1
    iommu = iommu_init(hwdef->iommu_base);
349 36cd9210 blueswir1
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
350 5dcb6b91 blueswir1
                                       hwdef->intctl_base + 0x10000ULL,
351 d537cf6c pbrook
                                       &hwdef->intbit_to_level[0],
352 d7edfd27 blueswir1
                                       &slavio_irq, &slavio_cpu_irq,
353 b3a23197 blueswir1
                                       cpu_irqs,
354 d7edfd27 blueswir1
                                       hwdef->clock_irq);
355 b3a23197 blueswir1
356 5aca8c3b blueswir1
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
357 2d069bab blueswir1
                              iommu, &espdma_irq, &esp_reset);
358 2d069bab blueswir1
359 5aca8c3b blueswir1
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
360 2d069bab blueswir1
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
361 2d069bab blueswir1
                             &le_reset);
362 ba3c64fb bellard
363 eee0b836 blueswir1
    if (graphic_depth != 8 && graphic_depth != 24) {
364 eee0b836 blueswir1
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
365 eee0b836 blueswir1
        exit (1);
366 eee0b836 blueswir1
    }
367 b3ceef24 blueswir1
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
368 eee0b836 blueswir1
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
369 dbe06e18 blueswir1
370 dbe06e18 blueswir1
    if (nd_table[0].model == NULL
371 dbe06e18 blueswir1
        || strcmp(nd_table[0].model, "lance") == 0) {
372 2d069bab blueswir1
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
373 c4a7060c blueswir1
    } else if (strcmp(nd_table[0].model, "?") == 0) {
374 c4a7060c blueswir1
        fprintf(stderr, "qemu: Supported NICs: lance\n");
375 c4a7060c blueswir1
        exit (1);
376 dbe06e18 blueswir1
    } else {
377 dbe06e18 blueswir1
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
378 dbe06e18 blueswir1
        exit (1);
379 a41b2ff2 pbrook
    }
380 dbe06e18 blueswir1
381 d537cf6c pbrook
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
382 d537cf6c pbrook
                        hwdef->nvram_size, 8);
383 81732d19 blueswir1
384 81732d19 blueswir1
    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
385 81732d19 blueswir1
                          slavio_cpu_irq);
386 81732d19 blueswir1
387 d537cf6c pbrook
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
388 b81b3b10 bellard
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
389 b81b3b10 bellard
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
390 d537cf6c pbrook
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
391 d537cf6c pbrook
                       serial_hds[1], serial_hds[0]);
392 d537cf6c pbrook
    fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
393 2d069bab blueswir1
394 2d069bab blueswir1
    main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
395 2d069bab blueswir1
                        esp_reset);
396 f1587550 ths
397 f1587550 ths
    for (i = 0; i < MAX_DISKS; i++) {
398 f1587550 ths
        if (bs_table[i]) {
399 f1587550 ths
            esp_scsi_attach(main_esp, bs_table[i], i);
400 f1587550 ths
        }
401 f1587550 ths
    }
402 f1587550 ths
403 5dcb6b91 blueswir1
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
404 d537cf6c pbrook
                                   slavio_irq[hwdef->me_irq]);
405 5dcb6b91 blueswir1
    if (hwdef->cs_base != (target_phys_addr_t)-1)
406 803b3c7b blueswir1
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
407 b3ceef24 blueswir1
408 b3ceef24 blueswir1
    return nvram;
409 36cd9210 blueswir1
}
410 36cd9210 blueswir1
411 6ac0e82d balrog
static void sun4m_load_kernel(long vram_size, int RAM_size,
412 6ac0e82d balrog
                              const char *boot_device,
413 36cd9210 blueswir1
                              const char *kernel_filename,
414 36cd9210 blueswir1
                              const char *kernel_cmdline,
415 36cd9210 blueswir1
                              const char *initrd_filename,
416 b3ceef24 blueswir1
                              int machine_id,
417 b3ceef24 blueswir1
                              void *nvram)
418 36cd9210 blueswir1
{
419 36cd9210 blueswir1
    int ret, linux_boot;
420 36cd9210 blueswir1
    char buf[1024];
421 36cd9210 blueswir1
    unsigned int i;
422 36cd9210 blueswir1
    long prom_offset, initrd_size, kernel_size;
423 36cd9210 blueswir1
424 36cd9210 blueswir1
    linux_boot = (kernel_filename != NULL);
425 420557e8 bellard
426 b3ceef24 blueswir1
    prom_offset = RAM_size + vram_size;
427 40ce0a9a blueswir1
    cpu_register_physical_memory(PROM_PADDR,
428 5fafdf24 ths
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
429 b3783731 bellard
                                 prom_offset | IO_MEM_ROM);
430 e80cfcfc bellard
431 1192dad8 j_mayer
    if (bios_name == NULL)
432 1192dad8 j_mayer
        bios_name = PROM_FILENAME;
433 1192dad8 j_mayer
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
434 40ce0a9a blueswir1
    ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
435 aa6ad6fe blueswir1
    if (ret < 0 || ret > PROM_SIZE_MAX)
436 aa6ad6fe blueswir1
        ret = load_image(buf, phys_ram_base + prom_offset);
437 aa6ad6fe blueswir1
    if (ret < 0 || ret > PROM_SIZE_MAX) {
438 aa6ad6fe blueswir1
        fprintf(stderr, "qemu: could not load prom '%s'\n",
439 aa6ad6fe blueswir1
                buf);
440 aa6ad6fe blueswir1
        exit(1);
441 e80cfcfc bellard
    }
442 e80cfcfc bellard
443 6f7e9aec bellard
    kernel_size = 0;
444 e80cfcfc bellard
    if (linux_boot) {
445 0bd5f4ce blueswir1
        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
446 0bd5f4ce blueswir1
                               NULL);
447 6f7e9aec bellard
        if (kernel_size < 0)
448 f930d07e blueswir1
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
449 f930d07e blueswir1
        if (kernel_size < 0)
450 f930d07e blueswir1
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
451 6f7e9aec bellard
        if (kernel_size < 0) {
452 5fafdf24 ths
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
453 e80cfcfc bellard
                    kernel_filename);
454 f930d07e blueswir1
            exit(1);
455 420557e8 bellard
        }
456 713c45fa bellard
457 713c45fa bellard
        /* load initrd */
458 713c45fa bellard
        initrd_size = 0;
459 713c45fa bellard
        if (initrd_filename) {
460 713c45fa bellard
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
461 713c45fa bellard
            if (initrd_size < 0) {
462 5fafdf24 ths
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
463 713c45fa bellard
                        initrd_filename);
464 713c45fa bellard
                exit(1);
465 713c45fa bellard
            }
466 713c45fa bellard
        }
467 713c45fa bellard
        if (initrd_size > 0) {
468 f930d07e blueswir1
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
469 f930d07e blueswir1
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
470 f930d07e blueswir1
                    == 0x48647253) { // HdrS
471 f930d07e blueswir1
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
472 f930d07e blueswir1
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
473 f930d07e blueswir1
                    break;
474 f930d07e blueswir1
                }
475 f930d07e blueswir1
            }
476 713c45fa bellard
        }
477 420557e8 bellard
    }
478 36cd9210 blueswir1
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
479 b3ceef24 blueswir1
               boot_device, RAM_size, kernel_size, graphic_width,
480 36cd9210 blueswir1
               graphic_height, graphic_depth, machine_id);
481 36cd9210 blueswir1
}
482 36cd9210 blueswir1
483 36cd9210 blueswir1
static const struct hwdef hwdefs[] = {
484 36cd9210 blueswir1
    /* SS-5 */
485 36cd9210 blueswir1
    {
486 36cd9210 blueswir1
        .iommu_base   = 0x10000000,
487 36cd9210 blueswir1
        .tcx_base     = 0x50000000,
488 36cd9210 blueswir1
        .cs_base      = 0x6c000000,
489 384ccb5d blueswir1
        .slavio_base  = 0x70000000,
490 36cd9210 blueswir1
        .ms_kb_base   = 0x71000000,
491 36cd9210 blueswir1
        .serial_base  = 0x71100000,
492 36cd9210 blueswir1
        .nvram_base   = 0x71200000,
493 36cd9210 blueswir1
        .fd_base      = 0x71400000,
494 36cd9210 blueswir1
        .counter_base = 0x71d00000,
495 36cd9210 blueswir1
        .intctl_base  = 0x71e00000,
496 36cd9210 blueswir1
        .dma_base     = 0x78400000,
497 36cd9210 blueswir1
        .esp_base     = 0x78800000,
498 36cd9210 blueswir1
        .le_base      = 0x78c00000,
499 5dcb6b91 blueswir1
        .power_base   = 0x7a000000,
500 36cd9210 blueswir1
        .vram_size    = 0x00100000,
501 36cd9210 blueswir1
        .nvram_size   = 0x2000,
502 36cd9210 blueswir1
        .esp_irq = 18,
503 36cd9210 blueswir1
        .le_irq = 16,
504 36cd9210 blueswir1
        .clock_irq = 7,
505 36cd9210 blueswir1
        .clock1_irq = 19,
506 36cd9210 blueswir1
        .ms_kb_irq = 14,
507 36cd9210 blueswir1
        .ser_irq = 15,
508 36cd9210 blueswir1
        .fd_irq = 22,
509 36cd9210 blueswir1
        .me_irq = 30,
510 36cd9210 blueswir1
        .cs_irq = 5,
511 36cd9210 blueswir1
        .machine_id = 0x80,
512 e0353fe2 blueswir1
        .intbit_to_level = {
513 f930d07e blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
514 f930d07e blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
515 e0353fe2 blueswir1
        },
516 e0353fe2 blueswir1
    },
517 e0353fe2 blueswir1
    /* SS-10 */
518 e0353fe2 blueswir1
    {
519 5dcb6b91 blueswir1
        .iommu_base   = 0xfe0000000ULL,
520 5dcb6b91 blueswir1
        .tcx_base     = 0xe20000000ULL,
521 803b3c7b blueswir1
        .cs_base      = -1,
522 5dcb6b91 blueswir1
        .slavio_base  = 0xff0000000ULL,
523 5dcb6b91 blueswir1
        .ms_kb_base   = 0xff1000000ULL,
524 5dcb6b91 blueswir1
        .serial_base  = 0xff1100000ULL,
525 5dcb6b91 blueswir1
        .nvram_base   = 0xff1200000ULL,
526 5dcb6b91 blueswir1
        .fd_base      = 0xff1700000ULL,
527 5dcb6b91 blueswir1
        .counter_base = 0xff1300000ULL,
528 5dcb6b91 blueswir1
        .intctl_base  = 0xff1400000ULL,
529 5dcb6b91 blueswir1
        .dma_base     = 0xef0400000ULL,
530 5dcb6b91 blueswir1
        .esp_base     = 0xef0800000ULL,
531 5dcb6b91 blueswir1
        .le_base      = 0xef0c00000ULL,
532 5dcb6b91 blueswir1
        .power_base   = 0xefa000000ULL,
533 e0353fe2 blueswir1
        .vram_size    = 0x00100000,
534 e0353fe2 blueswir1
        .nvram_size   = 0x2000,
535 e0353fe2 blueswir1
        .esp_irq = 18,
536 e0353fe2 blueswir1
        .le_irq = 16,
537 e0353fe2 blueswir1
        .clock_irq = 7,
538 e0353fe2 blueswir1
        .clock1_irq = 19,
539 e0353fe2 blueswir1
        .ms_kb_irq = 14,
540 e0353fe2 blueswir1
        .ser_irq = 15,
541 e0353fe2 blueswir1
        .fd_irq = 22,
542 e0353fe2 blueswir1
        .me_irq = 30,
543 803b3c7b blueswir1
        .cs_irq = -1,
544 803b3c7b blueswir1
        .machine_id = 0x72,
545 e0353fe2 blueswir1
        .intbit_to_level = {
546 f930d07e blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
547 f930d07e blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
548 e0353fe2 blueswir1
        },
549 36cd9210 blueswir1
    },
550 36cd9210 blueswir1
};
551 36cd9210 blueswir1
552 6ac0e82d balrog
static void sun4m_common_init(int RAM_size, const char *boot_device, DisplayState *ds,
553 36cd9210 blueswir1
                              const char *kernel_filename, const char *kernel_cmdline,
554 36cd9210 blueswir1
                              const char *initrd_filename, const char *cpu_model,
555 4edebb0e blueswir1
                              unsigned int machine, int max_ram)
556 36cd9210 blueswir1
{
557 b3ceef24 blueswir1
    void *nvram;
558 b3ceef24 blueswir1
559 b3ceef24 blueswir1
    if ((unsigned int)RAM_size > (unsigned int)max_ram) {
560 4edebb0e blueswir1
        fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
561 b3ceef24 blueswir1
                (unsigned int)RAM_size / (1024 * 1024),
562 5dcb6b91 blueswir1
                (unsigned int)max_ram / (1024 * 1024));
563 4edebb0e blueswir1
        exit(1);
564 4edebb0e blueswir1
    }
565 b3ceef24 blueswir1
    nvram = sun4m_hw_init(&hwdefs[machine], RAM_size, ds, cpu_model);
566 36cd9210 blueswir1
567 b3ceef24 blueswir1
    sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
568 36cd9210 blueswir1
                      kernel_filename, kernel_cmdline, initrd_filename,
569 b3ceef24 blueswir1
                      hwdefs[machine].machine_id, nvram);
570 36cd9210 blueswir1
}
571 36cd9210 blueswir1
572 36cd9210 blueswir1
/* SPARCstation 5 hardware initialisation */
573 6ac0e82d balrog
static void ss5_init(int RAM_size, int vga_ram_size, const char *boot_device,
574 36cd9210 blueswir1
                       DisplayState *ds, const char **fd_filename, int snapshot,
575 36cd9210 blueswir1
                       const char *kernel_filename, const char *kernel_cmdline,
576 36cd9210 blueswir1
                       const char *initrd_filename, const char *cpu_model)
577 36cd9210 blueswir1
{
578 36cd9210 blueswir1
    if (cpu_model == NULL)
579 36cd9210 blueswir1
        cpu_model = "Fujitsu MB86904";
580 b3ceef24 blueswir1
    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
581 36cd9210 blueswir1
                      kernel_cmdline, initrd_filename, cpu_model,
582 4edebb0e blueswir1
                      0, 0x10000000);
583 420557e8 bellard
}
584 c0e564d5 bellard
585 e0353fe2 blueswir1
/* SPARCstation 10 hardware initialisation */
586 6ac0e82d balrog
static void ss10_init(int RAM_size, int vga_ram_size, const char *boot_device,
587 e0353fe2 blueswir1
                            DisplayState *ds, const char **fd_filename, int snapshot,
588 e0353fe2 blueswir1
                            const char *kernel_filename, const char *kernel_cmdline,
589 e0353fe2 blueswir1
                            const char *initrd_filename, const char *cpu_model)
590 e0353fe2 blueswir1
{
591 e0353fe2 blueswir1
    if (cpu_model == NULL)
592 e0353fe2 blueswir1
        cpu_model = "TI SuperSparc II";
593 b3ceef24 blueswir1
    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
594 e0353fe2 blueswir1
                      kernel_cmdline, initrd_filename, cpu_model,
595 40ce0a9a blueswir1
                      1, 0xffffffff); // XXX actually first 62GB ok
596 e0353fe2 blueswir1
}
597 e0353fe2 blueswir1
598 36cd9210 blueswir1
QEMUMachine ss5_machine = {
599 36cd9210 blueswir1
    "SS-5",
600 36cd9210 blueswir1
    "Sun4m platform, SPARCstation 5",
601 36cd9210 blueswir1
    ss5_init,
602 c0e564d5 bellard
};
603 e0353fe2 blueswir1
604 e0353fe2 blueswir1
QEMUMachine ss10_machine = {
605 e0353fe2 blueswir1
    "SS-10",
606 e0353fe2 blueswir1
    "Sun4m platform, SPARCstation 10",
607 e0353fe2 blueswir1
    ss10_init,
608 e0353fe2 blueswir1
};