1
/*
2
* QEMU PPC PREP hardware System Emulator
ths
authored
17 years ago
3
*
4
* Copyright ( c ) 2003 - 2007 Jocelyn Mayer
ths
authored
17 years ago
5
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
* 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 .
23
*/
24
25
26
27
28
29
30
31
32
33
# include "hw.h"
# include "nvram.h"
# include "pc.h"
# include "fdc.h"
# include "net.h"
# include "sysemu.h"
# include "isa.h"
# include "pci.h"
# include "ppc.h"
# include "boards.h"
34
# include "qemu-log.h"
35
36
// # define HARD_DEBUG_PPC_IO
37
// # define DEBUG_PPC_IO
38
39
40
41
/* SMP is not enabled, for now */
# define MAX_CPUS 1
ths
authored
17 years ago
42
43
# define MAX_IDE_BUS 2
44
# define BIOS_SIZE ( 1024 * 1024 )
45
46
47
# define BIOS_FILENAME "ppc_rom.bin"
# define KERNEL_LOAD_ADDR 0x01000000
# define INITRD_LOAD_ADDR 0x01800000
48
49
50
51
52
53
# if defined ( HARD_DEBUG_PPC_IO ) && ! defined ( DEBUG_PPC_IO )
# define DEBUG_PPC_IO
# endif
# if defined ( HARD_DEBUG_PPC_IO )
54
# define PPC_IO_DPRINTF ( fmt , ...) \
55
do { \
56
if ( qemu_loglevel_mask ( CPU_LOG_IOPORT )) { \
57
qemu_log ( "%s: " fmt , __func__ , ## __VA_ARGS__ ); \
58
} else { \
59
printf ( "%s : " fmt , __func__ , ## __VA_ARGS__ ); \
60
61
62
} \
} while ( 0 )
# elif defined ( DEBUG_PPC_IO )
63
# define PPC_IO_DPRINTF ( fmt , ...) qemu_log_mask ( CPU_LOG_IOPORT , ## __VA_ARGS__ )
64
# else
65
# define PPC_IO_DPRINTF ( fmt , ...) do { } while ( 0 )
66
67
# endif
68
/* Constants for devices init */
69
70
71
72
73
74
75
76
static const int ide_iobase [ 2 ] = { 0x1f0 , 0x170 };
static const int ide_iobase2 [ 2 ] = { 0x3f6 , 0x376 };
static const int ide_irq [ 2 ] = { 13 , 13 };
# define NE2000_NB_MAX 6
static uint32_t ne2000_io [ NE2000_NB_MAX ] = { 0x300 , 0x320 , 0x340 , 0x360 , 0x280 , 0x380 };
static int ne2000_irq [ NE2000_NB_MAX ] = { 9 , 10 , 11 , 3 , 4 , 5 };
77
78
79
80
// static PITState * pit ;
/* ISA IO ports bridge */
81
82
# define PPC_IO_BASE 0x80000000
83
# if 0
84
/* Speaker port 0x61 */
85
86
87
static int speaker_data_on ;
static int dummy_refresh_clock ;
# endif
88
89
static void speaker_ioport_write ( void * opaque , uint32_t addr , uint32_t val )
90
{
91
# if 0
92
93
speaker_data_on = ( val >> 1 ) & 1 ;
pit_set_gate ( pit , 2 , val & 1 );
94
# endif
95
96
}
97
static uint32_t speaker_ioport_read ( void * opaque , uint32_t addr )
98
{
99
# if 0
100
101
102
103
int out ;
out = pit_get_out ( pit , 2 , qemu_get_clock ( vm_clock ));
dummy_refresh_clock ^= 1 ;
return ( speaker_data_on << 1 ) | pit_get_gate ( pit , 2 ) | ( out << 5 ) |
104
( dummy_refresh_clock << 4 );
105
# endif
106
return 0 ;
107
108
}
109
110
/* PCI intack register */
/* Read-only register (?) */
111
112
static void _PPC_intack_write ( void * opaque ,
target_phys_addr_t addr , uint32_t value )
113
{
114
// printf ( "%s: 0x" PADDRX " => 0x%08" PRIx32 " \n " , __func__ , addr , value );
115
116
}
117
static always_inline uint32_t _PPC_intack_read ( target_phys_addr_t addr )
118
119
120
{
uint32_t retval = 0 ;
121
if (( addr & 0xf ) == 0 )
122
retval = pic_intack_read ( isa_pic );
123
// printf ( "%s: 0x" PADDRX " <= %08" PRIx32 " \n " , __func__ , addr , retval );
124
125
126
127
return retval ;
}
128
static uint32_t PPC_intack_readb ( void * opaque , target_phys_addr_t addr )
129
130
131
132
{
return _PPC_intack_read ( addr );
}
133
static uint32_t PPC_intack_readw ( void * opaque , target_phys_addr_t addr )
134
{
135
# ifdef TARGET_WORDS_BIGENDIAN
136
137
138
return bswap16 ( _PPC_intack_read ( addr ));
# else
return _PPC_intack_read ( addr );
139
# endif
140
141
}
142
static uint32_t PPC_intack_readl ( void * opaque , target_phys_addr_t addr )
143
{
144
# ifdef TARGET_WORDS_BIGENDIAN
145
146
147
return bswap32 ( _PPC_intack_read ( addr ));
# else
return _PPC_intack_read ( addr );
148
# endif
149
150
}
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
static CPUWriteMemoryFunc * PPC_intack_write [] = {
& _PPC_intack_write ,
& _PPC_intack_write ,
& _PPC_intack_write ,
};
static CPUReadMemoryFunc * PPC_intack_read [] = {
& PPC_intack_readb ,
& PPC_intack_readw ,
& PPC_intack_readl ,
};
/* PowerPC control and status registers */
# if 0 // Not used
static struct {
/* IDs */
uint32_t veni_devi ;
uint32_t revi ;
/* Control and status */
uint32_t gcsr ;
uint32_t xcfr ;
uint32_t ct32 ;
uint32_t mcsr ;
/* General purpose registers */
uint32_t gprg [ 6 ];
/* Exceptions */
uint32_t feen ;
uint32_t fest ;
uint32_t fema ;
uint32_t fecl ;
uint32_t eeen ;
uint32_t eest ;
uint32_t eecl ;
uint32_t eeint ;
uint32_t eemck0 ;
uint32_t eemck1 ;
/* Error diagnostic */
} XCSR ;
190
191
static void PPC_XCSR_writeb ( void * opaque ,
target_phys_addr_t addr , uint32_t value )
192
{
193
printf ( "%s: 0x" PADDRX " => 0x%08" PRIx32 " \n " , __func__ , addr , value );
194
195
}
196
197
static void PPC_XCSR_writew ( void * opaque ,
target_phys_addr_t addr , uint32_t value )
198
{
199
# ifdef TARGET_WORDS_BIGENDIAN
200
value = bswap16 ( value );
201
# endif
202
printf ( "%s: 0x" PADDRX " => 0x%08" PRIx32 " \n " , __func__ , addr , value );
203
204
}
205
206
static void PPC_XCSR_writel ( void * opaque ,
target_phys_addr_t addr , uint32_t value )
207
{
208
# ifdef TARGET_WORDS_BIGENDIAN
209
value = bswap32 ( value );
210
# endif
211
printf ( "%s: 0x" PADDRX " => 0x%08" PRIx32 " \n " , __func__ , addr , value );
212
213
}
214
static uint32_t PPC_XCSR_readb ( void * opaque , target_phys_addr_t addr )
215
216
{
uint32_t retval = 0 ;
217
218
printf ( "%s: 0x" PADDRX " <= %08" PRIx32 " \n " , __func__ , addr , retval );
219
220
221
222
return retval ;
}
223
static uint32_t PPC_XCSR_readw ( void * opaque , target_phys_addr_t addr )
224
{
225
226
uint32_t retval = 0 ;
227
printf ( "%s: 0x" PADDRX " <= %08" PRIx32 " \n " , __func__ , addr , retval );
228
229
230
231
232
# ifdef TARGET_WORDS_BIGENDIAN
retval = bswap16 ( retval );
# endif
return retval ;
233
234
}
235
static uint32_t PPC_XCSR_readl ( void * opaque , target_phys_addr_t addr )
236
237
238
{
uint32_t retval = 0 ;
239
printf ( "%s: 0x" PADDRX " <= %08" PRIx32 " \n " , __func__ , addr , retval );
240
241
242
# ifdef TARGET_WORDS_BIGENDIAN
retval = bswap32 ( retval );
# endif
243
244
245
246
return retval ;
}
247
248
249
250
static CPUWriteMemoryFunc * PPC_XCSR_write [] = {
& PPC_XCSR_writeb ,
& PPC_XCSR_writew ,
& PPC_XCSR_writel ,
251
252
};
253
254
255
256
static CPUReadMemoryFunc * PPC_XCSR_read [] = {
& PPC_XCSR_readb ,
& PPC_XCSR_readw ,
& PPC_XCSR_readl ,
257
};
258
# endif
259
260
261
/* Fake super-io ports for PREP platform (Intel 82378ZB) */
typedef struct sysctrl_t {
262
qemu_irq reset_irq ;
263
264
265
266
m48t59_t * nvram ;
uint8_t state ;
uint8_t syscontrol ;
uint8_t fake_io [ 2 ];
267
int contiguous_map ;
268
int endian ;
269
} sysctrl_t ;
270
271
272
enum {
STATE_HARDFILE = 0x01 ,
273
274
};
275
static sysctrl_t * sysctrl ;
276
277
static void PREP_io_write ( void * opaque , uint32_t addr , uint32_t val )
278
{
279
280
sysctrl_t * sysctrl = opaque ;
281
282
PPC_IO_DPRINTF ( "0x%08" PRIx32 " => 0x%02" PRIx32 " \n " , addr - PPC_IO_BASE ,
val );
283
sysctrl -> fake_io [ addr - 0x0398 ] = val ;
284
285
}
286
static uint32_t PREP_io_read ( void * opaque , uint32_t addr )
287
{
288
sysctrl_t * sysctrl = opaque ;
289
290
PPC_IO_DPRINTF ( "0x%08" PRIx32 " <= 0x%02" PRIx32 " \n " , addr - PPC_IO_BASE ,
291
292
293
sysctrl -> fake_io [ addr - 0x0398 ]);
return sysctrl -> fake_io [ addr - 0x0398 ];
}
294
295
static void PREP_io_800_writeb ( void * opaque , uint32_t addr , uint32_t val )
296
{
297
298
sysctrl_t * sysctrl = opaque ;
299
300
PPC_IO_DPRINTF ( "0x%08" PRIx32 " => 0x%02" PRIx32 " \n " ,
addr - PPC_IO_BASE , val );
301
302
303
304
switch ( addr ) {
case 0x0092 :
/* Special port 92 */
/* Check soft reset asked */
305
if ( val & 0x01 ) {
306
307
308
qemu_irq_raise ( sysctrl -> reset_irq );
} else {
qemu_irq_lower ( sysctrl -> reset_irq );
309
310
}
/* Check LE mode */
311
if ( val & 0x02 ) {
312
313
314
sysctrl -> endian = 1 ;
} else {
sysctrl -> endian = 0 ;
315
316
}
break ;
317
318
319
320
321
322
323
324
325
case 0x0800 :
/* Motorola CPU configuration register : read-only */
break ;
case 0x0802 :
/* Motorola base module feature register : read-only */
break ;
case 0x0803 :
/* Motorola base module status register : read-only */
break ;
326
case 0x0808 :
327
328
329
330
331
/* Hardfile light register */
if ( val & 1 )
sysctrl -> state |= STATE_HARDFILE ;
else
sysctrl -> state &= ~ STATE_HARDFILE ;
332
333
334
break ;
case 0x0810 :
/* Password protect 1 register */
335
336
if ( sysctrl -> nvram != NULL )
m48t59_toggle_lock ( sysctrl -> nvram , 1 );
337
338
339
break ;
case 0x0812 :
/* Password protect 2 register */
340
341
if ( sysctrl -> nvram != NULL )
m48t59_toggle_lock ( sysctrl -> nvram , 2 );
342
343
break ;
case 0x0814 :
344
/* L2 invalidate register */
345
// tlb_flush ( first_cpu , 1 );
346
347
348
break ;
case 0x081C :
/* system control register */
349
sysctrl -> syscontrol = val & 0x0F ;
350
351
352
break ;
case 0x0850 :
/* I/O map type register */
353
sysctrl -> contiguous_map = val & 0x01 ;
354
355
break ;
default :
356
357
printf ( "ERROR: unaffected IO port write: %04" PRIx32
" => %02" PRIx32 " \n " , addr , val );
358
359
360
361
break ;
}
}
362
static uint32_t PREP_io_800_readb ( void * opaque , uint32_t addr )
363
{
364
sysctrl_t * sysctrl = opaque ;
365
366
367
368
369
uint32_t retval = 0xFF ;
switch ( addr ) {
case 0x0092 :
/* Special port 92 */
370
371
372
373
374
375
376
377
378
379
380
381
382
retval = 0x00 ;
break ;
case 0x0800 :
/* Motorola CPU configuration register */
retval = 0xEF ; /* MPC750 */
break ;
case 0x0802 :
/* Motorola Base module feature register */
retval = 0xAD ; /* No ESCC, PMC slot neither ethernet */
break ;
case 0x0803 :
/* Motorola base module status register */
retval = 0xE0 ; /* Standard MPC750 */
383
384
385
386
387
388
389
390
break ;
case 0x080C :
/* Equipment present register :
* no L2 cache
* no upgrade processor
* no cards in PCI slots
* SCSI fuse is bad
*/
391
392
393
394
395
retval = 0x3C ;
break ;
case 0x0810 :
/* Motorola base module extended feature register */
retval = 0x39 ; /* No USB, CF and PCI bridge. NVRAM present */
396
break ;
397
398
399
case 0x0814 :
/* L2 invalidate: don't care */
break ;
400
401
402
403
404
405
406
407
case 0x0818 :
/* Keylock */
retval = 0x00 ;
break ;
case 0x081C :
/* system control register
* 7 - 6 / 1 - 0 : L2 cache enable
*/
408
retval = sysctrl -> syscontrol ;
409
410
411
412
413
414
415
break ;
case 0x0823 :
/* */
retval = 0x03 ; /* no L2 cache */
break ;
case 0x0850 :
/* I/O map type register */
416
retval = sysctrl -> contiguous_map ;
417
418
break ;
default :
419
printf ( "ERROR: unaffected IO port: %04" PRIx32 " read \n " , addr );
420
421
break ;
}
422
423
PPC_IO_DPRINTF ( "0x%08" PRIx32 " <= 0x%02" PRIx32 " \n " ,
addr - PPC_IO_BASE , retval );
424
425
426
427
return retval ;
}
428
429
430
static always_inline target_phys_addr_t prep_IO_address ( sysctrl_t * sysctrl ,
target_phys_addr_t
addr )
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
{
if ( sysctrl -> contiguous_map == 0 ) {
/* 64 KB contiguous space for IOs */
addr &= 0xFFFF ;
} else {
/* 8 MB non-contiguous space for IOs */
addr = ( addr & 0x1F ) | (( addr & 0x007FFF000 ) >> 7 );
}
return addr ;
}
static void PPC_prep_io_writeb ( void * opaque , target_phys_addr_t addr ,
uint32_t value )
{
sysctrl_t * sysctrl = opaque ;
addr = prep_IO_address ( sysctrl , addr );
cpu_outb ( NULL , addr , value );
}
static uint32_t PPC_prep_io_readb ( void * opaque , target_phys_addr_t addr )
{
sysctrl_t * sysctrl = opaque ;
uint32_t ret ;
addr = prep_IO_address ( sysctrl , addr );
ret = cpu_inb ( NULL , addr );
return ret ;
}
static void PPC_prep_io_writew ( void * opaque , target_phys_addr_t addr ,
uint32_t value )
{
sysctrl_t * sysctrl = opaque ;
addr = prep_IO_address ( sysctrl , addr );
# ifdef TARGET_WORDS_BIGENDIAN
value = bswap16 ( value );
# endif
472
PPC_IO_DPRINTF ( "0x" PADDRX " => 0x%08" PRIx32 " \n " , addr , value );
473
474
475
476
477
478
479
480
481
482
483
484
485
cpu_outw ( NULL , addr , value );
}
static uint32_t PPC_prep_io_readw ( void * opaque , target_phys_addr_t addr )
{
sysctrl_t * sysctrl = opaque ;
uint32_t ret ;
addr = prep_IO_address ( sysctrl , addr );
ret = cpu_inw ( NULL , addr );
# ifdef TARGET_WORDS_BIGENDIAN
ret = bswap16 ( ret );
# endif
486
PPC_IO_DPRINTF ( "0x" PADDRX " <= 0x%08" PRIx32 " \n " , addr , ret );
487
488
489
490
491
492
493
494
495
496
497
498
499
return ret ;
}
static void PPC_prep_io_writel ( void * opaque , target_phys_addr_t addr ,
uint32_t value )
{
sysctrl_t * sysctrl = opaque ;
addr = prep_IO_address ( sysctrl , addr );
# ifdef TARGET_WORDS_BIGENDIAN
value = bswap32 ( value );
# endif
500
PPC_IO_DPRINTF ( "0x" PADDRX " => 0x%08" PRIx32 " \n " , addr , value );
501
502
503
504
505
506
507
508
509
510
511
512
513
cpu_outl ( NULL , addr , value );
}
static uint32_t PPC_prep_io_readl ( void * opaque , target_phys_addr_t addr )
{
sysctrl_t * sysctrl = opaque ;
uint32_t ret ;
addr = prep_IO_address ( sysctrl , addr );
ret = cpu_inl ( NULL , addr );
# ifdef TARGET_WORDS_BIGENDIAN
ret = bswap32 ( ret );
# endif
514
PPC_IO_DPRINTF ( "0x" PADDRX " <= 0x%08" PRIx32 " \n " , addr , ret );
515
516
517
518
return ret ;
}
519
static CPUWriteMemoryFunc * PPC_prep_io_write [] = {
520
521
522
523
524
& PPC_prep_io_writeb ,
& PPC_prep_io_writew ,
& PPC_prep_io_writel ,
};
525
static CPUReadMemoryFunc * PPC_prep_io_read [] = {
526
527
528
529
530
& PPC_prep_io_readb ,
& PPC_prep_io_readw ,
& PPC_prep_io_readl ,
};
531
# define NVRAM_SIZE 0x2000
532
533
/* PowerPC PREP hardware initialisation */
534
static void ppc_prep_init ( ram_addr_t ram_size ,
535
const char * boot_device ,
536
const char * kernel_filename ,
537
538
539
const char * kernel_cmdline ,
const char * initrd_filename ,
const char * cpu_model )
540
{
541
CPUState * env = NULL , * envs [ MAX_CPUS ];
542
char * filename ;
543
544
nvram_t nvram ;
m48t59_t * m48t59 ;
545
int PPC_io_memory ;
546
int linux_boot , i , nb_nics1 , bios_size ;
547
ram_addr_t ram_offset , bios_offset ;
548
uint32_t kernel_base , kernel_size , initrd_base , initrd_size ;
549
PCIBus * pci_bus ;
550
qemu_irq * i8259 ;
551
int ppc_boot_device ;
ths
authored
17 years ago
552
553
554
int index ;
BlockDriverState * hd [ MAX_IDE_BUS * MAX_IDE_DEVS ];
BlockDriverState * fd [ MAX_FD ];
555
556
sysctrl = qemu_mallocz ( sizeof ( sysctrl_t ));
557
558
linux_boot = ( kernel_filename != NULL );
559
560
/* init CPUs */
561
if ( cpu_model == NULL )
562
cpu_model = "default" ;
563
for ( i = 0 ; i < smp_cpus ; i ++ ) {
564
565
566
567
568
env = cpu_init ( cpu_model );
if ( ! env ) {
fprintf ( stderr , "Unable to find PowerPC CPU definition \n " );
exit ( 1 );
}
569
570
571
572
573
574
575
if ( env -> flags & POWERPC_FLAG_RTC_CLK ) {
/* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
cpu_ppc_tb_init ( env , 7812500UL );
} else {
/* Set time-base frequency to 100 Mhz */
cpu_ppc_tb_init ( env , 100UL * 1000UL * 1000UL );
}
576
qemu_register_reset ( & cpu_ppc_reset , env );
577
578
envs [ i ] = env ;
}
579
580
/* allocate RAM */
581
582
583
ram_offset = qemu_ram_alloc ( ram_size );
cpu_register_physical_memory ( 0 , ram_size , ram_offset );
584
/* allocate and load BIOS */
585
bios_offset = qemu_ram_alloc ( BIOS_SIZE );
586
587
if ( bios_name == NULL )
bios_name = BIOS_FILENAME ;
588
589
590
591
592
593
filename = qemu_find_file ( QEMU_FILE_TYPE_BIOS , bios_name );
if ( filename ) {
bios_size = get_image_size ( filename );
} else {
bios_size = - 1 ;
}
594
595
596
597
598
599
if ( bios_size > 0 && bios_size <= BIOS_SIZE ) {
target_phys_addr_t bios_addr ;
bios_size = ( bios_size + 0xfff ) & ~ 0xfff ;
bios_addr = ( uint32_t )( - bios_size );
cpu_register_physical_memory ( bios_addr , bios_size ,
bios_offset | IO_MEM_ROM );
600
bios_size = load_image_targphys ( filename , bios_addr , bios_size );
601
}
602
if ( bios_size < 0 || bios_size > BIOS_SIZE ) {
603
604
605
606
hw_error ( "qemu: could not load PPC PREP bios '%s' \n " , bios_name );
}
if ( filename ) {
qemu_free ( filename );
607
}
608
if ( env -> nip < 0xFFF80000 && bios_size < 0x00100000 ) {
609
hw_error ( "PowerPC 601 / 620 / 970 need a 1MB BIOS \n " );
610
}
611
612
if ( linux_boot ) {
613
kernel_base = KERNEL_LOAD_ADDR ;
614
/* now we can load the kernel */
615
616
kernel_size = load_image_targphys ( kernel_filename , kernel_base ,
ram_size - kernel_base );
617
if ( kernel_size < 0 ) {
618
hw_error ( "qemu: could not load kernel '%s' \n " , kernel_filename );
619
620
621
622
exit ( 1 );
}
/* load initrd */
if ( initrd_filename ) {
623
initrd_base = INITRD_LOAD_ADDR ;
624
625
initrd_size = load_image_targphys ( initrd_filename , initrd_base ,
ram_size - initrd_base );
626
if ( initrd_size < 0 ) {
627
hw_error ( "qemu: could not load initial ram disk '%s' \n " ,
628
initrd_filename );
629
}
630
631
632
} else {
initrd_base = 0 ;
initrd_size = 0 ;
633
}
634
ppc_boot_device = 'm' ;
635
} else {
636
637
638
639
kernel_base = 0 ;
kernel_size = 0 ;
initrd_base = 0 ;
initrd_size = 0 ;
640
641
ppc_boot_device = '\0' ;
/* For now, OHW cannot boot from the network. */
642
643
644
for ( i = 0 ; boot_device [ i ] != '\0' ; i ++ ) {
if ( boot_device [ i ] >= 'a' && boot_device [ i ] <= 'f' ) {
ppc_boot_device = boot_device [ i ];
645
break ;
646
}
647
648
649
650
651
}
if ( ppc_boot_device == '\0' ) {
fprintf ( stderr , "No valid boot device for Mac99 machine \n " );
exit ( 1 );
}
652
653
}
654
isa_mem_base = 0xc0000000 ;
655
if ( PPC_INPUT ( env ) != PPC_FLAGS_INPUT_6xx ) {
656
hw_error ( "Only 6xx bus is supported on PREP machine \n " );
657
}
658
i8259 = i8259_init ( first_cpu -> irq_inputs [ PPC6xx_INPUT_INT ]);
659
pci_bus = pci_prep_init ( i8259 );
660
661
// pci_bus = i440fx_init ();
/* Register 8 MB of ISA IO space (needed for non-contiguous map) */
662
PPC_io_memory = cpu_register_io_memory ( PPC_prep_io_read ,
663
664
PPC_prep_io_write , sysctrl );
cpu_register_physical_memory ( 0x80000000 , 0x00800000 , PPC_io_memory );
665
666
/* init basic PC hardware */
667
pci_vga_init ( pci_bus , 0 , 0 );
668
// openpic = openpic_init ( 0x00000000 , 0xF0000000 , 1 );
669
// pit = pit_init ( 0x40 , i8259 [ 0 ]);
670
rtc_init ( 0x70 , i8259 [ 8 ], 2000 );
671
672
serial_init ( 0x3f8 , i8259 [ 4 ], 115200 , serial_hds [ 0 ]);
673
674
675
676
nb_nics1 = nb_nics ;
if ( nb_nics1 > NE2000_NB_MAX )
nb_nics1 = NE2000_NB_MAX ;
for ( i = 0 ; i < nb_nics1 ; i ++ ) {
677
678
679
680
if ( nd_table [ i ]. model == NULL ) {
nd_table [ i ]. model = "ne2k_isa" ;
}
if ( strcmp ( nd_table [ i ]. model , "ne2k_isa" ) == 0 ) {
681
isa_ne2000_init ( ne2000_io [ i ], i8259 [ ne2000_irq [ i ]], & nd_table [ i ]);
682
} else {
683
pci_nic_init ( & nd_table [ i ], "ne2k_pci" , NULL );
684
}
685
686
}
ths
authored
17 years ago
687
688
689
690
691
692
693
694
695
696
697
698
699
700
if ( drive_get_max_bus ( IF_IDE ) >= MAX_IDE_BUS ) {
fprintf ( stderr , "qemu: too many IDE bus \n " );
exit ( 1 );
}
for ( i = 0 ; i < MAX_IDE_BUS * MAX_IDE_DEVS ; i ++ ) {
index = drive_get_index ( IF_IDE , i / MAX_IDE_DEVS , i % MAX_IDE_DEVS );
if ( index != - 1 )
hd [ i ] = drives_table [ index ]. bdrv ;
else
hd [ i ] = NULL ;
}
for ( i = 0 ; i < MAX_IDE_BUS ; i ++ ) {
701
isa_ide_init ( ide_iobase [ i ], ide_iobase2 [ i ], i8259 [ ide_irq [ i ]],
ths
authored
17 years ago
702
703
hd [ 2 * i ],
hd [ 2 * i + 1 ]);
704
}
705
i8042_init ( i8259 [ 1 ], i8259 [ 12 ], 0x60 );
706
DMA_init ( 1 );
707
708
// SB16_init ();
ths
authored
17 years ago
709
710
711
712
713
714
715
716
for ( i = 0 ; i < MAX_FD ; i ++ ) {
index = drive_get_index ( IF_FLOPPY , 0 , i );
if ( index != - 1 )
fd [ i ] = drives_table [ index ]. bdrv ;
else
fd [ i ] = NULL ;
}
fdctrl_init ( i8259 [ 6 ], 2 , 0 , 0x3f0 , fd );
717
718
719
720
/* Register speaker port */
register_ioport_read ( 0x61 , 1 , 1 , speaker_ioport_read , NULL );
register_ioport_write ( 0x61 , 1 , 1 , speaker_ioport_write , NULL );
721
/* Register fake IO ports for PREP */
722
sysctrl -> reset_irq = first_cpu -> irq_inputs [ PPC6xx_INPUT_HRESET ];
723
724
register_ioport_read ( 0x398 , 2 , 1 , & PREP_io_read , sysctrl );
register_ioport_write ( 0x398 , 2 , 1 , & PREP_io_write , sysctrl );
725
/* System control ports */
726
727
728
729
730
register_ioport_read ( 0x0092 , 0x01 , 1 , & PREP_io_800_readb , sysctrl );
register_ioport_write ( 0x0092 , 0x01 , 1 , & PREP_io_800_writeb , sysctrl );
register_ioport_read ( 0x0800 , 0x52 , 1 , & PREP_io_800_readb , sysctrl );
register_ioport_write ( 0x0800 , 0x52 , 1 , & PREP_io_800_writeb , sysctrl );
/* PCI intack location */
731
PPC_io_memory = cpu_register_io_memory ( PPC_intack_read ,
732
PPC_intack_write , NULL );
733
cpu_register_physical_memory ( 0xBFFFFFF0 , 0x4 , PPC_io_memory );
734
/* PowerPC control and status register group */
735
# if 0
736
PPC_io_memory = cpu_register_io_memory ( PPC_XCSR_read , PPC_XCSR_write ,
737
NULL );
738
cpu_register_physical_memory ( 0xFEFF0000 , 0x1000 , PPC_io_memory );
739
# endif
740
741
if ( usb_enabled ) {
742
usb_ohci_init_pci ( pci_bus , 3 , - 1 );
743
744
}
745
746
m48t59 = m48t59_init ( i8259 [ 8 ], 0 , 0x0074 , NVRAM_SIZE , 59 );
if ( m48t59 == NULL )
747
return ;
748
sysctrl -> nvram = m48t59 ;
749
750
/* Initialise NVRAM */
751
752
753
nvram . opaque = m48t59 ;
nvram . read_fn = & m48t59_read ;
nvram . write_fn = & m48t59_write ;
754
PPC_NVRAM_set_params ( & nvram , NVRAM_SIZE , "PREP" , ram_size , ppc_boot_device ,
755
kernel_base , kernel_size ,
756
kernel_cmdline ,
757
758
initrd_base , initrd_size ,
/* XXX: need an option to load a NVRAM image */
759
760
0 ,
graphic_width , graphic_height , graphic_depth );
761
762
763
/* Special port to get debug messages from Open-Firmware */
register_ioport_write ( 0x0F00 , 4 , 1 , & PPC_debug_write , NULL );
764
}
765
766
static QEMUMachine prep_machine = {
767
768
769
. name = "prep" ,
. desc = "PowerPC PREP platform" ,
. init = ppc_prep_init ,
770
. max_cpus = MAX_CPUS ,
771
};
772
773
774
775
776
777
778
static void prep_machine_init ( void )
{
qemu_register_machine ( & prep_machine );
}
machine_init ( prep_machine_init );