Statistics
| Branch: | Revision:

root / hw / sun4m.c @ e4bcb14c

History | View | Annotate | Download (20.7 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 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "qemu-timer.h"
26 87ecb68b pbrook
#include "sun4m.h"
27 87ecb68b pbrook
#include "nvram.h"
28 87ecb68b pbrook
#include "sparc32_dma.h"
29 87ecb68b pbrook
#include "fdc.h"
30 87ecb68b pbrook
#include "sysemu.h"
31 87ecb68b pbrook
#include "net.h"
32 87ecb68b pbrook
#include "boards.h"
33 d2c63fc1 blueswir1
#include "firmware_abi.h"
34 d2c63fc1 blueswir1
35 b3a23197 blueswir1
//#define DEBUG_IRQ
36 420557e8 bellard
37 36cd9210 blueswir1
/*
38 36cd9210 blueswir1
 * Sun4m architecture was used in the following machines:
39 36cd9210 blueswir1
 *
40 36cd9210 blueswir1
 * SPARCserver 6xxMP/xx
41 36cd9210 blueswir1
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
42 36cd9210 blueswir1
 * SPARCstation LX/ZX (4/30)
43 36cd9210 blueswir1
 * SPARCstation Voyager
44 36cd9210 blueswir1
 * SPARCstation 10/xx, SPARCserver 10/xx
45 36cd9210 blueswir1
 * SPARCstation 5, SPARCserver 5
46 36cd9210 blueswir1
 * SPARCstation 20/xx, SPARCserver 20
47 36cd9210 blueswir1
 * SPARCstation 4
48 36cd9210 blueswir1
 *
49 36cd9210 blueswir1
 * See for example: http://www.sunhelp.org/faq/sunref1.html
50 36cd9210 blueswir1
 */
51 36cd9210 blueswir1
52 b3a23197 blueswir1
#ifdef DEBUG_IRQ
53 b3a23197 blueswir1
#define DPRINTF(fmt, args...)                           \
54 b3a23197 blueswir1
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
55 b3a23197 blueswir1
#else
56 b3a23197 blueswir1
#define DPRINTF(fmt, args...)
57 b3a23197 blueswir1
#endif
58 b3a23197 blueswir1
59 420557e8 bellard
#define KERNEL_LOAD_ADDR     0x00004000
60 b6f479d3 bellard
#define CMDLINE_ADDR         0x007ff000
61 713c45fa bellard
#define INITRD_LOAD_ADDR     0x00800000
62 aa6ad6fe blueswir1
#define PROM_SIZE_MAX        (512 * 1024)
63 40ce0a9a blueswir1
#define PROM_VADDR           0xffd00000
64 f930d07e blueswir1
#define PROM_FILENAME        "openbios-sparc32"
65 b8174937 bellard
66 ba3c64fb bellard
#define MAX_CPUS 16
67 b3a23197 blueswir1
#define MAX_PILS 16
68 420557e8 bellard
69 36cd9210 blueswir1
struct hwdef {
70 5dcb6b91 blueswir1
    target_phys_addr_t iommu_base, slavio_base;
71 5dcb6b91 blueswir1
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
72 5dcb6b91 blueswir1
    target_phys_addr_t serial_base, fd_base;
73 5dcb6b91 blueswir1
    target_phys_addr_t dma_base, esp_base, le_base;
74 5dcb6b91 blueswir1
    target_phys_addr_t tcx_base, cs_base, power_base;
75 36cd9210 blueswir1
    long vram_size, nvram_size;
76 36cd9210 blueswir1
    // IRQ numbers are not PIL ones, but master interrupt controller register
77 36cd9210 blueswir1
    // bit numbers
78 d7edfd27 blueswir1
    int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
79 36cd9210 blueswir1
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
80 36cd9210 blueswir1
    int machine_id; // For NVRAM
81 7fbfb139 blueswir1
    uint32_t iommu_version;
82 e0353fe2 blueswir1
    uint32_t intbit_to_level[32];
83 3ebf5aaf blueswir1
    uint64_t max_mem;
84 3ebf5aaf blueswir1
    const char * const default_cpu_model;
85 36cd9210 blueswir1
};
86 36cd9210 blueswir1
87 420557e8 bellard
/* TSC handling */
88 420557e8 bellard
89 420557e8 bellard
uint64_t cpu_get_tsc()
90 420557e8 bellard
{
91 420557e8 bellard
    return qemu_get_clock(vm_clock);
92 420557e8 bellard
}
93 420557e8 bellard
94 6f7e9aec bellard
int DMA_get_channel_mode (int nchan)
95 6f7e9aec bellard
{
96 6f7e9aec bellard
    return 0;
97 6f7e9aec bellard
}
98 6f7e9aec bellard
int DMA_read_memory (int nchan, void *buf, int pos, int size)
99 6f7e9aec bellard
{
100 6f7e9aec bellard
    return 0;
101 6f7e9aec bellard
}
102 6f7e9aec bellard
int DMA_write_memory (int nchan, void *buf, int pos, int size)
103 6f7e9aec bellard
{
104 6f7e9aec bellard
    return 0;
105 6f7e9aec bellard
}
106 6f7e9aec bellard
void DMA_hold_DREQ (int nchan) {}
107 6f7e9aec bellard
void DMA_release_DREQ (int nchan) {}
108 6f7e9aec bellard
void DMA_schedule(int nchan) {}
109 6f7e9aec bellard
void DMA_run (void) {}
110 6f7e9aec bellard
void DMA_init (int high_page_enable) {}
111 6f7e9aec bellard
void DMA_register_channel (int nchan,
112 6f7e9aec bellard
                           DMA_transfer_handler transfer_handler,
113 6f7e9aec bellard
                           void *opaque)
114 6f7e9aec bellard
{
115 6f7e9aec bellard
}
116 6f7e9aec bellard
117 6f7e9aec bellard
extern int nographic;
118 6f7e9aec bellard
119 819385c5 bellard
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
120 d2c63fc1 blueswir1
                       const char *boot_devices, uint32_t RAM_size,
121 f930d07e blueswir1
                       uint32_t kernel_size,
122 f930d07e blueswir1
                       int width, int height, int depth,
123 36cd9210 blueswir1
                       int machine_id)
124 e80cfcfc bellard
{
125 d2c63fc1 blueswir1
    unsigned int i;
126 66508601 blueswir1
    uint32_t start, end;
127 d2c63fc1 blueswir1
    uint8_t image[0x1ff0];
128 d2c63fc1 blueswir1
    ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
129 d2c63fc1 blueswir1
    struct sparc_arch_cfg *sparc_header;
130 d2c63fc1 blueswir1
    struct OpenBIOS_nvpart_v1 *part_header;
131 d2c63fc1 blueswir1
132 d2c63fc1 blueswir1
    memset(image, '\0', sizeof(image));
133 e80cfcfc bellard
134 6f7e9aec bellard
    // Try to match PPC NVRAM
135 d2c63fc1 blueswir1
    strcpy(header->struct_ident, "QEMU_BIOS");
136 d2c63fc1 blueswir1
    header->struct_version = cpu_to_be32(3); /* structure v3 */
137 d2c63fc1 blueswir1
138 d2c63fc1 blueswir1
    header->nvram_size = cpu_to_be16(0x2000);
139 d2c63fc1 blueswir1
    header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
140 d2c63fc1 blueswir1
    header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
141 d2c63fc1 blueswir1
    strcpy(header->arch, "sun4m");
142 d2c63fc1 blueswir1
    header->nb_cpus = smp_cpus & 0xff;
143 d2c63fc1 blueswir1
    header->RAM0_base = 0;
144 d2c63fc1 blueswir1
    header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
145 d2c63fc1 blueswir1
    strcpy(header->boot_devices, boot_devices);
146 d2c63fc1 blueswir1
    header->nboot_devices = strlen(boot_devices) & 0xff;
147 d2c63fc1 blueswir1
    header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR);
148 d2c63fc1 blueswir1
    header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
149 b6f479d3 bellard
    if (cmdline) {
150 f930d07e blueswir1
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
151 d2c63fc1 blueswir1
        header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
152 d2c63fc1 blueswir1
        header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
153 b6f479d3 bellard
    }
154 d2c63fc1 blueswir1
    // XXX add initrd_image, initrd_size
155 d2c63fc1 blueswir1
    header->width = cpu_to_be16(width);
156 d2c63fc1 blueswir1
    header->height = cpu_to_be16(height);
157 d2c63fc1 blueswir1
    header->depth = cpu_to_be16(depth);
158 d2c63fc1 blueswir1
    if (nographic)
159 d2c63fc1 blueswir1
        header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
160 d2c63fc1 blueswir1
161 d2c63fc1 blueswir1
    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
162 d2c63fc1 blueswir1
163 d2c63fc1 blueswir1
    // Architecture specific header
164 d2c63fc1 blueswir1
    start = sizeof(ohwcfg_v3_t);
165 d2c63fc1 blueswir1
    sparc_header = (struct sparc_arch_cfg *)&image[start];
166 d2c63fc1 blueswir1
    sparc_header->valid = 0;
167 d2c63fc1 blueswir1
    start += sizeof(struct sparc_arch_cfg);
168 b6f479d3 bellard
169 66508601 blueswir1
    // OpenBIOS nvram variables
170 66508601 blueswir1
    // Variable partition
171 d2c63fc1 blueswir1
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
172 d2c63fc1 blueswir1
    part_header->signature = OPENBIOS_PART_SYSTEM;
173 d2c63fc1 blueswir1
    strcpy(part_header->name, "system");
174 66508601 blueswir1
175 d2c63fc1 blueswir1
    end = start + sizeof(struct OpenBIOS_nvpart_v1);
176 66508601 blueswir1
    for (i = 0; i < nb_prom_envs; i++)
177 d2c63fc1 blueswir1
        end = OpenBIOS_set_var(image, end, prom_envs[i]);
178 d2c63fc1 blueswir1
179 d2c63fc1 blueswir1
    // End marker
180 d2c63fc1 blueswir1
    image[end++] = '\0';
181 66508601 blueswir1
182 66508601 blueswir1
    end = start + ((end - start + 15) & ~15);
183 d2c63fc1 blueswir1
    OpenBIOS_finish_partition(part_header, end - start);
184 66508601 blueswir1
185 66508601 blueswir1
    // free partition
186 66508601 blueswir1
    start = end;
187 d2c63fc1 blueswir1
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
188 d2c63fc1 blueswir1
    part_header->signature = OPENBIOS_PART_FREE;
189 d2c63fc1 blueswir1
    strcpy(part_header->name, "free");
190 66508601 blueswir1
191 66508601 blueswir1
    end = 0x1fd0;
192 d2c63fc1 blueswir1
    OpenBIOS_finish_partition(part_header, end - start);
193 d2c63fc1 blueswir1
194 d2c63fc1 blueswir1
    Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, machine_id);
195 d2c63fc1 blueswir1
196 d2c63fc1 blueswir1
    for (i = 0; i < sizeof(image); i++)
197 d2c63fc1 blueswir1
        m48t59_write(nvram, i, image[i]);
198 e80cfcfc bellard
}
199 e80cfcfc bellard
200 e80cfcfc bellard
static void *slavio_intctl;
201 e80cfcfc bellard
202 e80cfcfc bellard
void pic_info()
203 e80cfcfc bellard
{
204 e80cfcfc bellard
    slavio_pic_info(slavio_intctl);
205 e80cfcfc bellard
}
206 e80cfcfc bellard
207 e80cfcfc bellard
void irq_info()
208 e80cfcfc bellard
{
209 e80cfcfc bellard
    slavio_irq_info(slavio_intctl);
210 e80cfcfc bellard
}
211 e80cfcfc bellard
212 327ac2e7 blueswir1
void cpu_check_irqs(CPUState *env)
213 327ac2e7 blueswir1
{
214 327ac2e7 blueswir1
    if (env->pil_in && (env->interrupt_index == 0 ||
215 327ac2e7 blueswir1
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
216 327ac2e7 blueswir1
        unsigned int i;
217 327ac2e7 blueswir1
218 327ac2e7 blueswir1
        for (i = 15; i > 0; i--) {
219 327ac2e7 blueswir1
            if (env->pil_in & (1 << i)) {
220 327ac2e7 blueswir1
                int old_interrupt = env->interrupt_index;
221 327ac2e7 blueswir1
222 327ac2e7 blueswir1
                env->interrupt_index = TT_EXTINT | i;
223 327ac2e7 blueswir1
                if (old_interrupt != env->interrupt_index)
224 327ac2e7 blueswir1
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
225 327ac2e7 blueswir1
                break;
226 327ac2e7 blueswir1
            }
227 327ac2e7 blueswir1
        }
228 327ac2e7 blueswir1
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
229 327ac2e7 blueswir1
        env->interrupt_index = 0;
230 327ac2e7 blueswir1
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
231 327ac2e7 blueswir1
    }
232 327ac2e7 blueswir1
}
233 327ac2e7 blueswir1
234 b3a23197 blueswir1
static void cpu_set_irq(void *opaque, int irq, int level)
235 b3a23197 blueswir1
{
236 b3a23197 blueswir1
    CPUState *env = opaque;
237 b3a23197 blueswir1
238 b3a23197 blueswir1
    if (level) {
239 b3a23197 blueswir1
        DPRINTF("Raise CPU IRQ %d\n", irq);
240 b3a23197 blueswir1
        env->halted = 0;
241 327ac2e7 blueswir1
        env->pil_in |= 1 << irq;
242 327ac2e7 blueswir1
        cpu_check_irqs(env);
243 b3a23197 blueswir1
    } else {
244 b3a23197 blueswir1
        DPRINTF("Lower CPU IRQ %d\n", irq);
245 327ac2e7 blueswir1
        env->pil_in &= ~(1 << irq);
246 327ac2e7 blueswir1
        cpu_check_irqs(env);
247 b3a23197 blueswir1
    }
248 b3a23197 blueswir1
}
249 b3a23197 blueswir1
250 b3a23197 blueswir1
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
251 b3a23197 blueswir1
{
252 b3a23197 blueswir1
}
253 b3a23197 blueswir1
254 3475187d bellard
static void *slavio_misc;
255 3475187d bellard
256 3475187d bellard
void qemu_system_powerdown(void)
257 3475187d bellard
{
258 3475187d bellard
    slavio_set_power_fail(slavio_misc, 1);
259 3475187d bellard
}
260 3475187d bellard
261 c68ea704 bellard
static void main_cpu_reset(void *opaque)
262 c68ea704 bellard
{
263 c68ea704 bellard
    CPUState *env = opaque;
264 3d29fbef blueswir1
265 3d29fbef blueswir1
    cpu_reset(env);
266 3d29fbef blueswir1
    env->halted = 0;
267 3d29fbef blueswir1
}
268 3d29fbef blueswir1
269 3d29fbef blueswir1
static void secondary_cpu_reset(void *opaque)
270 3d29fbef blueswir1
{
271 3d29fbef blueswir1
    CPUState *env = opaque;
272 3d29fbef blueswir1
273 c68ea704 bellard
    cpu_reset(env);
274 3d29fbef blueswir1
    env->halted = 1;
275 c68ea704 bellard
}
276 c68ea704 bellard
277 3ebf5aaf blueswir1
static unsigned long sun4m_load_kernel(const char *kernel_filename,
278 3ebf5aaf blueswir1
                                       const char *kernel_cmdline,
279 3ebf5aaf blueswir1
                                       const char *initrd_filename)
280 3ebf5aaf blueswir1
{
281 3ebf5aaf blueswir1
    int linux_boot;
282 3ebf5aaf blueswir1
    unsigned int i;
283 3ebf5aaf blueswir1
    long initrd_size, kernel_size;
284 3ebf5aaf blueswir1
285 3ebf5aaf blueswir1
    linux_boot = (kernel_filename != NULL);
286 3ebf5aaf blueswir1
287 3ebf5aaf blueswir1
    kernel_size = 0;
288 3ebf5aaf blueswir1
    if (linux_boot) {
289 3ebf5aaf blueswir1
        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
290 3ebf5aaf blueswir1
                               NULL);
291 3ebf5aaf blueswir1
        if (kernel_size < 0)
292 3ebf5aaf blueswir1
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
293 3ebf5aaf blueswir1
        if (kernel_size < 0)
294 3ebf5aaf blueswir1
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
295 3ebf5aaf blueswir1
        if (kernel_size < 0) {
296 3ebf5aaf blueswir1
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
297 3ebf5aaf blueswir1
                    kernel_filename);
298 3ebf5aaf blueswir1
            exit(1);
299 3ebf5aaf blueswir1
        }
300 3ebf5aaf blueswir1
301 3ebf5aaf blueswir1
        /* load initrd */
302 3ebf5aaf blueswir1
        initrd_size = 0;
303 3ebf5aaf blueswir1
        if (initrd_filename) {
304 3ebf5aaf blueswir1
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
305 3ebf5aaf blueswir1
            if (initrd_size < 0) {
306 3ebf5aaf blueswir1
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
307 3ebf5aaf blueswir1
                        initrd_filename);
308 3ebf5aaf blueswir1
                exit(1);
309 3ebf5aaf blueswir1
            }
310 3ebf5aaf blueswir1
        }
311 3ebf5aaf blueswir1
        if (initrd_size > 0) {
312 3ebf5aaf blueswir1
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
313 3ebf5aaf blueswir1
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
314 3ebf5aaf blueswir1
                    == 0x48647253) { // HdrS
315 3ebf5aaf blueswir1
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
316 3ebf5aaf blueswir1
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
317 3ebf5aaf blueswir1
                    break;
318 3ebf5aaf blueswir1
                }
319 3ebf5aaf blueswir1
            }
320 3ebf5aaf blueswir1
        }
321 3ebf5aaf blueswir1
    }
322 3ebf5aaf blueswir1
    return kernel_size;
323 3ebf5aaf blueswir1
}
324 3ebf5aaf blueswir1
325 3ebf5aaf blueswir1
static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
326 3ebf5aaf blueswir1
                          const char *boot_device,
327 3ebf5aaf blueswir1
                          DisplayState *ds, const char *kernel_filename,
328 3ebf5aaf blueswir1
                          const char *kernel_cmdline,
329 3ebf5aaf blueswir1
                          const char *initrd_filename, const char *cpu_model)
330 36cd9210 blueswir1
331 420557e8 bellard
{
332 ba3c64fb bellard
    CPUState *env, *envs[MAX_CPUS];
333 713c45fa bellard
    unsigned int i;
334 b3ceef24 blueswir1
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
335 b3a23197 blueswir1
    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
336 d7edfd27 blueswir1
        *espdma_irq, *ledma_irq;
337 2d069bab blueswir1
    qemu_irq *esp_reset, *le_reset;
338 3ebf5aaf blueswir1
    unsigned long prom_offset, kernel_size;
339 3ebf5aaf blueswir1
    int ret;
340 3ebf5aaf blueswir1
    char buf[1024];
341 e4bcb14c ths
    BlockDriverState *fd[MAX_FD];
342 e4bcb14c ths
    int index;
343 420557e8 bellard
344 ba3c64fb bellard
    /* init CPUs */
345 3ebf5aaf blueswir1
    if (!cpu_model)
346 3ebf5aaf blueswir1
        cpu_model = hwdef->default_cpu_model;
347 b3a23197 blueswir1
348 ba3c64fb bellard
    for(i = 0; i < smp_cpus; i++) {
349 aaed909a bellard
        env = cpu_init(cpu_model);
350 aaed909a bellard
        if (!env) {
351 aaed909a bellard
            fprintf(stderr, "Unable to find Sparc CPU definition\n");
352 aaed909a bellard
            exit(1);
353 aaed909a bellard
        }
354 aaed909a bellard
        cpu_sparc_set_id(env, i);
355 ba3c64fb bellard
        envs[i] = env;
356 3d29fbef blueswir1
        if (i == 0) {
357 3d29fbef blueswir1
            qemu_register_reset(main_cpu_reset, env);
358 3d29fbef blueswir1
        } else {
359 3d29fbef blueswir1
            qemu_register_reset(secondary_cpu_reset, env);
360 ba3c64fb bellard
            env->halted = 1;
361 3d29fbef blueswir1
        }
362 ba3c64fb bellard
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
363 b3a23197 blueswir1
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
364 3ebf5aaf blueswir1
        env->prom_addr = hwdef->slavio_base;
365 ba3c64fb bellard
    }
366 b3a23197 blueswir1
367 b3a23197 blueswir1
    for (i = smp_cpus; i < MAX_CPUS; i++)
368 b3a23197 blueswir1
        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
369 b3a23197 blueswir1
370 3ebf5aaf blueswir1
371 420557e8 bellard
    /* allocate RAM */
372 3ebf5aaf blueswir1
    if ((uint64_t)RAM_size > hwdef->max_mem) {
373 3ebf5aaf blueswir1
        fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
374 3ebf5aaf blueswir1
                (unsigned int)RAM_size / (1024 * 1024),
375 3ebf5aaf blueswir1
                (unsigned int)(hwdef->max_mem / (1024 * 1024)));
376 3ebf5aaf blueswir1
        exit(1);
377 3ebf5aaf blueswir1
    }
378 b3ceef24 blueswir1
    cpu_register_physical_memory(0, RAM_size, 0);
379 420557e8 bellard
380 3ebf5aaf blueswir1
    /* load boot prom */
381 3ebf5aaf blueswir1
    prom_offset = RAM_size + hwdef->vram_size;
382 3ebf5aaf blueswir1
    cpu_register_physical_memory(hwdef->slavio_base,
383 3ebf5aaf blueswir1
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
384 3ebf5aaf blueswir1
                                 TARGET_PAGE_MASK,
385 3ebf5aaf blueswir1
                                 prom_offset | IO_MEM_ROM);
386 3ebf5aaf blueswir1
387 3ebf5aaf blueswir1
    if (bios_name == NULL)
388 3ebf5aaf blueswir1
        bios_name = PROM_FILENAME;
389 3ebf5aaf blueswir1
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
390 3ebf5aaf blueswir1
    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
391 3ebf5aaf blueswir1
    if (ret < 0 || ret > PROM_SIZE_MAX)
392 3ebf5aaf blueswir1
        ret = load_image(buf, phys_ram_base + prom_offset);
393 3ebf5aaf blueswir1
    if (ret < 0 || ret > PROM_SIZE_MAX) {
394 3ebf5aaf blueswir1
        fprintf(stderr, "qemu: could not load prom '%s'\n",
395 3ebf5aaf blueswir1
                buf);
396 3ebf5aaf blueswir1
        exit(1);
397 3ebf5aaf blueswir1
    }
398 3ebf5aaf blueswir1
399 3ebf5aaf blueswir1
    /* set up devices */
400 7fbfb139 blueswir1
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version);
401 36cd9210 blueswir1
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
402 5dcb6b91 blueswir1
                                       hwdef->intctl_base + 0x10000ULL,
403 d537cf6c pbrook
                                       &hwdef->intbit_to_level[0],
404 d7edfd27 blueswir1
                                       &slavio_irq, &slavio_cpu_irq,
405 b3a23197 blueswir1
                                       cpu_irqs,
406 d7edfd27 blueswir1
                                       hwdef->clock_irq);
407 b3a23197 blueswir1
408 5aca8c3b blueswir1
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
409 2d069bab blueswir1
                              iommu, &espdma_irq, &esp_reset);
410 2d069bab blueswir1
411 5aca8c3b blueswir1
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
412 2d069bab blueswir1
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
413 2d069bab blueswir1
                             &le_reset);
414 ba3c64fb bellard
415 eee0b836 blueswir1
    if (graphic_depth != 8 && graphic_depth != 24) {
416 eee0b836 blueswir1
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
417 eee0b836 blueswir1
        exit (1);
418 eee0b836 blueswir1
    }
419 b3ceef24 blueswir1
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
420 eee0b836 blueswir1
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
421 dbe06e18 blueswir1
422 dbe06e18 blueswir1
    if (nd_table[0].model == NULL
423 dbe06e18 blueswir1
        || strcmp(nd_table[0].model, "lance") == 0) {
424 2d069bab blueswir1
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
425 c4a7060c blueswir1
    } else if (strcmp(nd_table[0].model, "?") == 0) {
426 c4a7060c blueswir1
        fprintf(stderr, "qemu: Supported NICs: lance\n");
427 c4a7060c blueswir1
        exit (1);
428 dbe06e18 blueswir1
    } else {
429 dbe06e18 blueswir1
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
430 dbe06e18 blueswir1
        exit (1);
431 a41b2ff2 pbrook
    }
432 dbe06e18 blueswir1
433 d537cf6c pbrook
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
434 d537cf6c pbrook
                        hwdef->nvram_size, 8);
435 81732d19 blueswir1
436 81732d19 blueswir1
    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
437 81732d19 blueswir1
                          slavio_cpu_irq);
438 81732d19 blueswir1
439 d537cf6c pbrook
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
440 b81b3b10 bellard
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
441 b81b3b10 bellard
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
442 d537cf6c pbrook
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
443 d537cf6c pbrook
                       serial_hds[1], serial_hds[0]);
444 741402f9 blueswir1
445 e4bcb14c ths
    if (hwdef->fd_base != (target_phys_addr_t)-1) {
446 e4bcb14c ths
        /* there is zero or one floppy drive */
447 e4bcb14c ths
        fd[1] = fd[0] = NULL;
448 e4bcb14c ths
        index = drive_get_index(IF_FLOPPY, 0, 0);
449 e4bcb14c ths
        if (index != -1)
450 e4bcb14c ths
            fd[0] = drives_table[index].bdrv;
451 2d069bab blueswir1
452 e4bcb14c ths
        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd);
453 e4bcb14c ths
    }
454 e4bcb14c ths
455 e4bcb14c ths
    if (drive_get_max_bus(IF_SCSI) > 0) {
456 e4bcb14c ths
        fprintf(stderr, "qemu: too many SCSI bus\n");
457 e4bcb14c ths
        exit(1);
458 e4bcb14c ths
    }
459 e4bcb14c ths
460 e4bcb14c ths
    main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq,
461 2d069bab blueswir1
                        esp_reset);
462 f1587550 ths
463 e4bcb14c ths
    for (i = 0; i < ESP_MAX_DEVS; i++) {
464 e4bcb14c ths
        index = drive_get_index(IF_SCSI, 0, i);
465 e4bcb14c ths
        if (index == -1)
466 e4bcb14c ths
            continue;
467 e4bcb14c ths
        esp_scsi_attach(main_esp, drives_table[index].bdrv, i);
468 f1587550 ths
    }
469 f1587550 ths
470 5dcb6b91 blueswir1
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
471 d537cf6c pbrook
                                   slavio_irq[hwdef->me_irq]);
472 5dcb6b91 blueswir1
    if (hwdef->cs_base != (target_phys_addr_t)-1)
473 803b3c7b blueswir1
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
474 b3ceef24 blueswir1
475 3ebf5aaf blueswir1
    kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline,
476 3ebf5aaf blueswir1
                                    initrd_filename);
477 36cd9210 blueswir1
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 3ebf5aaf blueswir1
               graphic_height, graphic_depth, hwdef->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 7fbfb139 blueswir1
        .iommu_version = 0x04000000,
513 e0353fe2 blueswir1
        .intbit_to_level = {
514 f930d07e blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
515 f930d07e blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
516 e0353fe2 blueswir1
        },
517 3ebf5aaf blueswir1
        .max_mem = 0x10000000,
518 3ebf5aaf blueswir1
        .default_cpu_model = "Fujitsu MB86904",
519 e0353fe2 blueswir1
    },
520 e0353fe2 blueswir1
    /* SS-10 */
521 e0353fe2 blueswir1
    {
522 5dcb6b91 blueswir1
        .iommu_base   = 0xfe0000000ULL,
523 5dcb6b91 blueswir1
        .tcx_base     = 0xe20000000ULL,
524 803b3c7b blueswir1
        .cs_base      = -1,
525 5dcb6b91 blueswir1
        .slavio_base  = 0xff0000000ULL,
526 5dcb6b91 blueswir1
        .ms_kb_base   = 0xff1000000ULL,
527 5dcb6b91 blueswir1
        .serial_base  = 0xff1100000ULL,
528 5dcb6b91 blueswir1
        .nvram_base   = 0xff1200000ULL,
529 5dcb6b91 blueswir1
        .fd_base      = 0xff1700000ULL,
530 5dcb6b91 blueswir1
        .counter_base = 0xff1300000ULL,
531 5dcb6b91 blueswir1
        .intctl_base  = 0xff1400000ULL,
532 5dcb6b91 blueswir1
        .dma_base     = 0xef0400000ULL,
533 5dcb6b91 blueswir1
        .esp_base     = 0xef0800000ULL,
534 5dcb6b91 blueswir1
        .le_base      = 0xef0c00000ULL,
535 5dcb6b91 blueswir1
        .power_base   = 0xefa000000ULL,
536 e0353fe2 blueswir1
        .vram_size    = 0x00100000,
537 e0353fe2 blueswir1
        .nvram_size   = 0x2000,
538 e0353fe2 blueswir1
        .esp_irq = 18,
539 e0353fe2 blueswir1
        .le_irq = 16,
540 e0353fe2 blueswir1
        .clock_irq = 7,
541 e0353fe2 blueswir1
        .clock1_irq = 19,
542 e0353fe2 blueswir1
        .ms_kb_irq = 14,
543 e0353fe2 blueswir1
        .ser_irq = 15,
544 e0353fe2 blueswir1
        .fd_irq = 22,
545 e0353fe2 blueswir1
        .me_irq = 30,
546 803b3c7b blueswir1
        .cs_irq = -1,
547 803b3c7b blueswir1
        .machine_id = 0x72,
548 7fbfb139 blueswir1
        .iommu_version = 0x03000000,
549 e0353fe2 blueswir1
        .intbit_to_level = {
550 f930d07e blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
551 f930d07e blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
552 e0353fe2 blueswir1
        },
553 3ebf5aaf blueswir1
        .max_mem = 0xffffffff, // XXX actually first 62GB ok
554 3ebf5aaf blueswir1
        .default_cpu_model = "TI SuperSparc II",
555 36cd9210 blueswir1
    },
556 6a3b9cc9 blueswir1
    /* SS-600MP */
557 6a3b9cc9 blueswir1
    {
558 6a3b9cc9 blueswir1
        .iommu_base   = 0xfe0000000ULL,
559 6a3b9cc9 blueswir1
        .tcx_base     = 0xe20000000ULL,
560 6a3b9cc9 blueswir1
        .cs_base      = -1,
561 6a3b9cc9 blueswir1
        .slavio_base  = 0xff0000000ULL,
562 6a3b9cc9 blueswir1
        .ms_kb_base   = 0xff1000000ULL,
563 6a3b9cc9 blueswir1
        .serial_base  = 0xff1100000ULL,
564 6a3b9cc9 blueswir1
        .nvram_base   = 0xff1200000ULL,
565 6a3b9cc9 blueswir1
        .fd_base      = -1,
566 6a3b9cc9 blueswir1
        .counter_base = 0xff1300000ULL,
567 6a3b9cc9 blueswir1
        .intctl_base  = 0xff1400000ULL,
568 6a3b9cc9 blueswir1
        .dma_base     = 0xef0081000ULL,
569 6a3b9cc9 blueswir1
        .esp_base     = 0xef0080000ULL,
570 6a3b9cc9 blueswir1
        .le_base      = 0xef0060000ULL,
571 6a3b9cc9 blueswir1
        .power_base   = 0xefa000000ULL,
572 6a3b9cc9 blueswir1
        .vram_size    = 0x00100000,
573 6a3b9cc9 blueswir1
        .nvram_size   = 0x2000,
574 6a3b9cc9 blueswir1
        .esp_irq = 18,
575 6a3b9cc9 blueswir1
        .le_irq = 16,
576 6a3b9cc9 blueswir1
        .clock_irq = 7,
577 6a3b9cc9 blueswir1
        .clock1_irq = 19,
578 6a3b9cc9 blueswir1
        .ms_kb_irq = 14,
579 6a3b9cc9 blueswir1
        .ser_irq = 15,
580 6a3b9cc9 blueswir1
        .fd_irq = 22,
581 6a3b9cc9 blueswir1
        .me_irq = 30,
582 6a3b9cc9 blueswir1
        .cs_irq = -1,
583 6a3b9cc9 blueswir1
        .machine_id = 0x71,
584 7fbfb139 blueswir1
        .iommu_version = 0x01000000,
585 6a3b9cc9 blueswir1
        .intbit_to_level = {
586 6a3b9cc9 blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
587 6a3b9cc9 blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
588 6a3b9cc9 blueswir1
        },
589 3ebf5aaf blueswir1
        .max_mem = 0xffffffff, // XXX actually first 62GB ok
590 3ebf5aaf blueswir1
        .default_cpu_model = "TI SuperSparc II",
591 6a3b9cc9 blueswir1
    },
592 36cd9210 blueswir1
};
593 36cd9210 blueswir1
594 36cd9210 blueswir1
/* SPARCstation 5 hardware initialisation */
595 b881c2c6 blueswir1
static void ss5_init(int RAM_size, int vga_ram_size,
596 b881c2c6 blueswir1
                     const char *boot_device, DisplayState *ds,
597 b881c2c6 blueswir1
                     const char *kernel_filename, const char *kernel_cmdline,
598 b881c2c6 blueswir1
                     const char *initrd_filename, const char *cpu_model)
599 36cd9210 blueswir1
{
600 3ebf5aaf blueswir1
    sun4m_hw_init(&hwdefs[0], RAM_size, boot_device, ds, kernel_filename,
601 3ebf5aaf blueswir1
                  kernel_cmdline, initrd_filename, cpu_model);
602 420557e8 bellard
}
603 c0e564d5 bellard
604 e0353fe2 blueswir1
/* SPARCstation 10 hardware initialisation */
605 b881c2c6 blueswir1
static void ss10_init(int RAM_size, int vga_ram_size,
606 b881c2c6 blueswir1
                      const char *boot_device, DisplayState *ds,
607 b881c2c6 blueswir1
                      const char *kernel_filename, const char *kernel_cmdline,
608 b881c2c6 blueswir1
                      const char *initrd_filename, const char *cpu_model)
609 e0353fe2 blueswir1
{
610 3ebf5aaf blueswir1
    sun4m_hw_init(&hwdefs[1], RAM_size, boot_device, ds, kernel_filename,
611 3ebf5aaf blueswir1
                  kernel_cmdline, initrd_filename, cpu_model);
612 e0353fe2 blueswir1
}
613 e0353fe2 blueswir1
614 6a3b9cc9 blueswir1
/* SPARCserver 600MP hardware initialisation */
615 b881c2c6 blueswir1
static void ss600mp_init(int RAM_size, int vga_ram_size,
616 b881c2c6 blueswir1
                         const char *boot_device, DisplayState *ds,
617 6a3b9cc9 blueswir1
                         const char *kernel_filename, const char *kernel_cmdline,
618 6a3b9cc9 blueswir1
                         const char *initrd_filename, const char *cpu_model)
619 6a3b9cc9 blueswir1
{
620 3ebf5aaf blueswir1
    sun4m_hw_init(&hwdefs[2], RAM_size, boot_device, ds, kernel_filename,
621 3ebf5aaf blueswir1
                  kernel_cmdline, initrd_filename, cpu_model);
622 6a3b9cc9 blueswir1
}
623 6a3b9cc9 blueswir1
624 36cd9210 blueswir1
QEMUMachine ss5_machine = {
625 36cd9210 blueswir1
    "SS-5",
626 36cd9210 blueswir1
    "Sun4m platform, SPARCstation 5",
627 36cd9210 blueswir1
    ss5_init,
628 c0e564d5 bellard
};
629 e0353fe2 blueswir1
630 e0353fe2 blueswir1
QEMUMachine ss10_machine = {
631 e0353fe2 blueswir1
    "SS-10",
632 e0353fe2 blueswir1
    "Sun4m platform, SPARCstation 10",
633 e0353fe2 blueswir1
    ss10_init,
634 e0353fe2 blueswir1
};
635 6a3b9cc9 blueswir1
636 6a3b9cc9 blueswir1
QEMUMachine ss600mp_machine = {
637 6a3b9cc9 blueswir1
    "SS-600MP",
638 6a3b9cc9 blueswir1
    "Sun4m platform, SPARCserver 600MP",
639 6a3b9cc9 blueswir1
    ss600mp_init,
640 6a3b9cc9 blueswir1
};