blob: bae8803d80ab56474f7f73c609c50837613a0438 [file] [log] [blame]
bellard420557e2004-09-30 22:13:50 +00001/*
blueswir1ee76f822007-12-28 20:59:23 +00002 * QEMU Sun4m & Sun4d & Sun4c System Emulator
ths5fafdf22007-09-16 21:08:06 +00003 *
bellardb81b3b12005-04-06 20:43:37 +00004 * Copyright (c) 2003-2005 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellard420557e2004-09-30 22:13:50 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
pbrook87ecb682007-11-17 17:14:51 +000024#include "hw.h"
25#include "qemu-timer.h"
26#include "sun4m.h"
27#include "nvram.h"
28#include "sparc32_dma.h"
29#include "fdc.h"
30#include "sysemu.h"
31#include "net.h"
32#include "boards.h"
blueswir1d2c63fc2007-11-14 19:35:16 +000033#include "firmware_abi.h"
blueswir18b17de82008-03-02 08:48:47 +000034#include "scsi.h"
blueswir122548762008-05-10 10:12:00 +000035#include "pc.h"
36#include "isa.h"
blueswir13cce6242008-09-18 18:27:29 +000037#include "fw_cfg.h"
blueswir1b4ed08e2009-01-12 17:38:28 +000038#include "escc.h"
blueswir1d2c63fc2007-11-14 19:35:16 +000039
blueswir1b3a23192007-05-27 16:42:29 +000040//#define DEBUG_IRQ
bellard420557e2004-09-30 22:13:50 +000041
blueswir136cd9212007-04-01 15:44:43 +000042/*
43 * Sun4m architecture was used in the following machines:
44 *
45 * SPARCserver 6xxMP/xx
blueswir177f193d2008-05-12 16:13:33 +000046 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15),
47 * SPARCclassic X (4/10)
blueswir136cd9212007-04-01 15:44:43 +000048 * SPARCstation LX/ZX (4/30)
49 * SPARCstation Voyager
50 * SPARCstation 10/xx, SPARCserver 10/xx
51 * SPARCstation 5, SPARCserver 5
52 * SPARCstation 20/xx, SPARCserver 20
53 * SPARCstation 4
54 *
blueswir17d858922007-12-28 20:57:43 +000055 * Sun4d architecture was used in the following machines:
56 *
57 * SPARCcenter 2000
58 * SPARCserver 1000
59 *
blueswir1ee76f822007-12-28 20:59:23 +000060 * Sun4c architecture was used in the following machines:
61 * SPARCstation 1/1+, SPARCserver 1/1+
62 * SPARCstation SLC
63 * SPARCstation IPC
64 * SPARCstation ELC
65 * SPARCstation IPX
66 *
blueswir136cd9212007-04-01 15:44:43 +000067 * See for example: http://www.sunhelp.org/faq/sunref1.html
68 */
69
blueswir1b3a23192007-05-27 16:42:29 +000070#ifdef DEBUG_IRQ
71#define DPRINTF(fmt, args...) \
72 do { printf("CPUIRQ: " fmt , ##args); } while (0)
73#else
74#define DPRINTF(fmt, args...)
75#endif
76
bellard420557e2004-09-30 22:13:50 +000077#define KERNEL_LOAD_ADDR 0x00004000
bellardb6f479d2005-03-01 21:51:04 +000078#define CMDLINE_ADDR 0x007ff000
bellard713c45f2005-02-22 19:08:41 +000079#define INITRD_LOAD_ADDR 0x00800000
blueswir1a7227722008-11-02 14:44:35 +000080#define PROM_SIZE_MAX (1024 * 1024)
blueswir140ce0a92007-09-24 19:44:09 +000081#define PROM_VADDR 0xffd00000
blueswir1f930d072007-10-06 11:28:21 +000082#define PROM_FILENAME "openbios-sparc32"
blueswir13cce6242008-09-18 18:27:29 +000083#define CFG_ADDR 0xd00000510ULL
blueswir1fbfcf952008-09-18 18:34:28 +000084#define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
bellardb8174932006-09-10 19:25:12 +000085
blueswir1ac2e9d62008-04-27 15:29:18 +000086// Control plane, 8-bit and 24-bit planes
87#define TCX_SIZE (9 * 1024 * 1024)
88
bellardba3c64f2005-12-05 20:31:52 +000089#define MAX_CPUS 16
blueswir1b3a23192007-05-27 16:42:29 +000090#define MAX_PILS 16
bellard420557e2004-09-30 22:13:50 +000091
blueswir1b4ed08e2009-01-12 17:38:28 +000092#define ESCC_CLOCK 4915200
93
blueswir18137cde2008-10-27 15:56:56 +000094struct sun4m_hwdef {
blueswir15dcb6b92007-05-19 12:58:30 +000095 target_phys_addr_t iommu_base, slavio_base;
96 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
97 target_phys_addr_t serial_base, fd_base;
blueswir14c2485d2007-12-27 20:26:23 +000098 target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
blueswir10019ad52008-01-27 09:49:28 +000099 target_phys_addr_t tcx_base, cs_base, apc_base, aux1_base, aux2_base;
blueswir17eb0c8e2007-12-09 17:03:50 +0000100 target_phys_addr_t ecc_base;
101 uint32_t ecc_version;
blueswir136cd9212007-04-01 15:44:43 +0000102 long vram_size, nvram_size;
blueswir16341fdc2007-12-29 20:09:57 +0000103 // IRQ numbers are not PIL ones, but master interrupt controller
blueswir1e3a79bc2008-01-01 20:57:25 +0000104 // register bit numbers
blueswir11572a182008-10-28 17:55:32 +0000105 int esp_irq, le_irq, clock_irq, clock1_irq;
blueswir1e42c20b2008-01-17 21:04:16 +0000106 int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq, ecc_irq;
blueswir1905fdcb2008-09-18 18:33:18 +0000107 uint8_t nvram_machine_id;
108 uint16_t machine_id;
blueswir17fbfb132007-11-17 09:04:09 +0000109 uint32_t iommu_version;
blueswir1e0353fe2007-04-01 15:55:28 +0000110 uint32_t intbit_to_level[32];
blueswir13ebf5aa2007-11-28 20:54:33 +0000111 uint64_t max_mem;
112 const char * const default_cpu_model;
blueswir136cd9212007-04-01 15:44:43 +0000113};
114
blueswir17d858922007-12-28 20:57:43 +0000115#define MAX_IOUNITS 5
116
117struct sun4d_hwdef {
118 target_phys_addr_t iounit_bases[MAX_IOUNITS], slavio_base;
119 target_phys_addr_t counter_base, nvram_base, ms_kb_base;
120 target_phys_addr_t serial_base;
121 target_phys_addr_t espdma_base, esp_base;
122 target_phys_addr_t ledma_base, le_base;
123 target_phys_addr_t tcx_base;
124 target_phys_addr_t sbi_base;
125 unsigned long vram_size, nvram_size;
126 // IRQ numbers are not PIL ones, but SBI register bit numbers
127 int esp_irq, le_irq, clock_irq, clock1_irq;
128 int ser_irq, ms_kb_irq, me_irq;
blueswir1905fdcb2008-09-18 18:33:18 +0000129 uint8_t nvram_machine_id;
130 uint16_t machine_id;
blueswir17d858922007-12-28 20:57:43 +0000131 uint32_t iounit_version;
132 uint64_t max_mem;
133 const char * const default_cpu_model;
134};
135
blueswir18137cde2008-10-27 15:56:56 +0000136struct sun4c_hwdef {
137 target_phys_addr_t iommu_base, slavio_base;
138 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
139 target_phys_addr_t serial_base, fd_base;
140 target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
blueswir11572a182008-10-28 17:55:32 +0000141 target_phys_addr_t tcx_base, aux1_base;
blueswir18137cde2008-10-27 15:56:56 +0000142 long vram_size, nvram_size;
143 // IRQ numbers are not PIL ones, but master interrupt controller
144 // register bit numbers
blueswir11572a182008-10-28 17:55:32 +0000145 int esp_irq, le_irq, clock_irq, clock1_irq;
146 int ser_irq, ms_kb_irq, fd_irq, me_irq;
blueswir18137cde2008-10-27 15:56:56 +0000147 uint8_t nvram_machine_id;
148 uint16_t machine_id;
149 uint32_t iommu_version;
150 uint32_t intbit_to_level[32];
151 uint64_t max_mem;
152 const char * const default_cpu_model;
153};
154
bellard6f7e9ae2005-03-13 09:43:36 +0000155int DMA_get_channel_mode (int nchan)
156{
157 return 0;
158}
159int DMA_read_memory (int nchan, void *buf, int pos, int size)
160{
161 return 0;
162}
163int DMA_write_memory (int nchan, void *buf, int pos, int size)
164{
165 return 0;
166}
167void DMA_hold_DREQ (int nchan) {}
168void DMA_release_DREQ (int nchan) {}
169void DMA_schedule(int nchan) {}
bellard6f7e9ae2005-03-13 09:43:36 +0000170void DMA_init (int high_page_enable) {}
171void DMA_register_channel (int nchan,
172 DMA_transfer_handler transfer_handler,
173 void *opaque)
174{
175}
176
blueswir181864572008-06-20 16:25:56 +0000177static int nvram_boot_set(void *opaque, const char *boot_device)
178{
179 unsigned int i;
180 uint8_t image[sizeof(ohwcfg_v3_t)];
181 ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
182 m48t59_t *nvram = (m48t59_t *)opaque;
183
184 for (i = 0; i < sizeof(image); i++)
185 image[i] = m48t59_read(nvram, i) & 0xff;
186
blueswir1363a37d2008-08-21 17:58:08 +0000187 pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
188 boot_device);
blueswir181864572008-06-20 16:25:56 +0000189 header->nboot_devices = strlen(boot_device) & 0xff;
190 header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
191
192 for (i = 0; i < sizeof(image); i++)
193 m48t59_write(nvram, i, image[i]);
194
195 return 0;
196}
197
bellard819385c2005-10-30 16:58:32 +0000198static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
blueswir16ef05b92008-05-01 18:21:46 +0000199 const char *boot_devices, ram_addr_t RAM_size,
blueswir1f930d072007-10-06 11:28:21 +0000200 uint32_t kernel_size,
201 int width, int height, int depth,
blueswir1905fdcb2008-09-18 18:33:18 +0000202 int nvram_machine_id, const char *arch)
bellarde80cfcf2004-12-19 23:18:01 +0000203{
blueswir1d2c63fc2007-11-14 19:35:16 +0000204 unsigned int i;
blueswir166508602007-05-01 14:16:52 +0000205 uint32_t start, end;
blueswir1d2c63fc2007-11-14 19:35:16 +0000206 uint8_t image[0x1ff0];
207 ohwcfg_v3_t *header = (ohwcfg_v3_t *)&image;
208 struct sparc_arch_cfg *sparc_header;
209 struct OpenBIOS_nvpart_v1 *part_header;
210
211 memset(image, '\0', sizeof(image));
bellarde80cfcf2004-12-19 23:18:01 +0000212
bellard6f7e9ae2005-03-13 09:43:36 +0000213 // Try to match PPC NVRAM
blueswir1363a37d2008-08-21 17:58:08 +0000214 pstrcpy((char *)header->struct_ident, sizeof(header->struct_ident),
215 "QEMU_BIOS");
blueswir1d2c63fc2007-11-14 19:35:16 +0000216 header->struct_version = cpu_to_be32(3); /* structure v3 */
217
218 header->nvram_size = cpu_to_be16(0x2000);
219 header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
220 header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
blueswir1363a37d2008-08-21 17:58:08 +0000221 pstrcpy((char *)header->arch, sizeof(header->arch), arch);
blueswir1d2c63fc2007-11-14 19:35:16 +0000222 header->nb_cpus = smp_cpus & 0xff;
223 header->RAM0_base = 0;
224 header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
blueswir1363a37d2008-08-21 17:58:08 +0000225 pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
226 boot_devices);
blueswir1d2c63fc2007-11-14 19:35:16 +0000227 header->nboot_devices = strlen(boot_devices) & 0xff;
228 header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR);
229 header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
bellardb6f479d2005-03-01 21:51:04 +0000230 if (cmdline) {
blueswir1293f78b2008-05-12 17:22:13 +0000231 pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline);
blueswir1d2c63fc2007-11-14 19:35:16 +0000232 header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
233 header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
bellardb6f479d2005-03-01 21:51:04 +0000234 }
blueswir1d2c63fc2007-11-14 19:35:16 +0000235 // XXX add initrd_image, initrd_size
236 header->width = cpu_to_be16(width);
237 header->height = cpu_to_be16(height);
238 header->depth = cpu_to_be16(depth);
239 if (nographic)
240 header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
241
242 header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
243
244 // Architecture specific header
245 start = sizeof(ohwcfg_v3_t);
246 sparc_header = (struct sparc_arch_cfg *)&image[start];
247 sparc_header->valid = 0;
248 start += sizeof(struct sparc_arch_cfg);
bellardb6f479d2005-03-01 21:51:04 +0000249
blueswir166508602007-05-01 14:16:52 +0000250 // OpenBIOS nvram variables
251 // Variable partition
blueswir1d2c63fc2007-11-14 19:35:16 +0000252 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
253 part_header->signature = OPENBIOS_PART_SYSTEM;
blueswir1363a37d2008-08-21 17:58:08 +0000254 pstrcpy(part_header->name, sizeof(part_header->name), "system");
blueswir166508602007-05-01 14:16:52 +0000255
blueswir1d2c63fc2007-11-14 19:35:16 +0000256 end = start + sizeof(struct OpenBIOS_nvpart_v1);
blueswir166508602007-05-01 14:16:52 +0000257 for (i = 0; i < nb_prom_envs; i++)
blueswir1d2c63fc2007-11-14 19:35:16 +0000258 end = OpenBIOS_set_var(image, end, prom_envs[i]);
blueswir166508602007-05-01 14:16:52 +0000259
blueswir1d2c63fc2007-11-14 19:35:16 +0000260 // End marker
261 image[end++] = '\0';
262
blueswir166508602007-05-01 14:16:52 +0000263 end = start + ((end - start + 15) & ~15);
blueswir1d2c63fc2007-11-14 19:35:16 +0000264 OpenBIOS_finish_partition(part_header, end - start);
blueswir166508602007-05-01 14:16:52 +0000265
266 // free partition
267 start = end;
blueswir1d2c63fc2007-11-14 19:35:16 +0000268 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
269 part_header->signature = OPENBIOS_PART_FREE;
blueswir1363a37d2008-08-21 17:58:08 +0000270 pstrcpy(part_header->name, sizeof(part_header->name), "free");
blueswir166508602007-05-01 14:16:52 +0000271
272 end = 0x1fd0;
blueswir1d2c63fc2007-11-14 19:35:16 +0000273 OpenBIOS_finish_partition(part_header, end - start);
blueswir166508602007-05-01 14:16:52 +0000274
blueswir1905fdcb2008-09-18 18:33:18 +0000275 Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr,
276 nvram_machine_id);
bellarde80cfcf2004-12-19 23:18:01 +0000277
blueswir1d2c63fc2007-11-14 19:35:16 +0000278 for (i = 0; i < sizeof(image); i++)
279 m48t59_write(nvram, i, image[i]);
blueswir181864572008-06-20 16:25:56 +0000280
281 qemu_register_boot_set(nvram_boot_set, nvram);
bellarde80cfcf2004-12-19 23:18:01 +0000282}
283
284static void *slavio_intctl;
285
blueswir122548762008-05-10 10:12:00 +0000286void pic_info(void)
bellarde80cfcf2004-12-19 23:18:01 +0000287{
blueswir17d858922007-12-28 20:57:43 +0000288 if (slavio_intctl)
289 slavio_pic_info(slavio_intctl);
bellarde80cfcf2004-12-19 23:18:01 +0000290}
291
blueswir122548762008-05-10 10:12:00 +0000292void irq_info(void)
bellarde80cfcf2004-12-19 23:18:01 +0000293{
blueswir17d858922007-12-28 20:57:43 +0000294 if (slavio_intctl)
295 slavio_irq_info(slavio_intctl);
bellarde80cfcf2004-12-19 23:18:01 +0000296}
297
blueswir1327ac2e2007-08-04 10:50:30 +0000298void cpu_check_irqs(CPUState *env)
299{
300 if (env->pil_in && (env->interrupt_index == 0 ||
301 (env->interrupt_index & ~15) == TT_EXTINT)) {
302 unsigned int i;
303
304 for (i = 15; i > 0; i--) {
305 if (env->pil_in & (1 << i)) {
306 int old_interrupt = env->interrupt_index;
307
308 env->interrupt_index = TT_EXTINT | i;
blueswir1f32d7ec2008-03-04 20:29:59 +0000309 if (old_interrupt != env->interrupt_index) {
310 DPRINTF("Set CPU IRQ %d\n", i);
blueswir1327ac2e2007-08-04 10:50:30 +0000311 cpu_interrupt(env, CPU_INTERRUPT_HARD);
blueswir1f32d7ec2008-03-04 20:29:59 +0000312 }
blueswir1327ac2e2007-08-04 10:50:30 +0000313 break;
314 }
315 }
316 } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
blueswir1f32d7ec2008-03-04 20:29:59 +0000317 DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
blueswir1327ac2e2007-08-04 10:50:30 +0000318 env->interrupt_index = 0;
319 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
320 }
321}
322
blueswir1b3a23192007-05-27 16:42:29 +0000323static void cpu_set_irq(void *opaque, int irq, int level)
324{
325 CPUState *env = opaque;
326
327 if (level) {
328 DPRINTF("Raise CPU IRQ %d\n", irq);
blueswir1b3a23192007-05-27 16:42:29 +0000329 env->halted = 0;
blueswir1327ac2e2007-08-04 10:50:30 +0000330 env->pil_in |= 1 << irq;
331 cpu_check_irqs(env);
blueswir1b3a23192007-05-27 16:42:29 +0000332 } else {
333 DPRINTF("Lower CPU IRQ %d\n", irq);
blueswir1327ac2e2007-08-04 10:50:30 +0000334 env->pil_in &= ~(1 << irq);
335 cpu_check_irqs(env);
blueswir1b3a23192007-05-27 16:42:29 +0000336 }
337}
338
339static void dummy_cpu_set_irq(void *opaque, int irq, int level)
340{
341}
342
bellard34751872005-07-02 14:31:34 +0000343static void *slavio_misc;
344
345void qemu_system_powerdown(void)
346{
347 slavio_set_power_fail(slavio_misc, 1);
348}
349
bellardc68ea702005-11-21 23:33:12 +0000350static void main_cpu_reset(void *opaque)
351{
352 CPUState *env = opaque;
blueswir13d29fbe2007-05-17 19:21:46 +0000353
bellardc68ea702005-11-21 23:33:12 +0000354 cpu_reset(env);
blueswir13d29fbe2007-05-17 19:21:46 +0000355 env->halted = 0;
356}
357
358static void secondary_cpu_reset(void *opaque)
359{
360 CPUState *env = opaque;
361
362 cpu_reset(env);
363 env->halted = 1;
bellardc68ea702005-11-21 23:33:12 +0000364}
365
blueswir16d0c2932008-11-02 10:51:05 +0000366static void cpu_halt_signal(void *opaque, int irq, int level)
367{
368 if (level && cpu_single_env)
369 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
370}
371
blueswir13ebf5aa2007-11-28 20:54:33 +0000372static unsigned long sun4m_load_kernel(const char *kernel_filename,
blueswir1293f78b2008-05-12 17:22:13 +0000373 const char *initrd_filename,
374 ram_addr_t RAM_size)
blueswir13ebf5aa2007-11-28 20:54:33 +0000375{
376 int linux_boot;
377 unsigned int i;
378 long initrd_size, kernel_size;
379
380 linux_boot = (kernel_filename != NULL);
381
382 kernel_size = 0;
383 if (linux_boot) {
384 kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
385 NULL);
386 if (kernel_size < 0)
blueswir1293f78b2008-05-12 17:22:13 +0000387 kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
388 RAM_size - KERNEL_LOAD_ADDR);
blueswir13ebf5aa2007-11-28 20:54:33 +0000389 if (kernel_size < 0)
blueswir1293f78b2008-05-12 17:22:13 +0000390 kernel_size = load_image_targphys(kernel_filename,
391 KERNEL_LOAD_ADDR,
392 RAM_size - KERNEL_LOAD_ADDR);
blueswir13ebf5aa2007-11-28 20:54:33 +0000393 if (kernel_size < 0) {
394 fprintf(stderr, "qemu: could not load kernel '%s'\n",
395 kernel_filename);
396 exit(1);
397 }
398
399 /* load initrd */
400 initrd_size = 0;
401 if (initrd_filename) {
blueswir1293f78b2008-05-12 17:22:13 +0000402 initrd_size = load_image_targphys(initrd_filename,
403 INITRD_LOAD_ADDR,
404 RAM_size - INITRD_LOAD_ADDR);
blueswir13ebf5aa2007-11-28 20:54:33 +0000405 if (initrd_size < 0) {
406 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
407 initrd_filename);
408 exit(1);
409 }
410 }
411 if (initrd_size > 0) {
412 for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
blueswir1293f78b2008-05-12 17:22:13 +0000413 if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
414 stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
415 stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
blueswir13ebf5aa2007-11-28 20:54:33 +0000416 break;
417 }
418 }
419 }
420 }
421 return kernel_size;
422}
423
blueswir18137cde2008-10-27 15:56:56 +0000424static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
blueswir13ebf5aa2007-11-28 20:54:33 +0000425 const char *boot_device,
aliguori3023f332009-01-16 19:04:14 +0000426 const char *kernel_filename,
blueswir13ebf5aa2007-11-28 20:54:33 +0000427 const char *kernel_cmdline,
428 const char *initrd_filename, const char *cpu_model)
blueswir136cd9212007-04-01 15:44:43 +0000429
bellard420557e2004-09-30 22:13:50 +0000430{
bellardba3c64f2005-12-05 20:31:52 +0000431 CPUState *env, *envs[MAX_CPUS];
bellard713c45f2005-02-22 19:08:41 +0000432 unsigned int i;
blueswir1b3ceef22007-06-25 19:56:13 +0000433 void *iommu, *espdma, *ledma, *main_esp, *nvram;
blueswir1b3a23192007-05-27 16:42:29 +0000434 qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
blueswir1d7edfd22007-05-27 16:37:49 +0000435 *espdma_irq, *ledma_irq;
blueswir12d069ba2007-08-16 19:56:27 +0000436 qemu_irq *esp_reset, *le_reset;
blueswir12be17eb2008-03-21 18:05:23 +0000437 qemu_irq *fdc_tc;
blueswir16d0c2932008-11-02 10:51:05 +0000438 qemu_irq *cpu_halt;
blueswir15c6602c2008-11-05 19:25:39 +0000439 ram_addr_t ram_offset, prom_offset, tcx_offset, idreg_offset;
440 unsigned long kernel_size;
blueswir13ebf5aa2007-11-28 20:54:33 +0000441 int ret;
442 char buf[1024];
thse4bcb142007-12-02 04:51:10 +0000443 BlockDriverState *fd[MAX_FD];
blueswir122548762008-05-10 10:12:00 +0000444 int drive_index;
blueswir13cce6242008-09-18 18:27:29 +0000445 void *fw_cfg;
bellard420557e2004-09-30 22:13:50 +0000446
bellardba3c64f2005-12-05 20:31:52 +0000447 /* init CPUs */
blueswir13ebf5aa2007-11-28 20:54:33 +0000448 if (!cpu_model)
449 cpu_model = hwdef->default_cpu_model;
blueswir1b3a23192007-05-27 16:42:29 +0000450
bellardba3c64f2005-12-05 20:31:52 +0000451 for(i = 0; i < smp_cpus; i++) {
bellardaaed9092007-11-10 15:15:54 +0000452 env = cpu_init(cpu_model);
453 if (!env) {
blueswir18e82c6a2008-01-06 07:50:38 +0000454 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
bellardaaed9092007-11-10 15:15:54 +0000455 exit(1);
456 }
457 cpu_sparc_set_id(env, i);
bellardba3c64f2005-12-05 20:31:52 +0000458 envs[i] = env;
blueswir13d29fbe2007-05-17 19:21:46 +0000459 if (i == 0) {
460 qemu_register_reset(main_cpu_reset, env);
461 } else {
462 qemu_register_reset(secondary_cpu_reset, env);
bellardba3c64f2005-12-05 20:31:52 +0000463 env->halted = 1;
blueswir13d29fbe2007-05-17 19:21:46 +0000464 }
blueswir1b3a23192007-05-27 16:42:29 +0000465 cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
blueswir13ebf5aa2007-11-28 20:54:33 +0000466 env->prom_addr = hwdef->slavio_base;
bellardba3c64f2005-12-05 20:31:52 +0000467 }
blueswir1b3a23192007-05-27 16:42:29 +0000468
469 for (i = smp_cpus; i < MAX_CPUS; i++)
470 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
471
blueswir13ebf5aa2007-11-28 20:54:33 +0000472
bellard420557e2004-09-30 22:13:50 +0000473 /* allocate RAM */
blueswir13ebf5aa2007-11-28 20:54:33 +0000474 if ((uint64_t)RAM_size > hwdef->max_mem) {
blueswir177f193d2008-05-12 16:13:33 +0000475 fprintf(stderr,
476 "qemu: Too much memory for this machine: %d, maximum %d\n",
blueswir16ef05b92008-05-01 18:21:46 +0000477 (unsigned int)(RAM_size / (1024 * 1024)),
blueswir13ebf5aa2007-11-28 20:54:33 +0000478 (unsigned int)(hwdef->max_mem / (1024 * 1024)));
479 exit(1);
480 }
blueswir15c6602c2008-11-05 19:25:39 +0000481 ram_offset = qemu_ram_alloc(RAM_size);
482 cpu_register_physical_memory(0, RAM_size, ram_offset);
bellard420557e2004-09-30 22:13:50 +0000483
blueswir13ebf5aa2007-11-28 20:54:33 +0000484 /* load boot prom */
blueswir15c6602c2008-11-05 19:25:39 +0000485 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
blueswir13ebf5aa2007-11-28 20:54:33 +0000486 cpu_register_physical_memory(hwdef->slavio_base,
487 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
488 TARGET_PAGE_MASK,
489 prom_offset | IO_MEM_ROM);
490
491 if (bios_name == NULL)
492 bios_name = PROM_FILENAME;
493 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
494 ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
495 if (ret < 0 || ret > PROM_SIZE_MAX)
blueswir1e01f4a12008-05-13 15:44:10 +0000496 ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);
blueswir13ebf5aa2007-11-28 20:54:33 +0000497 if (ret < 0 || ret > PROM_SIZE_MAX) {
498 fprintf(stderr, "qemu: could not load prom '%s'\n",
499 buf);
500 exit(1);
501 }
502
503 /* set up devices */
blueswir136cd9212007-04-01 15:44:43 +0000504 slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
blueswir15dcb6b92007-05-19 12:58:30 +0000505 hwdef->intctl_base + 0x10000ULL,
pbrookd537cf62007-04-07 18:14:41 +0000506 &hwdef->intbit_to_level[0],
blueswir1d7edfd22007-05-27 16:37:49 +0000507 &slavio_irq, &slavio_cpu_irq,
blueswir1b3a23192007-05-27 16:42:29 +0000508 cpu_irqs,
blueswir1d7edfd22007-05-27 16:37:49 +0000509 hwdef->clock_irq);
blueswir1b3a23192007-05-27 16:42:29 +0000510
blueswir1fe096122008-12-24 20:21:18 +0000511 if (hwdef->idreg_base) {
blueswir1293f78b2008-05-12 17:22:13 +0000512 static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 };
blueswir14c2485d2007-12-27 20:26:23 +0000513
blueswir15c6602c2008-11-05 19:25:39 +0000514 idreg_offset = qemu_ram_alloc(sizeof(idreg_data));
blueswir1293f78b2008-05-12 17:22:13 +0000515 cpu_register_physical_memory(hwdef->idreg_base, sizeof(idreg_data),
blueswir15c6602c2008-11-05 19:25:39 +0000516 idreg_offset | IO_MEM_ROM);
blueswir1293f78b2008-05-12 17:22:13 +0000517 cpu_physical_memory_write_rom(hwdef->idreg_base, idreg_data,
518 sizeof(idreg_data));
blueswir14c2485d2007-12-27 20:26:23 +0000519 }
520
blueswir1ff403da2008-01-01 17:04:45 +0000521 iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
522 slavio_irq[hwdef->me_irq]);
523
blueswir15aca8c32007-05-26 17:39:43 +0000524 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
blueswir12d069ba2007-08-16 19:56:27 +0000525 iommu, &espdma_irq, &esp_reset);
526
blueswir15aca8c32007-05-26 17:39:43 +0000527 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
blueswir12d069ba2007-08-16 19:56:27 +0000528 slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
529 &le_reset);
bellardba3c64f2005-12-05 20:31:52 +0000530
blueswir1eee0b832007-04-21 19:45:49 +0000531 if (graphic_depth != 8 && graphic_depth != 24) {
532 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
533 exit (1);
534 }
blueswir15c6602c2008-11-05 19:25:39 +0000535 tcx_offset = qemu_ram_alloc(hwdef->vram_size);
aliguori3023f332009-01-16 19:04:14 +0000536 tcx_init(hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset,
blueswir1eee0b832007-04-21 19:45:49 +0000537 hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
blueswir1dbe06e12007-05-27 19:38:20 +0000538
aliguori0ae18ce2009-01-13 19:39:36 +0000539 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
blueswir1dbe06e12007-05-27 19:38:20 +0000540
pbrookd537cf62007-04-07 18:14:41 +0000541 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
542 hwdef->nvram_size, 8);
blueswir181732d12007-10-06 11:25:43 +0000543
544 slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
blueswir119f8e5d2007-12-17 18:17:17 +0000545 slavio_cpu_irq, smp_cpus);
blueswir181732d12007-10-06 11:25:43 +0000546
blueswir1577390f2007-12-04 20:58:31 +0000547 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
blueswir1b4ed08e2009-01-12 17:38:28 +0000548 nographic, ESCC_CLOCK, 1);
bellardb81b3b12005-04-06 20:43:37 +0000549 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
550 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
aurel32aeeb69c2009-01-14 14:47:56 +0000551 escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], slavio_irq[hwdef->ser_irq],
552 serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
blueswir1741402f2007-11-04 11:59:15 +0000553
blueswir16d0c2932008-11-02 10:51:05 +0000554 cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);
blueswir12be17eb2008-03-21 18:05:23 +0000555 slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->apc_base,
556 hwdef->aux1_base, hwdef->aux2_base,
blueswir16d0c2932008-11-02 10:51:05 +0000557 slavio_irq[hwdef->me_irq], cpu_halt[0],
blueswir12be17eb2008-03-21 18:05:23 +0000558 &fdc_tc);
559
blueswir1fe096122008-12-24 20:21:18 +0000560 if (hwdef->fd_base) {
thse4bcb142007-12-02 04:51:10 +0000561 /* there is zero or one floppy drive */
blueswir1309e60b2008-02-29 19:26:20 +0000562 memset(fd, 0, sizeof(fd));
blueswir122548762008-05-10 10:12:00 +0000563 drive_index = drive_get_index(IF_FLOPPY, 0, 0);
564 if (drive_index != -1)
565 fd[0] = drives_table[drive_index].bdrv;
blueswir12d069ba2007-08-16 19:56:27 +0000566
blueswir12be17eb2008-03-21 18:05:23 +0000567 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
568 fdc_tc);
thse4bcb142007-12-02 04:51:10 +0000569 }
570
571 if (drive_get_max_bus(IF_SCSI) > 0) {
572 fprintf(stderr, "qemu: too many SCSI bus\n");
573 exit(1);
574 }
575
blueswir15d20fa62008-04-09 16:32:48 +0000576 main_esp = esp_init(hwdef->esp_base, 2,
blueswir18b17de82008-03-02 08:48:47 +0000577 espdma_memory_read, espdma_memory_write,
578 espdma, *espdma_irq, esp_reset);
thsf1587552007-01-10 11:46:13 +0000579
thse4bcb142007-12-02 04:51:10 +0000580 for (i = 0; i < ESP_MAX_DEVS; i++) {
blueswir122548762008-05-10 10:12:00 +0000581 drive_index = drive_get_index(IF_SCSI, 0, i);
582 if (drive_index == -1)
thse4bcb142007-12-02 04:51:10 +0000583 continue;
blueswir122548762008-05-10 10:12:00 +0000584 esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);
thsf1587552007-01-10 11:46:13 +0000585 }
586
blueswir1fe096122008-12-24 20:21:18 +0000587 if (hwdef->cs_base)
blueswir1803b3c72007-04-05 17:00:23 +0000588 cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
blueswir1b3ceef22007-06-25 19:56:13 +0000589
blueswir1293f78b2008-05-12 17:22:13 +0000590 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
591 RAM_size);
blueswir136cd9212007-04-01 15:44:43 +0000592
blueswir136cd9212007-04-01 15:44:43 +0000593 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
blueswir1b3ceef22007-06-25 19:56:13 +0000594 boot_device, RAM_size, kernel_size, graphic_width,
blueswir1905fdcb2008-09-18 18:33:18 +0000595 graphic_height, graphic_depth, hwdef->nvram_machine_id,
596 "Sun4m");
blueswir17eb0c8e2007-12-09 17:03:50 +0000597
blueswir1fe096122008-12-24 20:21:18 +0000598 if (hwdef->ecc_base)
blueswir1e42c20b2008-01-17 21:04:16 +0000599 ecc_init(hwdef->ecc_base, slavio_irq[hwdef->ecc_irq],
600 hwdef->ecc_version);
blueswir13cce6242008-09-18 18:27:29 +0000601
602 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
603 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
blueswir1905fdcb2008-09-18 18:33:18 +0000604 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
605 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
blueswir1fbfcf952008-09-18 18:34:28 +0000606 fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
bellard420557e2004-09-30 22:13:50 +0000607}
bellardc0e564d2005-06-05 15:17:28 +0000608
blueswir1905fdcb2008-09-18 18:33:18 +0000609enum {
610 ss2_id = 0,
611 ss5_id = 32,
612 vger_id,
613 lx_id,
614 ss4_id,
615 scls_id,
616 sbook_id,
617 ss10_id = 64,
618 ss20_id,
619 ss600mp_id,
620 ss1000_id = 96,
621 ss2000_id,
622};
623
blueswir18137cde2008-10-27 15:56:56 +0000624static const struct sun4m_hwdef sun4m_hwdefs[] = {
blueswir136cd9212007-04-01 15:44:43 +0000625 /* SS-5 */
626 {
627 .iommu_base = 0x10000000,
628 .tcx_base = 0x50000000,
629 .cs_base = 0x6c000000,
blueswir1384ccb52007-05-06 17:33:14 +0000630 .slavio_base = 0x70000000,
blueswir136cd9212007-04-01 15:44:43 +0000631 .ms_kb_base = 0x71000000,
632 .serial_base = 0x71100000,
633 .nvram_base = 0x71200000,
634 .fd_base = 0x71400000,
635 .counter_base = 0x71d00000,
636 .intctl_base = 0x71e00000,
blueswir14c2485d2007-12-27 20:26:23 +0000637 .idreg_base = 0x78000000,
blueswir136cd9212007-04-01 15:44:43 +0000638 .dma_base = 0x78400000,
639 .esp_base = 0x78800000,
640 .le_base = 0x78c00000,
blueswir1127fc402008-02-01 20:12:40 +0000641 .apc_base = 0x6a000000,
blueswir10019ad52008-01-27 09:49:28 +0000642 .aux1_base = 0x71900000,
643 .aux2_base = 0x71910000,
blueswir136cd9212007-04-01 15:44:43 +0000644 .vram_size = 0x00100000,
645 .nvram_size = 0x2000,
646 .esp_irq = 18,
647 .le_irq = 16,
blueswir1e3a79bc2008-01-01 20:57:25 +0000648 .clock_irq = 7,
blueswir136cd9212007-04-01 15:44:43 +0000649 .clock1_irq = 19,
650 .ms_kb_irq = 14,
651 .ser_irq = 15,
652 .fd_irq = 22,
653 .me_irq = 30,
654 .cs_irq = 5,
blueswir1905fdcb2008-09-18 18:33:18 +0000655 .nvram_machine_id = 0x80,
656 .machine_id = ss5_id,
blueswir1cf3102a2007-12-29 09:07:00 +0000657 .iommu_version = 0x05000000,
blueswir1e0353fe2007-04-01 15:55:28 +0000658 .intbit_to_level = {
blueswir1f930d072007-10-06 11:28:21 +0000659 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
660 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
blueswir1e0353fe2007-04-01 15:55:28 +0000661 },
blueswir13ebf5aa2007-11-28 20:54:33 +0000662 .max_mem = 0x10000000,
663 .default_cpu_model = "Fujitsu MB86904",
blueswir1e0353fe2007-04-01 15:55:28 +0000664 },
665 /* SS-10 */
blueswir1e0353fe2007-04-01 15:55:28 +0000666 {
blueswir15dcb6b92007-05-19 12:58:30 +0000667 .iommu_base = 0xfe0000000ULL,
668 .tcx_base = 0xe20000000ULL,
blueswir15dcb6b92007-05-19 12:58:30 +0000669 .slavio_base = 0xff0000000ULL,
670 .ms_kb_base = 0xff1000000ULL,
671 .serial_base = 0xff1100000ULL,
672 .nvram_base = 0xff1200000ULL,
673 .fd_base = 0xff1700000ULL,
674 .counter_base = 0xff1300000ULL,
675 .intctl_base = 0xff1400000ULL,
blueswir14c2485d2007-12-27 20:26:23 +0000676 .idreg_base = 0xef0000000ULL,
blueswir15dcb6b92007-05-19 12:58:30 +0000677 .dma_base = 0xef0400000ULL,
678 .esp_base = 0xef0800000ULL,
679 .le_base = 0xef0c00000ULL,
blueswir10019ad52008-01-27 09:49:28 +0000680 .apc_base = 0xefa000000ULL, // XXX should not exist
blueswir1127fc402008-02-01 20:12:40 +0000681 .aux1_base = 0xff1800000ULL,
682 .aux2_base = 0xff1a01000ULL,
blueswir17eb0c8e2007-12-09 17:03:50 +0000683 .ecc_base = 0xf00000000ULL,
684 .ecc_version = 0x10000000, // version 0, implementation 1
blueswir1e0353fe2007-04-01 15:55:28 +0000685 .vram_size = 0x00100000,
686 .nvram_size = 0x2000,
687 .esp_irq = 18,
688 .le_irq = 16,
blueswir1e3a79bc2008-01-01 20:57:25 +0000689 .clock_irq = 7,
blueswir1e0353fe2007-04-01 15:55:28 +0000690 .clock1_irq = 19,
691 .ms_kb_irq = 14,
692 .ser_irq = 15,
693 .fd_irq = 22,
694 .me_irq = 30,
blueswir1e42c20b2008-01-17 21:04:16 +0000695 .ecc_irq = 28,
blueswir1905fdcb2008-09-18 18:33:18 +0000696 .nvram_machine_id = 0x72,
697 .machine_id = ss10_id,
blueswir17fbfb132007-11-17 09:04:09 +0000698 .iommu_version = 0x03000000,
blueswir1e0353fe2007-04-01 15:55:28 +0000699 .intbit_to_level = {
blueswir1f930d072007-10-06 11:28:21 +0000700 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
701 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
blueswir1e0353fe2007-04-01 15:55:28 +0000702 },
blueswir16ef05b92008-05-01 18:21:46 +0000703 .max_mem = 0xf00000000ULL,
blueswir13ebf5aa2007-11-28 20:54:33 +0000704 .default_cpu_model = "TI SuperSparc II",
blueswir136cd9212007-04-01 15:44:43 +0000705 },
blueswir16a3b9cc2007-11-11 17:56:38 +0000706 /* SS-600MP */
707 {
708 .iommu_base = 0xfe0000000ULL,
709 .tcx_base = 0xe20000000ULL,
blueswir16a3b9cc2007-11-11 17:56:38 +0000710 .slavio_base = 0xff0000000ULL,
711 .ms_kb_base = 0xff1000000ULL,
712 .serial_base = 0xff1100000ULL,
713 .nvram_base = 0xff1200000ULL,
blueswir16a3b9cc2007-11-11 17:56:38 +0000714 .counter_base = 0xff1300000ULL,
715 .intctl_base = 0xff1400000ULL,
716 .dma_base = 0xef0081000ULL,
717 .esp_base = 0xef0080000ULL,
718 .le_base = 0xef0060000ULL,
blueswir10019ad52008-01-27 09:49:28 +0000719 .apc_base = 0xefa000000ULL, // XXX should not exist
blueswir1127fc402008-02-01 20:12:40 +0000720 .aux1_base = 0xff1800000ULL,
721 .aux2_base = 0xff1a01000ULL, // XXX should not exist
blueswir17eb0c8e2007-12-09 17:03:50 +0000722 .ecc_base = 0xf00000000ULL,
723 .ecc_version = 0x00000000, // version 0, implementation 0
blueswir16a3b9cc2007-11-11 17:56:38 +0000724 .vram_size = 0x00100000,
725 .nvram_size = 0x2000,
726 .esp_irq = 18,
727 .le_irq = 16,
blueswir1e3a79bc2008-01-01 20:57:25 +0000728 .clock_irq = 7,
blueswir16a3b9cc2007-11-11 17:56:38 +0000729 .clock1_irq = 19,
730 .ms_kb_irq = 14,
731 .ser_irq = 15,
732 .fd_irq = 22,
733 .me_irq = 30,
blueswir1e42c20b2008-01-17 21:04:16 +0000734 .ecc_irq = 28,
blueswir1905fdcb2008-09-18 18:33:18 +0000735 .nvram_machine_id = 0x71,
736 .machine_id = ss600mp_id,
blueswir17fbfb132007-11-17 09:04:09 +0000737 .iommu_version = 0x01000000,
blueswir16a3b9cc2007-11-11 17:56:38 +0000738 .intbit_to_level = {
739 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
740 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
741 },
blueswir16ef05b92008-05-01 18:21:46 +0000742 .max_mem = 0xf00000000ULL,
blueswir13ebf5aa2007-11-28 20:54:33 +0000743 .default_cpu_model = "TI SuperSparc II",
blueswir16a3b9cc2007-11-11 17:56:38 +0000744 },
blueswir1ae409722007-12-10 20:00:11 +0000745 /* SS-20 */
746 {
747 .iommu_base = 0xfe0000000ULL,
748 .tcx_base = 0xe20000000ULL,
blueswir1ae409722007-12-10 20:00:11 +0000749 .slavio_base = 0xff0000000ULL,
750 .ms_kb_base = 0xff1000000ULL,
751 .serial_base = 0xff1100000ULL,
752 .nvram_base = 0xff1200000ULL,
753 .fd_base = 0xff1700000ULL,
754 .counter_base = 0xff1300000ULL,
755 .intctl_base = 0xff1400000ULL,
blueswir14c2485d2007-12-27 20:26:23 +0000756 .idreg_base = 0xef0000000ULL,
blueswir1ae409722007-12-10 20:00:11 +0000757 .dma_base = 0xef0400000ULL,
758 .esp_base = 0xef0800000ULL,
759 .le_base = 0xef0c00000ULL,
blueswir10019ad52008-01-27 09:49:28 +0000760 .apc_base = 0xefa000000ULL, // XXX should not exist
blueswir1577d8dd2008-02-11 20:01:36 +0000761 .aux1_base = 0xff1800000ULL,
762 .aux2_base = 0xff1a01000ULL,
blueswir1ae409722007-12-10 20:00:11 +0000763 .ecc_base = 0xf00000000ULL,
764 .ecc_version = 0x20000000, // version 0, implementation 2
765 .vram_size = 0x00100000,
766 .nvram_size = 0x2000,
767 .esp_irq = 18,
768 .le_irq = 16,
blueswir1e3a79bc2008-01-01 20:57:25 +0000769 .clock_irq = 7,
blueswir1ae409722007-12-10 20:00:11 +0000770 .clock1_irq = 19,
771 .ms_kb_irq = 14,
772 .ser_irq = 15,
773 .fd_irq = 22,
774 .me_irq = 30,
blueswir1e42c20b2008-01-17 21:04:16 +0000775 .ecc_irq = 28,
blueswir1905fdcb2008-09-18 18:33:18 +0000776 .nvram_machine_id = 0x72,
777 .machine_id = ss20_id,
blueswir1ae409722007-12-10 20:00:11 +0000778 .iommu_version = 0x13000000,
779 .intbit_to_level = {
780 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
781 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
782 },
blueswir16ef05b92008-05-01 18:21:46 +0000783 .max_mem = 0xf00000000ULL,
blueswir1ae409722007-12-10 20:00:11 +0000784 .default_cpu_model = "TI SuperSparc II",
785 },
blueswir1a526a312008-03-05 18:27:45 +0000786 /* Voyager */
787 {
788 .iommu_base = 0x10000000,
789 .tcx_base = 0x50000000,
blueswir1a526a312008-03-05 18:27:45 +0000790 .slavio_base = 0x70000000,
791 .ms_kb_base = 0x71000000,
792 .serial_base = 0x71100000,
793 .nvram_base = 0x71200000,
794 .fd_base = 0x71400000,
795 .counter_base = 0x71d00000,
796 .intctl_base = 0x71e00000,
797 .idreg_base = 0x78000000,
798 .dma_base = 0x78400000,
799 .esp_base = 0x78800000,
800 .le_base = 0x78c00000,
801 .apc_base = 0x71300000, // pmc
802 .aux1_base = 0x71900000,
803 .aux2_base = 0x71910000,
blueswir1a526a312008-03-05 18:27:45 +0000804 .vram_size = 0x00100000,
805 .nvram_size = 0x2000,
806 .esp_irq = 18,
807 .le_irq = 16,
808 .clock_irq = 7,
809 .clock1_irq = 19,
810 .ms_kb_irq = 14,
811 .ser_irq = 15,
812 .fd_irq = 22,
813 .me_irq = 30,
blueswir1905fdcb2008-09-18 18:33:18 +0000814 .nvram_machine_id = 0x80,
815 .machine_id = vger_id,
blueswir1a526a312008-03-05 18:27:45 +0000816 .iommu_version = 0x05000000,
817 .intbit_to_level = {
818 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
819 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
820 },
821 .max_mem = 0x10000000,
822 .default_cpu_model = "Fujitsu MB86904",
823 },
824 /* LX */
825 {
826 .iommu_base = 0x10000000,
827 .tcx_base = 0x50000000,
blueswir1a526a312008-03-05 18:27:45 +0000828 .slavio_base = 0x70000000,
829 .ms_kb_base = 0x71000000,
830 .serial_base = 0x71100000,
831 .nvram_base = 0x71200000,
832 .fd_base = 0x71400000,
833 .counter_base = 0x71d00000,
834 .intctl_base = 0x71e00000,
835 .idreg_base = 0x78000000,
836 .dma_base = 0x78400000,
837 .esp_base = 0x78800000,
838 .le_base = 0x78c00000,
blueswir1a526a312008-03-05 18:27:45 +0000839 .aux1_base = 0x71900000,
840 .aux2_base = 0x71910000,
blueswir1a526a312008-03-05 18:27:45 +0000841 .vram_size = 0x00100000,
842 .nvram_size = 0x2000,
843 .esp_irq = 18,
844 .le_irq = 16,
845 .clock_irq = 7,
846 .clock1_irq = 19,
847 .ms_kb_irq = 14,
848 .ser_irq = 15,
849 .fd_irq = 22,
850 .me_irq = 30,
blueswir1905fdcb2008-09-18 18:33:18 +0000851 .nvram_machine_id = 0x80,
852 .machine_id = lx_id,
blueswir1a526a312008-03-05 18:27:45 +0000853 .iommu_version = 0x04000000,
854 .intbit_to_level = {
855 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
856 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
857 },
858 .max_mem = 0x10000000,
859 .default_cpu_model = "TI MicroSparc I",
860 },
861 /* SS-4 */
862 {
863 .iommu_base = 0x10000000,
864 .tcx_base = 0x50000000,
865 .cs_base = 0x6c000000,
866 .slavio_base = 0x70000000,
867 .ms_kb_base = 0x71000000,
868 .serial_base = 0x71100000,
869 .nvram_base = 0x71200000,
870 .fd_base = 0x71400000,
871 .counter_base = 0x71d00000,
872 .intctl_base = 0x71e00000,
873 .idreg_base = 0x78000000,
874 .dma_base = 0x78400000,
875 .esp_base = 0x78800000,
876 .le_base = 0x78c00000,
877 .apc_base = 0x6a000000,
878 .aux1_base = 0x71900000,
879 .aux2_base = 0x71910000,
blueswir1a526a312008-03-05 18:27:45 +0000880 .vram_size = 0x00100000,
881 .nvram_size = 0x2000,
882 .esp_irq = 18,
883 .le_irq = 16,
884 .clock_irq = 7,
885 .clock1_irq = 19,
886 .ms_kb_irq = 14,
887 .ser_irq = 15,
888 .fd_irq = 22,
889 .me_irq = 30,
890 .cs_irq = 5,
blueswir1905fdcb2008-09-18 18:33:18 +0000891 .nvram_machine_id = 0x80,
892 .machine_id = ss4_id,
blueswir1a526a312008-03-05 18:27:45 +0000893 .iommu_version = 0x05000000,
894 .intbit_to_level = {
895 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
896 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
897 },
898 .max_mem = 0x10000000,
899 .default_cpu_model = "Fujitsu MB86904",
900 },
901 /* SPARCClassic */
902 {
903 .iommu_base = 0x10000000,
904 .tcx_base = 0x50000000,
blueswir1a526a312008-03-05 18:27:45 +0000905 .slavio_base = 0x70000000,
906 .ms_kb_base = 0x71000000,
907 .serial_base = 0x71100000,
908 .nvram_base = 0x71200000,
909 .fd_base = 0x71400000,
910 .counter_base = 0x71d00000,
911 .intctl_base = 0x71e00000,
912 .idreg_base = 0x78000000,
913 .dma_base = 0x78400000,
914 .esp_base = 0x78800000,
915 .le_base = 0x78c00000,
916 .apc_base = 0x6a000000,
917 .aux1_base = 0x71900000,
918 .aux2_base = 0x71910000,
blueswir1a526a312008-03-05 18:27:45 +0000919 .vram_size = 0x00100000,
920 .nvram_size = 0x2000,
921 .esp_irq = 18,
922 .le_irq = 16,
923 .clock_irq = 7,
924 .clock1_irq = 19,
925 .ms_kb_irq = 14,
926 .ser_irq = 15,
927 .fd_irq = 22,
928 .me_irq = 30,
blueswir1905fdcb2008-09-18 18:33:18 +0000929 .nvram_machine_id = 0x80,
930 .machine_id = scls_id,
blueswir1a526a312008-03-05 18:27:45 +0000931 .iommu_version = 0x05000000,
932 .intbit_to_level = {
933 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
934 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
935 },
936 .max_mem = 0x10000000,
937 .default_cpu_model = "TI MicroSparc I",
938 },
939 /* SPARCbook */
940 {
941 .iommu_base = 0x10000000,
942 .tcx_base = 0x50000000, // XXX
blueswir1a526a312008-03-05 18:27:45 +0000943 .slavio_base = 0x70000000,
944 .ms_kb_base = 0x71000000,
945 .serial_base = 0x71100000,
946 .nvram_base = 0x71200000,
947 .fd_base = 0x71400000,
948 .counter_base = 0x71d00000,
949 .intctl_base = 0x71e00000,
950 .idreg_base = 0x78000000,
951 .dma_base = 0x78400000,
952 .esp_base = 0x78800000,
953 .le_base = 0x78c00000,
954 .apc_base = 0x6a000000,
955 .aux1_base = 0x71900000,
956 .aux2_base = 0x71910000,
blueswir1a526a312008-03-05 18:27:45 +0000957 .vram_size = 0x00100000,
958 .nvram_size = 0x2000,
959 .esp_irq = 18,
960 .le_irq = 16,
961 .clock_irq = 7,
962 .clock1_irq = 19,
963 .ms_kb_irq = 14,
964 .ser_irq = 15,
965 .fd_irq = 22,
966 .me_irq = 30,
blueswir1905fdcb2008-09-18 18:33:18 +0000967 .nvram_machine_id = 0x80,
968 .machine_id = sbook_id,
blueswir1a526a312008-03-05 18:27:45 +0000969 .iommu_version = 0x05000000,
970 .intbit_to_level = {
971 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
972 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
973 },
974 .max_mem = 0x10000000,
975 .default_cpu_model = "TI MicroSparc I",
976 },
blueswir136cd9212007-04-01 15:44:43 +0000977};
978
blueswir136cd9212007-04-01 15:44:43 +0000979/* SPARCstation 5 hardware initialisation */
aurel3200f82b82008-04-27 21:12:55 +0000980static void ss5_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +0000981 const char *boot_device,
blueswir1b881c2c2007-11-18 08:46:58 +0000982 const char *kernel_filename, const char *kernel_cmdline,
983 const char *initrd_filename, const char *cpu_model)
blueswir136cd9212007-04-01 15:44:43 +0000984{
aliguori3023f332009-01-16 19:04:14 +0000985 sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
blueswir13ebf5aa2007-11-28 20:54:33 +0000986 kernel_cmdline, initrd_filename, cpu_model);
blueswir136cd9212007-04-01 15:44:43 +0000987}
988
blueswir1e0353fe2007-04-01 15:55:28 +0000989/* SPARCstation 10 hardware initialisation */
aurel3200f82b82008-04-27 21:12:55 +0000990static void ss10_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +0000991 const char *boot_device,
blueswir1b881c2c2007-11-18 08:46:58 +0000992 const char *kernel_filename, const char *kernel_cmdline,
993 const char *initrd_filename, const char *cpu_model)
blueswir1e0353fe2007-04-01 15:55:28 +0000994{
aliguori3023f332009-01-16 19:04:14 +0000995 sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
blueswir13ebf5aa2007-11-28 20:54:33 +0000996 kernel_cmdline, initrd_filename, cpu_model);
blueswir1e0353fe2007-04-01 15:55:28 +0000997}
998
blueswir16a3b9cc2007-11-11 17:56:38 +0000999/* SPARCserver 600MP hardware initialisation */
aurel3200f82b82008-04-27 21:12:55 +00001000static void ss600mp_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001001 const char *boot_device,
blueswir177f193d2008-05-12 16:13:33 +00001002 const char *kernel_filename,
1003 const char *kernel_cmdline,
blueswir16a3b9cc2007-11-11 17:56:38 +00001004 const char *initrd_filename, const char *cpu_model)
1005{
aliguori3023f332009-01-16 19:04:14 +00001006 sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
blueswir13ebf5aa2007-11-28 20:54:33 +00001007 kernel_cmdline, initrd_filename, cpu_model);
blueswir16a3b9cc2007-11-11 17:56:38 +00001008}
1009
blueswir1ae409722007-12-10 20:00:11 +00001010/* SPARCstation 20 hardware initialisation */
aurel3200f82b82008-04-27 21:12:55 +00001011static void ss20_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001012 const char *boot_device,
blueswir1ae409722007-12-10 20:00:11 +00001013 const char *kernel_filename, const char *kernel_cmdline,
1014 const char *initrd_filename, const char *cpu_model)
1015{
aliguori3023f332009-01-16 19:04:14 +00001016 sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
blueswir1ee76f822007-12-28 20:59:23 +00001017 kernel_cmdline, initrd_filename, cpu_model);
1018}
1019
blueswir1a526a312008-03-05 18:27:45 +00001020/* SPARCstation Voyager hardware initialisation */
blueswir16ef05b92008-05-01 18:21:46 +00001021static void vger_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001022 const char *boot_device,
blueswir1a526a312008-03-05 18:27:45 +00001023 const char *kernel_filename, const char *kernel_cmdline,
1024 const char *initrd_filename, const char *cpu_model)
1025{
aliguori3023f332009-01-16 19:04:14 +00001026 sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
blueswir1a526a312008-03-05 18:27:45 +00001027 kernel_cmdline, initrd_filename, cpu_model);
1028}
1029
1030/* SPARCstation LX hardware initialisation */
blueswir16ef05b92008-05-01 18:21:46 +00001031static void ss_lx_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001032 const char *boot_device,
blueswir1a526a312008-03-05 18:27:45 +00001033 const char *kernel_filename, const char *kernel_cmdline,
1034 const char *initrd_filename, const char *cpu_model)
1035{
aliguori3023f332009-01-16 19:04:14 +00001036 sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
blueswir1a526a312008-03-05 18:27:45 +00001037 kernel_cmdline, initrd_filename, cpu_model);
1038}
1039
1040/* SPARCstation 4 hardware initialisation */
blueswir16ef05b92008-05-01 18:21:46 +00001041static void ss4_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001042 const char *boot_device,
blueswir1a526a312008-03-05 18:27:45 +00001043 const char *kernel_filename, const char *kernel_cmdline,
1044 const char *initrd_filename, const char *cpu_model)
1045{
aliguori3023f332009-01-16 19:04:14 +00001046 sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
blueswir1a526a312008-03-05 18:27:45 +00001047 kernel_cmdline, initrd_filename, cpu_model);
1048}
1049
1050/* SPARCClassic hardware initialisation */
blueswir16ef05b92008-05-01 18:21:46 +00001051static void scls_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001052 const char *boot_device,
blueswir1a526a312008-03-05 18:27:45 +00001053 const char *kernel_filename, const char *kernel_cmdline,
1054 const char *initrd_filename, const char *cpu_model)
1055{
aliguori3023f332009-01-16 19:04:14 +00001056 sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
blueswir1a526a312008-03-05 18:27:45 +00001057 kernel_cmdline, initrd_filename, cpu_model);
1058}
1059
1060/* SPARCbook hardware initialisation */
blueswir16ef05b92008-05-01 18:21:46 +00001061static void sbook_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001062 const char *boot_device,
blueswir1a526a312008-03-05 18:27:45 +00001063 const char *kernel_filename, const char *kernel_cmdline,
1064 const char *initrd_filename, const char *cpu_model)
1065{
aliguori3023f332009-01-16 19:04:14 +00001066 sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
blueswir1a526a312008-03-05 18:27:45 +00001067 kernel_cmdline, initrd_filename, cpu_model);
1068}
1069
blueswir136cd9212007-04-01 15:44:43 +00001070QEMUMachine ss5_machine = {
blueswir166de7332008-08-12 15:51:09 +00001071 .name = "SS-5",
1072 .desc = "Sun4m platform, SPARCstation 5",
1073 .init = ss5_init,
1074 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001075 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001076 .use_scsi = 1,
bellardc0e564d2005-06-05 15:17:28 +00001077};
blueswir1e0353fe2007-04-01 15:55:28 +00001078
1079QEMUMachine ss10_machine = {
blueswir166de7332008-08-12 15:51:09 +00001080 .name = "SS-10",
1081 .desc = "Sun4m platform, SPARCstation 10",
1082 .init = ss10_init,
1083 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001084 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001085 .use_scsi = 1,
blueswir11bcee012008-11-02 16:51:02 +00001086 .max_cpus = 4,
blueswir1e0353fe2007-04-01 15:55:28 +00001087};
blueswir16a3b9cc2007-11-11 17:56:38 +00001088
1089QEMUMachine ss600mp_machine = {
blueswir166de7332008-08-12 15:51:09 +00001090 .name = "SS-600MP",
1091 .desc = "Sun4m platform, SPARCserver 600MP",
1092 .init = ss600mp_init,
1093 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001094 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001095 .use_scsi = 1,
blueswir11bcee012008-11-02 16:51:02 +00001096 .max_cpus = 4,
blueswir16a3b9cc2007-11-11 17:56:38 +00001097};
blueswir1ae409722007-12-10 20:00:11 +00001098
1099QEMUMachine ss20_machine = {
blueswir166de7332008-08-12 15:51:09 +00001100 .name = "SS-20",
1101 .desc = "Sun4m platform, SPARCstation 20",
1102 .init = ss20_init,
1103 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001104 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001105 .use_scsi = 1,
blueswir11bcee012008-11-02 16:51:02 +00001106 .max_cpus = 4,
blueswir1ae409722007-12-10 20:00:11 +00001107};
1108
blueswir1a526a312008-03-05 18:27:45 +00001109QEMUMachine voyager_machine = {
blueswir166de7332008-08-12 15:51:09 +00001110 .name = "Voyager",
1111 .desc = "Sun4m platform, SPARCstation Voyager",
1112 .init = vger_init,
1113 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001114 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001115 .use_scsi = 1,
blueswir1a526a312008-03-05 18:27:45 +00001116};
1117
1118QEMUMachine ss_lx_machine = {
blueswir166de7332008-08-12 15:51:09 +00001119 .name = "LX",
1120 .desc = "Sun4m platform, SPARCstation LX",
1121 .init = ss_lx_init,
1122 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001123 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001124 .use_scsi = 1,
blueswir1a526a312008-03-05 18:27:45 +00001125};
1126
1127QEMUMachine ss4_machine = {
blueswir166de7332008-08-12 15:51:09 +00001128 .name = "SS-4",
1129 .desc = "Sun4m platform, SPARCstation 4",
1130 .init = ss4_init,
1131 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001132 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001133 .use_scsi = 1,
blueswir1a526a312008-03-05 18:27:45 +00001134};
1135
1136QEMUMachine scls_machine = {
blueswir166de7332008-08-12 15:51:09 +00001137 .name = "SPARCClassic",
1138 .desc = "Sun4m platform, SPARCClassic",
1139 .init = scls_init,
1140 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001141 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001142 .use_scsi = 1,
blueswir1a526a312008-03-05 18:27:45 +00001143};
1144
1145QEMUMachine sbook_machine = {
blueswir166de7332008-08-12 15:51:09 +00001146 .name = "SPARCbook",
1147 .desc = "Sun4m platform, SPARCbook",
1148 .init = sbook_init,
1149 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001150 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001151 .use_scsi = 1,
blueswir1a526a312008-03-05 18:27:45 +00001152};
1153
blueswir17d858922007-12-28 20:57:43 +00001154static const struct sun4d_hwdef sun4d_hwdefs[] = {
1155 /* SS-1000 */
1156 {
1157 .iounit_bases = {
1158 0xfe0200000ULL,
1159 0xfe1200000ULL,
1160 0xfe2200000ULL,
1161 0xfe3200000ULL,
1162 -1,
1163 },
1164 .tcx_base = 0x820000000ULL,
1165 .slavio_base = 0xf00000000ULL,
1166 .ms_kb_base = 0xf00240000ULL,
1167 .serial_base = 0xf00200000ULL,
1168 .nvram_base = 0xf00280000ULL,
1169 .counter_base = 0xf00300000ULL,
1170 .espdma_base = 0x800081000ULL,
1171 .esp_base = 0x800080000ULL,
1172 .ledma_base = 0x800040000ULL,
1173 .le_base = 0x800060000ULL,
1174 .sbi_base = 0xf02800000ULL,
blueswir1c1d00dc2008-04-27 16:43:11 +00001175 .vram_size = 0x00100000,
blueswir17d858922007-12-28 20:57:43 +00001176 .nvram_size = 0x2000,
1177 .esp_irq = 3,
1178 .le_irq = 4,
1179 .clock_irq = 14,
1180 .clock1_irq = 10,
1181 .ms_kb_irq = 12,
1182 .ser_irq = 12,
blueswir1905fdcb2008-09-18 18:33:18 +00001183 .nvram_machine_id = 0x80,
1184 .machine_id = ss1000_id,
blueswir17d858922007-12-28 20:57:43 +00001185 .iounit_version = 0x03000000,
blueswir16ef05b92008-05-01 18:21:46 +00001186 .max_mem = 0xf00000000ULL,
blueswir17d858922007-12-28 20:57:43 +00001187 .default_cpu_model = "TI SuperSparc II",
1188 },
1189 /* SS-2000 */
1190 {
1191 .iounit_bases = {
1192 0xfe0200000ULL,
1193 0xfe1200000ULL,
1194 0xfe2200000ULL,
1195 0xfe3200000ULL,
1196 0xfe4200000ULL,
1197 },
1198 .tcx_base = 0x820000000ULL,
1199 .slavio_base = 0xf00000000ULL,
1200 .ms_kb_base = 0xf00240000ULL,
1201 .serial_base = 0xf00200000ULL,
1202 .nvram_base = 0xf00280000ULL,
1203 .counter_base = 0xf00300000ULL,
1204 .espdma_base = 0x800081000ULL,
1205 .esp_base = 0x800080000ULL,
1206 .ledma_base = 0x800040000ULL,
1207 .le_base = 0x800060000ULL,
1208 .sbi_base = 0xf02800000ULL,
blueswir1c1d00dc2008-04-27 16:43:11 +00001209 .vram_size = 0x00100000,
blueswir17d858922007-12-28 20:57:43 +00001210 .nvram_size = 0x2000,
1211 .esp_irq = 3,
1212 .le_irq = 4,
1213 .clock_irq = 14,
1214 .clock1_irq = 10,
1215 .ms_kb_irq = 12,
1216 .ser_irq = 12,
blueswir1905fdcb2008-09-18 18:33:18 +00001217 .nvram_machine_id = 0x80,
1218 .machine_id = ss2000_id,
blueswir17d858922007-12-28 20:57:43 +00001219 .iounit_version = 0x03000000,
blueswir16ef05b92008-05-01 18:21:46 +00001220 .max_mem = 0xf00000000ULL,
blueswir17d858922007-12-28 20:57:43 +00001221 .default_cpu_model = "TI SuperSparc II",
1222 },
1223};
1224
blueswir16ef05b92008-05-01 18:21:46 +00001225static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
blueswir17d858922007-12-28 20:57:43 +00001226 const char *boot_device,
aliguori3023f332009-01-16 19:04:14 +00001227 const char *kernel_filename,
blueswir17d858922007-12-28 20:57:43 +00001228 const char *kernel_cmdline,
1229 const char *initrd_filename, const char *cpu_model)
1230{
1231 CPUState *env, *envs[MAX_CPUS];
1232 unsigned int i;
1233 void *iounits[MAX_IOUNITS], *espdma, *ledma, *main_esp, *nvram, *sbi;
1234 qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq,
1235 *espdma_irq, *ledma_irq;
1236 qemu_irq *esp_reset, *le_reset;
blueswir15c6602c2008-11-05 19:25:39 +00001237 ram_addr_t ram_offset, prom_offset, tcx_offset;
1238 unsigned long kernel_size;
blueswir17d858922007-12-28 20:57:43 +00001239 int ret;
1240 char buf[1024];
blueswir122548762008-05-10 10:12:00 +00001241 int drive_index;
blueswir13cce6242008-09-18 18:27:29 +00001242 void *fw_cfg;
blueswir17d858922007-12-28 20:57:43 +00001243
1244 /* init CPUs */
1245 if (!cpu_model)
1246 cpu_model = hwdef->default_cpu_model;
1247
1248 for (i = 0; i < smp_cpus; i++) {
1249 env = cpu_init(cpu_model);
1250 if (!env) {
blueswir18e82c6a2008-01-06 07:50:38 +00001251 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
blueswir17d858922007-12-28 20:57:43 +00001252 exit(1);
1253 }
1254 cpu_sparc_set_id(env, i);
1255 envs[i] = env;
1256 if (i == 0) {
1257 qemu_register_reset(main_cpu_reset, env);
1258 } else {
1259 qemu_register_reset(secondary_cpu_reset, env);
1260 env->halted = 1;
1261 }
blueswir17d858922007-12-28 20:57:43 +00001262 cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
1263 env->prom_addr = hwdef->slavio_base;
1264 }
1265
1266 for (i = smp_cpus; i < MAX_CPUS; i++)
1267 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
1268
1269 /* allocate RAM */
1270 if ((uint64_t)RAM_size > hwdef->max_mem) {
blueswir177f193d2008-05-12 16:13:33 +00001271 fprintf(stderr,
1272 "qemu: Too much memory for this machine: %d, maximum %d\n",
blueswir16ef05b92008-05-01 18:21:46 +00001273 (unsigned int)(RAM_size / (1024 * 1024)),
blueswir17d858922007-12-28 20:57:43 +00001274 (unsigned int)(hwdef->max_mem / (1024 * 1024)));
1275 exit(1);
1276 }
blueswir15c6602c2008-11-05 19:25:39 +00001277 ram_offset = qemu_ram_alloc(RAM_size);
1278 cpu_register_physical_memory(0, RAM_size, ram_offset);
blueswir17d858922007-12-28 20:57:43 +00001279
1280 /* load boot prom */
blueswir15c6602c2008-11-05 19:25:39 +00001281 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
blueswir17d858922007-12-28 20:57:43 +00001282 cpu_register_physical_memory(hwdef->slavio_base,
1283 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
1284 TARGET_PAGE_MASK,
1285 prom_offset | IO_MEM_ROM);
1286
1287 if (bios_name == NULL)
1288 bios_name = PROM_FILENAME;
1289 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
1290 ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
1291 if (ret < 0 || ret > PROM_SIZE_MAX)
blueswir1e01f4a12008-05-13 15:44:10 +00001292 ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);
blueswir17d858922007-12-28 20:57:43 +00001293 if (ret < 0 || ret > PROM_SIZE_MAX) {
1294 fprintf(stderr, "qemu: could not load prom '%s'\n",
1295 buf);
1296 exit(1);
1297 }
1298
1299 /* set up devices */
1300 sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs);
1301
1302 for (i = 0; i < MAX_IOUNITS; i++)
1303 if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1)
blueswir1ff403da2008-01-01 17:04:45 +00001304 iounits[i] = iommu_init(hwdef->iounit_bases[i],
1305 hwdef->iounit_version,
1306 sbi_irq[hwdef->me_irq]);
blueswir17d858922007-12-28 20:57:43 +00001307
1308 espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq],
1309 iounits[0], &espdma_irq, &esp_reset);
1310
1311 ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[hwdef->le_irq],
1312 iounits[0], &ledma_irq, &le_reset);
1313
1314 if (graphic_depth != 8 && graphic_depth != 24) {
1315 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
1316 exit (1);
1317 }
blueswir15c6602c2008-11-05 19:25:39 +00001318 tcx_offset = qemu_ram_alloc(hwdef->vram_size);
aliguori3023f332009-01-16 19:04:14 +00001319 tcx_init(hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset,
blueswir17d858922007-12-28 20:57:43 +00001320 hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
1321
aliguori0ae18ce2009-01-13 19:39:36 +00001322 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
blueswir17d858922007-12-28 20:57:43 +00001323
1324 nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0,
1325 hwdef->nvram_size, 8);
1326
1327 slavio_timer_init_all(hwdef->counter_base, sbi_irq[hwdef->clock1_irq],
1328 sbi_cpu_irq, smp_cpus);
1329
1330 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq],
blueswir1b4ed08e2009-01-12 17:38:28 +00001331 nographic, ESCC_CLOCK, 1);
blueswir17d858922007-12-28 20:57:43 +00001332 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
1333 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
aurel32aeeb69c2009-01-14 14:47:56 +00001334 escc_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], sbi_irq[hwdef->ser_irq],
1335 serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
blueswir17d858922007-12-28 20:57:43 +00001336
1337 if (drive_get_max_bus(IF_SCSI) > 0) {
1338 fprintf(stderr, "qemu: too many SCSI bus\n");
1339 exit(1);
1340 }
1341
blueswir15d20fa62008-04-09 16:32:48 +00001342 main_esp = esp_init(hwdef->esp_base, 2,
blueswir18b17de82008-03-02 08:48:47 +00001343 espdma_memory_read, espdma_memory_write,
1344 espdma, *espdma_irq, esp_reset);
blueswir17d858922007-12-28 20:57:43 +00001345
1346 for (i = 0; i < ESP_MAX_DEVS; i++) {
blueswir122548762008-05-10 10:12:00 +00001347 drive_index = drive_get_index(IF_SCSI, 0, i);
1348 if (drive_index == -1)
blueswir17d858922007-12-28 20:57:43 +00001349 continue;
blueswir122548762008-05-10 10:12:00 +00001350 esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);
blueswir17d858922007-12-28 20:57:43 +00001351 }
1352
blueswir1293f78b2008-05-12 17:22:13 +00001353 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
1354 RAM_size);
blueswir17d858922007-12-28 20:57:43 +00001355
1356 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
1357 boot_device, RAM_size, kernel_size, graphic_width,
blueswir1905fdcb2008-09-18 18:33:18 +00001358 graphic_height, graphic_depth, hwdef->nvram_machine_id,
1359 "Sun4d");
blueswir13cce6242008-09-18 18:27:29 +00001360
1361 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
1362 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
blueswir1905fdcb2008-09-18 18:33:18 +00001363 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
1364 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
blueswir17d858922007-12-28 20:57:43 +00001365}
1366
1367/* SPARCserver 1000 hardware initialisation */
aurel3200f82b82008-04-27 21:12:55 +00001368static void ss1000_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001369 const char *boot_device,
blueswir17d858922007-12-28 20:57:43 +00001370 const char *kernel_filename, const char *kernel_cmdline,
1371 const char *initrd_filename, const char *cpu_model)
1372{
aliguori3023f332009-01-16 19:04:14 +00001373 sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
blueswir17d858922007-12-28 20:57:43 +00001374 kernel_cmdline, initrd_filename, cpu_model);
1375}
1376
1377/* SPARCcenter 2000 hardware initialisation */
aurel3200f82b82008-04-27 21:12:55 +00001378static void ss2000_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001379 const char *boot_device,
blueswir17d858922007-12-28 20:57:43 +00001380 const char *kernel_filename, const char *kernel_cmdline,
1381 const char *initrd_filename, const char *cpu_model)
1382{
aliguori3023f332009-01-16 19:04:14 +00001383 sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
blueswir17d858922007-12-28 20:57:43 +00001384 kernel_cmdline, initrd_filename, cpu_model);
1385}
1386
1387QEMUMachine ss1000_machine = {
blueswir166de7332008-08-12 15:51:09 +00001388 .name = "SS-1000",
1389 .desc = "Sun4d platform, SPARCserver 1000",
1390 .init = ss1000_init,
1391 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001392 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001393 .use_scsi = 1,
blueswir11bcee012008-11-02 16:51:02 +00001394 .max_cpus = 8,
blueswir17d858922007-12-28 20:57:43 +00001395};
1396
1397QEMUMachine ss2000_machine = {
blueswir166de7332008-08-12 15:51:09 +00001398 .name = "SS-2000",
1399 .desc = "Sun4d platform, SPARCcenter 2000",
1400 .init = ss2000_init,
1401 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
blueswir1f88e4b92008-08-12 15:58:35 +00001402 .nodisk_ok = 1,
blueswir1c9b1ae22008-09-28 18:55:17 +00001403 .use_scsi = 1,
blueswir11bcee012008-11-02 16:51:02 +00001404 .max_cpus = 20,
blueswir17d858922007-12-28 20:57:43 +00001405};
blueswir18137cde2008-10-27 15:56:56 +00001406
1407static const struct sun4c_hwdef sun4c_hwdefs[] = {
1408 /* SS-2 */
1409 {
1410 .iommu_base = 0xf8000000,
1411 .tcx_base = 0xfe000000,
blueswir18137cde2008-10-27 15:56:56 +00001412 .slavio_base = 0xf6000000,
1413 .intctl_base = 0xf5000000,
1414 .counter_base = 0xf3000000,
1415 .ms_kb_base = 0xf0000000,
1416 .serial_base = 0xf1000000,
1417 .nvram_base = 0xf2000000,
1418 .fd_base = 0xf7200000,
1419 .dma_base = 0xf8400000,
1420 .esp_base = 0xf8800000,
1421 .le_base = 0xf8c00000,
blueswir18137cde2008-10-27 15:56:56 +00001422 .aux1_base = 0xf7400003,
blueswir18137cde2008-10-27 15:56:56 +00001423 .vram_size = 0x00100000,
1424 .nvram_size = 0x800,
1425 .esp_irq = 2,
1426 .le_irq = 3,
1427 .clock_irq = 5,
1428 .clock1_irq = 7,
1429 .ms_kb_irq = 1,
1430 .ser_irq = 1,
1431 .fd_irq = 1,
1432 .me_irq = 1,
blueswir18137cde2008-10-27 15:56:56 +00001433 .nvram_machine_id = 0x55,
1434 .machine_id = ss2_id,
1435 .max_mem = 0x10000000,
1436 .default_cpu_model = "Cypress CY7C601",
1437 },
1438};
1439
1440static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
1441 const char *boot_device,
aliguori3023f332009-01-16 19:04:14 +00001442 const char *kernel_filename,
blueswir18137cde2008-10-27 15:56:56 +00001443 const char *kernel_cmdline,
1444 const char *initrd_filename, const char *cpu_model)
1445{
1446 CPUState *env;
1447 unsigned int i;
1448 void *iommu, *espdma, *ledma, *main_esp, *nvram;
1449 qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq;
1450 qemu_irq *esp_reset, *le_reset;
1451 qemu_irq *fdc_tc;
blueswir15c6602c2008-11-05 19:25:39 +00001452 ram_addr_t ram_offset, prom_offset, tcx_offset;
1453 unsigned long kernel_size;
blueswir18137cde2008-10-27 15:56:56 +00001454 int ret;
1455 char buf[1024];
1456 BlockDriverState *fd[MAX_FD];
1457 int drive_index;
1458 void *fw_cfg;
1459
1460 /* init CPU */
1461 if (!cpu_model)
1462 cpu_model = hwdef->default_cpu_model;
1463
1464 env = cpu_init(cpu_model);
1465 if (!env) {
1466 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
1467 exit(1);
1468 }
1469
1470 cpu_sparc_set_id(env, 0);
1471
1472 qemu_register_reset(main_cpu_reset, env);
1473 cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
1474 env->prom_addr = hwdef->slavio_base;
1475
1476 /* allocate RAM */
1477 if ((uint64_t)RAM_size > hwdef->max_mem) {
1478 fprintf(stderr,
1479 "qemu: Too much memory for this machine: %d, maximum %d\n",
1480 (unsigned int)(RAM_size / (1024 * 1024)),
1481 (unsigned int)(hwdef->max_mem / (1024 * 1024)));
1482 exit(1);
1483 }
blueswir15c6602c2008-11-05 19:25:39 +00001484 ram_offset = qemu_ram_alloc(RAM_size);
1485 cpu_register_physical_memory(0, RAM_size, ram_offset);
blueswir18137cde2008-10-27 15:56:56 +00001486
1487 /* load boot prom */
blueswir15c6602c2008-11-05 19:25:39 +00001488 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
blueswir18137cde2008-10-27 15:56:56 +00001489 cpu_register_physical_memory(hwdef->slavio_base,
1490 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
1491 TARGET_PAGE_MASK,
1492 prom_offset | IO_MEM_ROM);
1493
1494 if (bios_name == NULL)
1495 bios_name = PROM_FILENAME;
1496 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
1497 ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
1498 if (ret < 0 || ret > PROM_SIZE_MAX)
1499 ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);
1500 if (ret < 0 || ret > PROM_SIZE_MAX) {
1501 fprintf(stderr, "qemu: could not load prom '%s'\n",
1502 buf);
1503 exit(1);
1504 }
blueswir18137cde2008-10-27 15:56:56 +00001505
1506 /* set up devices */
1507 slavio_intctl = sun4c_intctl_init(hwdef->intctl_base,
1508 &slavio_irq, cpu_irqs);
1509
1510 iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
1511 slavio_irq[hwdef->me_irq]);
1512
1513 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
1514 iommu, &espdma_irq, &esp_reset);
1515
1516 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
1517 slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
1518 &le_reset);
1519
1520 if (graphic_depth != 8 && graphic_depth != 24) {
1521 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
1522 exit (1);
1523 }
blueswir15c6602c2008-11-05 19:25:39 +00001524 tcx_offset = qemu_ram_alloc(hwdef->vram_size);
aliguori3023f332009-01-16 19:04:14 +00001525 tcx_init(hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset,
blueswir18137cde2008-10-27 15:56:56 +00001526 hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
1527
aliguori0ae18ce2009-01-13 19:39:36 +00001528 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
blueswir18137cde2008-10-27 15:56:56 +00001529
1530 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
1531 hwdef->nvram_size, 2);
1532
1533 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
blueswir1b4ed08e2009-01-12 17:38:28 +00001534 nographic, ESCC_CLOCK, 1);
blueswir18137cde2008-10-27 15:56:56 +00001535 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
1536 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
aurel32aeeb69c2009-01-14 14:47:56 +00001537 escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
1538 slavio_irq[hwdef->ser_irq], serial_hds[0], serial_hds[1],
1539 ESCC_CLOCK, 1);
blueswir18137cde2008-10-27 15:56:56 +00001540
blueswir1fe096122008-12-24 20:21:18 +00001541 slavio_misc = slavio_misc_init(0, 0, hwdef->aux1_base, 0,
blueswir16d0c2932008-11-02 10:51:05 +00001542 slavio_irq[hwdef->me_irq], NULL, &fdc_tc);
blueswir18137cde2008-10-27 15:56:56 +00001543
1544 if (hwdef->fd_base != (target_phys_addr_t)-1) {
1545 /* there is zero or one floppy drive */
blueswir1ce802582008-11-29 16:42:40 +00001546 memset(fd, 0, sizeof(fd));
blueswir18137cde2008-10-27 15:56:56 +00001547 drive_index = drive_get_index(IF_FLOPPY, 0, 0);
1548 if (drive_index != -1)
1549 fd[0] = drives_table[drive_index].bdrv;
1550
1551 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
1552 fdc_tc);
1553 }
1554
1555 if (drive_get_max_bus(IF_SCSI) > 0) {
1556 fprintf(stderr, "qemu: too many SCSI bus\n");
1557 exit(1);
1558 }
1559
1560 main_esp = esp_init(hwdef->esp_base, 2,
1561 espdma_memory_read, espdma_memory_write,
1562 espdma, *espdma_irq, esp_reset);
1563
1564 for (i = 0; i < ESP_MAX_DEVS; i++) {
1565 drive_index = drive_get_index(IF_SCSI, 0, i);
1566 if (drive_index == -1)
1567 continue;
1568 esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);
1569 }
1570
1571 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
1572 RAM_size);
1573
1574 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
1575 boot_device, RAM_size, kernel_size, graphic_width,
1576 graphic_height, graphic_depth, hwdef->nvram_machine_id,
1577 "Sun4c");
1578
1579 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
1580 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
1581 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
1582 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
1583}
1584
1585/* SPARCstation 2 hardware initialisation */
1586static void ss2_init(ram_addr_t RAM_size, int vga_ram_size,
aliguori3023f332009-01-16 19:04:14 +00001587 const char *boot_device,
blueswir18137cde2008-10-27 15:56:56 +00001588 const char *kernel_filename, const char *kernel_cmdline,
1589 const char *initrd_filename, const char *cpu_model)
1590{
aliguori3023f332009-01-16 19:04:14 +00001591 sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
blueswir18137cde2008-10-27 15:56:56 +00001592 kernel_cmdline, initrd_filename, cpu_model);
1593}
1594
1595QEMUMachine ss2_machine = {
1596 .name = "SS-2",
1597 .desc = "Sun4c platform, SPARCstation 2",
1598 .init = ss2_init,
1599 .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1600 .nodisk_ok = 1,
1601 .use_scsi = 1,
blueswir18137cde2008-10-27 15:56:56 +00001602};