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