Statistics
| Branch: | Revision:

root / hw / sun4m.c @ 5aca8c3b

History | View | Annotate | Download (17.5 kB)

1 420557e8 bellard
/*
2 420557e8 bellard
 * QEMU Sun4m System Emulator
3 420557e8 bellard
 * 
4 b81b3b10 bellard
 * Copyright (c) 2003-2005 Fabrice Bellard
5 420557e8 bellard
 * 
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 420557e8 bellard
26 36cd9210 blueswir1
/*
27 36cd9210 blueswir1
 * Sun4m architecture was used in the following machines:
28 36cd9210 blueswir1
 *
29 36cd9210 blueswir1
 * SPARCserver 6xxMP/xx
30 36cd9210 blueswir1
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
31 36cd9210 blueswir1
 * SPARCstation LX/ZX (4/30)
32 36cd9210 blueswir1
 * SPARCstation Voyager
33 36cd9210 blueswir1
 * SPARCstation 10/xx, SPARCserver 10/xx
34 36cd9210 blueswir1
 * SPARCstation 5, SPARCserver 5
35 36cd9210 blueswir1
 * SPARCstation 20/xx, SPARCserver 20
36 36cd9210 blueswir1
 * SPARCstation 4
37 36cd9210 blueswir1
 *
38 36cd9210 blueswir1
 * See for example: http://www.sunhelp.org/faq/sunref1.html
39 36cd9210 blueswir1
 */
40 36cd9210 blueswir1
41 420557e8 bellard
#define KERNEL_LOAD_ADDR     0x00004000
42 b6f479d3 bellard
#define CMDLINE_ADDR         0x007ff000
43 713c45fa bellard
#define INITRD_LOAD_ADDR     0x00800000
44 b3783731 bellard
#define PROM_SIZE_MAX        (256 * 1024)
45 e80cfcfc bellard
#define PROM_ADDR             0xffd00000
46 0986ac3b bellard
#define PROM_FILENAME             "openbios-sparc32"
47 b8174937 bellard
48 ba3c64fb bellard
#define MAX_CPUS 16
49 420557e8 bellard
50 36cd9210 blueswir1
struct hwdef {
51 5dcb6b91 blueswir1
    target_phys_addr_t iommu_base, slavio_base;
52 5dcb6b91 blueswir1
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
53 5dcb6b91 blueswir1
    target_phys_addr_t serial_base, fd_base;
54 5dcb6b91 blueswir1
    target_phys_addr_t dma_base, esp_base, le_base;
55 5dcb6b91 blueswir1
    target_phys_addr_t tcx_base, cs_base, power_base;
56 36cd9210 blueswir1
    long vram_size, nvram_size;
57 36cd9210 blueswir1
    // IRQ numbers are not PIL ones, but master interrupt controller register
58 36cd9210 blueswir1
    // bit numbers
59 36cd9210 blueswir1
    int intctl_g_intr, esp_irq, le_irq, cpu_irq, clock_irq, clock1_irq;
60 36cd9210 blueswir1
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
61 36cd9210 blueswir1
    int machine_id; // For NVRAM
62 e0353fe2 blueswir1
    uint32_t intbit_to_level[32];
63 36cd9210 blueswir1
};
64 36cd9210 blueswir1
65 420557e8 bellard
/* TSC handling */
66 420557e8 bellard
67 420557e8 bellard
uint64_t cpu_get_tsc()
68 420557e8 bellard
{
69 420557e8 bellard
    return qemu_get_clock(vm_clock);
70 420557e8 bellard
}
71 420557e8 bellard
72 6f7e9aec bellard
int DMA_get_channel_mode (int nchan)
73 6f7e9aec bellard
{
74 6f7e9aec bellard
    return 0;
75 6f7e9aec bellard
}
76 6f7e9aec bellard
int DMA_read_memory (int nchan, void *buf, int pos, int size)
77 6f7e9aec bellard
{
78 6f7e9aec bellard
    return 0;
79 6f7e9aec bellard
}
80 6f7e9aec bellard
int DMA_write_memory (int nchan, void *buf, int pos, int size)
81 6f7e9aec bellard
{
82 6f7e9aec bellard
    return 0;
83 6f7e9aec bellard
}
84 6f7e9aec bellard
void DMA_hold_DREQ (int nchan) {}
85 6f7e9aec bellard
void DMA_release_DREQ (int nchan) {}
86 6f7e9aec bellard
void DMA_schedule(int nchan) {}
87 6f7e9aec bellard
void DMA_run (void) {}
88 6f7e9aec bellard
void DMA_init (int high_page_enable) {}
89 6f7e9aec bellard
void DMA_register_channel (int nchan,
90 6f7e9aec bellard
                           DMA_transfer_handler transfer_handler,
91 6f7e9aec bellard
                           void *opaque)
92 6f7e9aec bellard
{
93 6f7e9aec bellard
}
94 6f7e9aec bellard
95 819385c5 bellard
static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
96 6f7e9aec bellard
{
97 819385c5 bellard
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
98 819385c5 bellard
    m48t59_write(nvram, addr++, value & 0xff);
99 6f7e9aec bellard
}
100 6f7e9aec bellard
101 819385c5 bellard
static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
102 6f7e9aec bellard
{
103 819385c5 bellard
    m48t59_write(nvram, addr++, value >> 24);
104 819385c5 bellard
    m48t59_write(nvram, addr++, (value >> 16) & 0xff);
105 819385c5 bellard
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
106 819385c5 bellard
    m48t59_write(nvram, addr++, value & 0xff);
107 6f7e9aec bellard
}
108 6f7e9aec bellard
109 819385c5 bellard
static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
110 6f7e9aec bellard
                       const unsigned char *str, uint32_t max)
111 6f7e9aec bellard
{
112 6f7e9aec bellard
    unsigned int i;
113 6f7e9aec bellard
114 6f7e9aec bellard
    for (i = 0; i < max && str[i] != '\0'; i++) {
115 819385c5 bellard
        m48t59_write(nvram, addr + i, str[i]);
116 6f7e9aec bellard
    }
117 819385c5 bellard
    m48t59_write(nvram, addr + max - 1, '\0');
118 6f7e9aec bellard
}
119 420557e8 bellard
120 66508601 blueswir1
static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr,
121 66508601 blueswir1
                                const unsigned char *str)
122 66508601 blueswir1
{
123 66508601 blueswir1
    uint32_t len;
124 66508601 blueswir1
125 66508601 blueswir1
    len = strlen(str) + 1;
126 66508601 blueswir1
    nvram_set_string(nvram, addr, str, len);
127 66508601 blueswir1
128 66508601 blueswir1
    return addr + len;
129 66508601 blueswir1
}
130 66508601 blueswir1
131 66508601 blueswir1
static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
132 66508601 blueswir1
                                    uint32_t end)
133 66508601 blueswir1
{
134 66508601 blueswir1
    unsigned int i, sum;
135 66508601 blueswir1
136 66508601 blueswir1
    // Length divided by 16
137 66508601 blueswir1
    m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff);
138 66508601 blueswir1
    m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff);
139 66508601 blueswir1
    // Checksum
140 66508601 blueswir1
    sum = m48t59_read(nvram, start);
141 66508601 blueswir1
    for (i = 0; i < 14; i++) {
142 66508601 blueswir1
        sum += m48t59_read(nvram, start + 2 + i);
143 66508601 blueswir1
        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
144 66508601 blueswir1
    }
145 66508601 blueswir1
    m48t59_write(nvram, start + 1, sum & 0xff);
146 66508601 blueswir1
}
147 66508601 blueswir1
148 819385c5 bellard
static m48t59_t *nvram;
149 420557e8 bellard
150 6f7e9aec bellard
extern int nographic;
151 6f7e9aec bellard
152 819385c5 bellard
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
153 6f7e9aec bellard
                       int boot_device, uint32_t RAM_size,
154 6f7e9aec bellard
                       uint32_t kernel_size,
155 36cd9210 blueswir1
                       int width, int height, int depth,
156 36cd9210 blueswir1
                       int machine_id)
157 e80cfcfc bellard
{
158 e80cfcfc bellard
    unsigned char tmp = 0;
159 66508601 blueswir1
    unsigned int i, j;
160 66508601 blueswir1
    uint32_t start, end;
161 e80cfcfc bellard
162 6f7e9aec bellard
    // Try to match PPC NVRAM
163 6f7e9aec bellard
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
164 6f7e9aec bellard
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
165 6f7e9aec bellard
    // NVRAM_size, arch not applicable
166 ba3c64fb bellard
    m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
167 ba3c64fb bellard
    m48t59_write(nvram, 0x2E, 0);
168 819385c5 bellard
    m48t59_write(nvram, 0x2F, nographic & 0xff);
169 6f7e9aec bellard
    nvram_set_lword(nvram,  0x30, RAM_size);
170 819385c5 bellard
    m48t59_write(nvram, 0x34, boot_device & 0xff);
171 6f7e9aec bellard
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
172 6f7e9aec bellard
    nvram_set_lword(nvram,  0x3C, kernel_size);
173 b6f479d3 bellard
    if (cmdline) {
174 b6f479d3 bellard
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
175 6f7e9aec bellard
        nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
176 6f7e9aec bellard
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
177 b6f479d3 bellard
    }
178 6f7e9aec bellard
    // initrd_image, initrd_size passed differently
179 6f7e9aec bellard
    nvram_set_word(nvram,   0x54, width);
180 6f7e9aec bellard
    nvram_set_word(nvram,   0x56, height);
181 6f7e9aec bellard
    nvram_set_word(nvram,   0x58, depth);
182 b6f479d3 bellard
183 66508601 blueswir1
    // OpenBIOS nvram variables
184 66508601 blueswir1
    // Variable partition
185 66508601 blueswir1
    start = 252;
186 66508601 blueswir1
    m48t59_write(nvram, start, 0x70);
187 66508601 blueswir1
    nvram_set_string(nvram, start + 4, "system", 12);
188 66508601 blueswir1
189 66508601 blueswir1
    end = start + 16;
190 66508601 blueswir1
    for (i = 0; i < nb_prom_envs; i++)
191 66508601 blueswir1
        end = nvram_set_var(nvram, end, prom_envs[i]);
192 66508601 blueswir1
193 66508601 blueswir1
    m48t59_write(nvram, end++ , 0);
194 66508601 blueswir1
    end = start + ((end - start + 15) & ~15);
195 66508601 blueswir1
    nvram_finish_partition(nvram, start, end);
196 66508601 blueswir1
197 66508601 blueswir1
    // free partition
198 66508601 blueswir1
    start = end;
199 66508601 blueswir1
    m48t59_write(nvram, start, 0x7f);
200 66508601 blueswir1
    nvram_set_string(nvram, start + 4, "free", 12);
201 66508601 blueswir1
202 66508601 blueswir1
    end = 0x1fd0;
203 66508601 blueswir1
    nvram_finish_partition(nvram, start, end);
204 66508601 blueswir1
205 6f7e9aec bellard
    // Sun4m specific use
206 66508601 blueswir1
    start = i = 0x1fd8;
207 819385c5 bellard
    m48t59_write(nvram, i++, 0x01);
208 36cd9210 blueswir1
    m48t59_write(nvram, i++, machine_id);
209 e80cfcfc bellard
    j = 0;
210 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
211 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
212 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
213 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
214 819385c5 bellard
    m48t59_write(nvram, i++, macaddr[j++]);
215 819385c5 bellard
    m48t59_write(nvram, i, macaddr[j]);
216 e80cfcfc bellard
217 e80cfcfc bellard
    /* Calculate checksum */
218 66508601 blueswir1
    for (i = start; i < start + 15; i++) {
219 66508601 blueswir1
        tmp ^= m48t59_read(nvram, i);
220 e80cfcfc bellard
    }
221 66508601 blueswir1
    m48t59_write(nvram, start + 15, tmp);
222 e80cfcfc bellard
}
223 e80cfcfc bellard
224 e80cfcfc bellard
static void *slavio_intctl;
225 e80cfcfc bellard
226 e80cfcfc bellard
void pic_info()
227 e80cfcfc bellard
{
228 e80cfcfc bellard
    slavio_pic_info(slavio_intctl);
229 e80cfcfc bellard
}
230 e80cfcfc bellard
231 e80cfcfc bellard
void irq_info()
232 e80cfcfc bellard
{
233 e80cfcfc bellard
    slavio_irq_info(slavio_intctl);
234 e80cfcfc bellard
}
235 e80cfcfc bellard
236 3475187d bellard
static void *slavio_misc;
237 3475187d bellard
238 3475187d bellard
void qemu_system_powerdown(void)
239 3475187d bellard
{
240 3475187d bellard
    slavio_set_power_fail(slavio_misc, 1);
241 3475187d bellard
}
242 3475187d bellard
243 c68ea704 bellard
static void main_cpu_reset(void *opaque)
244 c68ea704 bellard
{
245 c68ea704 bellard
    CPUState *env = opaque;
246 3d29fbef blueswir1
247 3d29fbef blueswir1
    cpu_reset(env);
248 3d29fbef blueswir1
    env->halted = 0;
249 3d29fbef blueswir1
}
250 3d29fbef blueswir1
251 3d29fbef blueswir1
static void secondary_cpu_reset(void *opaque)
252 3d29fbef blueswir1
{
253 3d29fbef blueswir1
    CPUState *env = opaque;
254 3d29fbef blueswir1
255 c68ea704 bellard
    cpu_reset(env);
256 3d29fbef blueswir1
    env->halted = 1;
257 c68ea704 bellard
}
258 c68ea704 bellard
259 36cd9210 blueswir1
static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
260 36cd9210 blueswir1
                          DisplayState *ds, const char *cpu_model)
261 36cd9210 blueswir1
262 420557e8 bellard
{
263 ba3c64fb bellard
    CPUState *env, *envs[MAX_CPUS];
264 713c45fa bellard
    unsigned int i;
265 5aca8c3b blueswir1
    void *iommu, *espdma, *ledma, *main_esp, *main_lance = NULL;
266 62724a37 blueswir1
    const sparc_def_t *def;
267 d537cf6c pbrook
    qemu_irq *slavio_irq;
268 420557e8 bellard
269 ba3c64fb bellard
    /* init CPUs */
270 62724a37 blueswir1
    sparc_find_by_name(cpu_model, &def);
271 62724a37 blueswir1
    if (def == NULL) {
272 62724a37 blueswir1
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
273 62724a37 blueswir1
        exit(1);
274 62724a37 blueswir1
    }
275 ba3c64fb bellard
    for(i = 0; i < smp_cpus; i++) {
276 ba3c64fb bellard
        env = cpu_init();
277 62724a37 blueswir1
        cpu_sparc_register(env, def);
278 ba3c64fb bellard
        envs[i] = env;
279 3d29fbef blueswir1
        if (i == 0) {
280 3d29fbef blueswir1
            qemu_register_reset(main_cpu_reset, env);
281 3d29fbef blueswir1
        } else {
282 3d29fbef blueswir1
            qemu_register_reset(secondary_cpu_reset, env);
283 ba3c64fb bellard
            env->halted = 1;
284 3d29fbef blueswir1
        }
285 ba3c64fb bellard
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
286 ba3c64fb bellard
    }
287 420557e8 bellard
    /* allocate RAM */
288 420557e8 bellard
    cpu_register_physical_memory(0, ram_size, 0);
289 420557e8 bellard
290 36cd9210 blueswir1
    iommu = iommu_init(hwdef->iommu_base);
291 36cd9210 blueswir1
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
292 5dcb6b91 blueswir1
                                       hwdef->intctl_base + 0x10000ULL,
293 d537cf6c pbrook
                                       &hwdef->intbit_to_level[0],
294 d537cf6c pbrook
                                       &slavio_irq);
295 ba3c64fb bellard
    for(i = 0; i < smp_cpus; i++) {
296 ba3c64fb bellard
        slavio_intctl_set_cpu(slavio_intctl, i, envs[i]);
297 ba3c64fb bellard
    }
298 5aca8c3b blueswir1
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
299 5aca8c3b blueswir1
                              iommu);
300 5aca8c3b blueswir1
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
301 5aca8c3b blueswir1
                             slavio_irq[hwdef->le_irq], iommu);
302 ba3c64fb bellard
303 eee0b836 blueswir1
    if (graphic_depth != 8 && graphic_depth != 24) {
304 eee0b836 blueswir1
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
305 eee0b836 blueswir1
        exit (1);
306 eee0b836 blueswir1
    }
307 36cd9210 blueswir1
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size,
308 eee0b836 blueswir1
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
309 a41b2ff2 pbrook
    if (nd_table[0].vlan) {
310 a41b2ff2 pbrook
        if (nd_table[0].model == NULL
311 a41b2ff2 pbrook
            || strcmp(nd_table[0].model, "lance") == 0) {
312 5aca8c3b blueswir1
            main_lance = lance_init(&nd_table[0], hwdef->le_base, ledma,
313 d537cf6c pbrook
                                    slavio_irq[hwdef->le_irq]);
314 a41b2ff2 pbrook
        } else {
315 a41b2ff2 pbrook
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
316 a41b2ff2 pbrook
            exit (1);
317 a41b2ff2 pbrook
        }
318 a41b2ff2 pbrook
    }
319 d537cf6c pbrook
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
320 d537cf6c pbrook
                        hwdef->nvram_size, 8);
321 ba3c64fb bellard
    for (i = 0; i < MAX_CPUS; i++) {
322 5dcb6b91 blueswir1
        slavio_timer_init(hwdef->counter_base +
323 5dcb6b91 blueswir1
                          (target_phys_addr_t)(i * TARGET_PAGE_SIZE),
324 52cc07d0 blueswir1
                          hwdef->clock_irq, 0, i, slavio_intctl);
325 ba3c64fb bellard
    }
326 5dcb6b91 blueswir1
    slavio_timer_init(hwdef->counter_base + 0x10000ULL, hwdef->clock1_irq, 2,
327 52cc07d0 blueswir1
                      (unsigned int)-1, slavio_intctl);
328 d537cf6c pbrook
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
329 b81b3b10 bellard
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
330 b81b3b10 bellard
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
331 d537cf6c pbrook
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
332 d537cf6c pbrook
                       serial_hds[1], serial_hds[0]);
333 d537cf6c pbrook
    fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
334 5aca8c3b blueswir1
    main_esp = esp_init(bs_table, hwdef->esp_base, espdma);
335 f1587550 ths
336 f1587550 ths
    for (i = 0; i < MAX_DISKS; i++) {
337 f1587550 ths
        if (bs_table[i]) {
338 f1587550 ths
            esp_scsi_attach(main_esp, bs_table[i], i);
339 f1587550 ths
        }
340 f1587550 ths
    }
341 f1587550 ths
342 5dcb6b91 blueswir1
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
343 d537cf6c pbrook
                                   slavio_irq[hwdef->me_irq]);
344 5dcb6b91 blueswir1
    if (hwdef->cs_base != (target_phys_addr_t)-1)
345 803b3c7b blueswir1
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
346 36cd9210 blueswir1
}
347 36cd9210 blueswir1
348 36cd9210 blueswir1
static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device,
349 36cd9210 blueswir1
                              const char *kernel_filename,
350 36cd9210 blueswir1
                              const char *kernel_cmdline,
351 36cd9210 blueswir1
                              const char *initrd_filename,
352 36cd9210 blueswir1
                              int machine_id)
353 36cd9210 blueswir1
{
354 36cd9210 blueswir1
    int ret, linux_boot;
355 36cd9210 blueswir1
    char buf[1024];
356 36cd9210 blueswir1
    unsigned int i;
357 36cd9210 blueswir1
    long prom_offset, initrd_size, kernel_size;
358 36cd9210 blueswir1
359 36cd9210 blueswir1
    linux_boot = (kernel_filename != NULL);
360 420557e8 bellard
361 e80cfcfc bellard
    prom_offset = ram_size + vram_size;
362 b3783731 bellard
    cpu_register_physical_memory(PROM_ADDR, 
363 b3783731 bellard
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, 
364 b3783731 bellard
                                 prom_offset | IO_MEM_ROM);
365 e80cfcfc bellard
366 0986ac3b bellard
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
367 74287114 ths
    ret = load_elf(buf, 0, NULL, NULL, NULL);
368 e80cfcfc bellard
    if (ret < 0) {
369 e80cfcfc bellard
        fprintf(stderr, "qemu: could not load prom '%s'\n", 
370 e80cfcfc bellard
                buf);
371 e80cfcfc bellard
        exit(1);
372 e80cfcfc bellard
    }
373 e80cfcfc bellard
374 6f7e9aec bellard
    kernel_size = 0;
375 e80cfcfc bellard
    if (linux_boot) {
376 74287114 ths
        kernel_size = load_elf(kernel_filename, -0xf0000000, NULL, NULL, NULL);
377 6f7e9aec bellard
        if (kernel_size < 0)
378 6f7e9aec bellard
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
379 6f7e9aec bellard
        if (kernel_size < 0)
380 6f7e9aec bellard
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
381 6f7e9aec bellard
        if (kernel_size < 0) {
382 420557e8 bellard
            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
383 e80cfcfc bellard
                    kernel_filename);
384 e80cfcfc bellard
            exit(1);
385 420557e8 bellard
        }
386 713c45fa bellard
387 713c45fa bellard
        /* load initrd */
388 713c45fa bellard
        initrd_size = 0;
389 713c45fa bellard
        if (initrd_filename) {
390 713c45fa bellard
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
391 713c45fa bellard
            if (initrd_size < 0) {
392 713c45fa bellard
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
393 713c45fa bellard
                        initrd_filename);
394 713c45fa bellard
                exit(1);
395 713c45fa bellard
            }
396 713c45fa bellard
        }
397 713c45fa bellard
        if (initrd_size > 0) {
398 713c45fa bellard
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
399 713c45fa bellard
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
400 713c45fa bellard
                    == 0x48647253) { // HdrS
401 713c45fa bellard
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
402 713c45fa bellard
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
403 713c45fa bellard
                    break;
404 713c45fa bellard
                }
405 713c45fa bellard
            }
406 713c45fa bellard
        }
407 420557e8 bellard
    }
408 36cd9210 blueswir1
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
409 36cd9210 blueswir1
               boot_device, ram_size, kernel_size, graphic_width,
410 36cd9210 blueswir1
               graphic_height, graphic_depth, machine_id);
411 36cd9210 blueswir1
}
412 36cd9210 blueswir1
413 36cd9210 blueswir1
static const struct hwdef hwdefs[] = {
414 36cd9210 blueswir1
    /* SS-5 */
415 36cd9210 blueswir1
    {
416 36cd9210 blueswir1
        .iommu_base   = 0x10000000,
417 36cd9210 blueswir1
        .tcx_base     = 0x50000000,
418 36cd9210 blueswir1
        .cs_base      = 0x6c000000,
419 384ccb5d blueswir1
        .slavio_base  = 0x70000000,
420 36cd9210 blueswir1
        .ms_kb_base   = 0x71000000,
421 36cd9210 blueswir1
        .serial_base  = 0x71100000,
422 36cd9210 blueswir1
        .nvram_base   = 0x71200000,
423 36cd9210 blueswir1
        .fd_base      = 0x71400000,
424 36cd9210 blueswir1
        .counter_base = 0x71d00000,
425 36cd9210 blueswir1
        .intctl_base  = 0x71e00000,
426 36cd9210 blueswir1
        .dma_base     = 0x78400000,
427 36cd9210 blueswir1
        .esp_base     = 0x78800000,
428 36cd9210 blueswir1
        .le_base      = 0x78c00000,
429 5dcb6b91 blueswir1
        .power_base   = 0x7a000000,
430 36cd9210 blueswir1
        .vram_size    = 0x00100000,
431 36cd9210 blueswir1
        .nvram_size   = 0x2000,
432 36cd9210 blueswir1
        .esp_irq = 18,
433 36cd9210 blueswir1
        .le_irq = 16,
434 36cd9210 blueswir1
        .clock_irq = 7,
435 36cd9210 blueswir1
        .clock1_irq = 19,
436 36cd9210 blueswir1
        .ms_kb_irq = 14,
437 36cd9210 blueswir1
        .ser_irq = 15,
438 36cd9210 blueswir1
        .fd_irq = 22,
439 36cd9210 blueswir1
        .me_irq = 30,
440 36cd9210 blueswir1
        .cs_irq = 5,
441 36cd9210 blueswir1
        .machine_id = 0x80,
442 e0353fe2 blueswir1
        .intbit_to_level = {
443 e0353fe2 blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,        3, 5, 7, 9, 11, 13, 12, 12,
444 e0353fe2 blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,        0, 0, 0, 0, 15, 0, 15, 0,
445 e0353fe2 blueswir1
        },
446 e0353fe2 blueswir1
    },
447 e0353fe2 blueswir1
    /* SS-10 */
448 e0353fe2 blueswir1
    {
449 5dcb6b91 blueswir1
        .iommu_base   = 0xfe0000000ULL,
450 5dcb6b91 blueswir1
        .tcx_base     = 0xe20000000ULL,
451 803b3c7b blueswir1
        .cs_base      = -1,
452 5dcb6b91 blueswir1
        .slavio_base  = 0xff0000000ULL,
453 5dcb6b91 blueswir1
        .ms_kb_base   = 0xff1000000ULL,
454 5dcb6b91 blueswir1
        .serial_base  = 0xff1100000ULL,
455 5dcb6b91 blueswir1
        .nvram_base   = 0xff1200000ULL,
456 5dcb6b91 blueswir1
        .fd_base      = 0xff1700000ULL,
457 5dcb6b91 blueswir1
        .counter_base = 0xff1300000ULL,
458 5dcb6b91 blueswir1
        .intctl_base  = 0xff1400000ULL,
459 5dcb6b91 blueswir1
        .dma_base     = 0xef0400000ULL,
460 5dcb6b91 blueswir1
        .esp_base     = 0xef0800000ULL,
461 5dcb6b91 blueswir1
        .le_base      = 0xef0c00000ULL,
462 5dcb6b91 blueswir1
        .power_base   = 0xefa000000ULL,
463 e0353fe2 blueswir1
        .vram_size    = 0x00100000,
464 e0353fe2 blueswir1
        .nvram_size   = 0x2000,
465 e0353fe2 blueswir1
        .esp_irq = 18,
466 e0353fe2 blueswir1
        .le_irq = 16,
467 e0353fe2 blueswir1
        .clock_irq = 7,
468 e0353fe2 blueswir1
        .clock1_irq = 19,
469 e0353fe2 blueswir1
        .ms_kb_irq = 14,
470 e0353fe2 blueswir1
        .ser_irq = 15,
471 e0353fe2 blueswir1
        .fd_irq = 22,
472 e0353fe2 blueswir1
        .me_irq = 30,
473 803b3c7b blueswir1
        .cs_irq = -1,
474 803b3c7b blueswir1
        .machine_id = 0x72,
475 e0353fe2 blueswir1
        .intbit_to_level = {
476 e0353fe2 blueswir1
            2, 3, 5, 7, 9, 11, 0, 14,        3, 5, 7, 9, 11, 13, 12, 12,
477 e0353fe2 blueswir1
            6, 0, 4, 10, 8, 0, 11, 0,        0, 0, 0, 0, 15, 0, 15, 0,
478 e0353fe2 blueswir1
        },
479 36cd9210 blueswir1
    },
480 36cd9210 blueswir1
};
481 36cd9210 blueswir1
482 36cd9210 blueswir1
static void sun4m_common_init(int ram_size, int boot_device, DisplayState *ds,
483 36cd9210 blueswir1
                              const char *kernel_filename, const char *kernel_cmdline,
484 36cd9210 blueswir1
                              const char *initrd_filename, const char *cpu_model,
485 4edebb0e blueswir1
                              unsigned int machine, int max_ram)
486 36cd9210 blueswir1
{
487 5dcb6b91 blueswir1
    if ((unsigned int)ram_size > (unsigned int)max_ram) {
488 4edebb0e blueswir1
        fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
489 5dcb6b91 blueswir1
                (unsigned int)ram_size / (1024 * 1024),
490 5dcb6b91 blueswir1
                (unsigned int)max_ram / (1024 * 1024));
491 4edebb0e blueswir1
        exit(1);
492 4edebb0e blueswir1
    }
493 36cd9210 blueswir1
    sun4m_hw_init(&hwdefs[machine], ram_size, ds, cpu_model);
494 36cd9210 blueswir1
495 36cd9210 blueswir1
    sun4m_load_kernel(hwdefs[machine].vram_size, ram_size, boot_device,
496 36cd9210 blueswir1
                      kernel_filename, kernel_cmdline, initrd_filename,
497 36cd9210 blueswir1
                      hwdefs[machine].machine_id);
498 36cd9210 blueswir1
}
499 36cd9210 blueswir1
500 36cd9210 blueswir1
/* SPARCstation 5 hardware initialisation */
501 36cd9210 blueswir1
static void ss5_init(int ram_size, int vga_ram_size, int boot_device,
502 36cd9210 blueswir1
                       DisplayState *ds, const char **fd_filename, int snapshot,
503 36cd9210 blueswir1
                       const char *kernel_filename, const char *kernel_cmdline,
504 36cd9210 blueswir1
                       const char *initrd_filename, const char *cpu_model)
505 36cd9210 blueswir1
{
506 36cd9210 blueswir1
    if (cpu_model == NULL)
507 36cd9210 blueswir1
        cpu_model = "Fujitsu MB86904";
508 36cd9210 blueswir1
    sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
509 36cd9210 blueswir1
                      kernel_cmdline, initrd_filename, cpu_model,
510 4edebb0e blueswir1
                      0, 0x10000000);
511 420557e8 bellard
}
512 c0e564d5 bellard
513 e0353fe2 blueswir1
/* SPARCstation 10 hardware initialisation */
514 e0353fe2 blueswir1
static void ss10_init(int ram_size, int vga_ram_size, int boot_device,
515 e0353fe2 blueswir1
                            DisplayState *ds, const char **fd_filename, int snapshot,
516 e0353fe2 blueswir1
                            const char *kernel_filename, const char *kernel_cmdline,
517 e0353fe2 blueswir1
                            const char *initrd_filename, const char *cpu_model)
518 e0353fe2 blueswir1
{
519 e0353fe2 blueswir1
    if (cpu_model == NULL)
520 e0353fe2 blueswir1
        cpu_model = "TI SuperSparc II";
521 e0353fe2 blueswir1
    sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
522 e0353fe2 blueswir1
                      kernel_cmdline, initrd_filename, cpu_model,
523 5dcb6b91 blueswir1
                      1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
524 e0353fe2 blueswir1
}
525 e0353fe2 blueswir1
526 36cd9210 blueswir1
QEMUMachine ss5_machine = {
527 36cd9210 blueswir1
    "SS-5",
528 36cd9210 blueswir1
    "Sun4m platform, SPARCstation 5",
529 36cd9210 blueswir1
    ss5_init,
530 c0e564d5 bellard
};
531 e0353fe2 blueswir1
532 e0353fe2 blueswir1
QEMUMachine ss10_machine = {
533 e0353fe2 blueswir1
    "SS-10",
534 e0353fe2 blueswir1
    "Sun4m platform, SPARCstation 10",
535 e0353fe2 blueswir1
    ss10_init,
536 e0353fe2 blueswir1
};