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