Merge pull request #27 from kernigh/pr-qemu-doze
Teach qemuppc to halt the cpu on _exit().
This commit is contained in:
commit
bf2e0be69a
|
@ -88,4 +88,4 @@
|
||||||
|
|
||||||
%type <y_word> c
|
%type <y_word> c
|
||||||
%type <y_word> e16 u8 u7 u6 u5 u4 u2 u1
|
%type <y_word> e16 u8 u7 u6 u5 u4 u2 u1
|
||||||
%type <y_word> nb ds bda bdl lia lil
|
%type <y_word> nb ds bda bdl lia lil spr_num
|
||||||
|
|
|
@ -34,7 +34,7 @@ operation
|
||||||
| OP_RT_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
|
| OP_RT_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
|
||||||
| OP_RT_RA_SI GPR ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
| OP_RT_RA_SI GPR ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
||||||
| OP_RT_RA_SI_addic c GPR ',' GPR ',' e16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
|
| OP_RT_RA_SI_addic c GPR ',' GPR ',' e16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
|
||||||
| OP_RT_SPR GPR ',' SPR { emit4($1 | ($2<<21) | ($4<<11)); }
|
| OP_RT_SPR GPR ',' spr_num { emit4($1 | ($2<<21) | ($4<<11)); }
|
||||||
| OP_RS_FXM u7 ',' GPR { emit4($1 | ($4<<21) | ($2<<12)); }
|
| OP_RS_FXM u7 ',' GPR { emit4($1 | ($4<<21) | ($2<<12)); }
|
||||||
| OP_RS_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
|
| OP_RS_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
|
||||||
| OP_RS_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
| OP_RS_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||||
|
@ -53,7 +53,7 @@ operation
|
||||||
| OP_RS_RA_SH_ME6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
|
| OP_RS_RA_SH_ME6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
|
||||||
| OP_RS_RA_SH5_C c GPR ',' GPR ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
| OP_RS_RA_SH5_C c GPR ',' GPR ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
||||||
| OP_RS_RA_SH6_C c GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | (($7&0x20)>>4)); }
|
| OP_RS_RA_SH6_C c GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | (($7&0x20)>>4)); }
|
||||||
| OP_RS_SPR SPR ',' GPR { emit4($1 | ($4<<21) | ($2<<11)); }
|
| OP_RS_SPR spr_num ',' GPR { emit4($1 | ($4<<21) | ($2<<11)); }
|
||||||
| OP_TO_RA_RB u5 ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
| OP_TO_RA_RB u5 ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||||
| OP_TO_RA_SI u5 ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
| OP_TO_RA_SI u5 ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
||||||
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
||||||
|
@ -238,3 +238,13 @@ lia
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
spr_num
|
||||||
|
: SPR { $$ = $1; }
|
||||||
|
| absexp
|
||||||
|
{
|
||||||
|
if (($1 < 0) || ($1 > 0x3ff))
|
||||||
|
serror("spr number out of range");
|
||||||
|
/* mfspr, mtspr swap the low and high 5 bits */
|
||||||
|
$$ = ($1 >> 5) | (($1 & 0x1f) << 5);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
|
@ -13,22 +13,14 @@
|
||||||
.sect .text
|
.sect .text
|
||||||
|
|
||||||
begtext:
|
begtext:
|
||||||
! This code is placed at the beginning of the ELF executable and is the
|
! This code is the first thing that runs. The booloader
|
||||||
! first thing that runs.
|
! passes the Open Firmware pointer in r5.
|
||||||
!
|
!
|
||||||
! On entry, the stack looks like this:
|
! We keep the bootloader's stack. The ACK expects:
|
||||||
!
|
!
|
||||||
! sp+... NULL
|
! sp+8 environment pointer
|
||||||
! sp+8+(4*argc) env (X quads)
|
! sp+4 argv as a pointer
|
||||||
! sp+4+(4*argc) NULL
|
|
||||||
! sp+4 argv (argc quads)
|
|
||||||
! sp argc
|
! sp argc
|
||||||
!
|
|
||||||
! The ACK actually expects:
|
|
||||||
!
|
|
||||||
! sp+8 argc
|
|
||||||
! sp+4 ptr to argv
|
|
||||||
! sp ptr to env
|
|
||||||
|
|
||||||
li32 r3, __openfirmware_ptr
|
li32 r3, __openfirmware_ptr
|
||||||
stw r5, 0(r3)
|
stw r5, 0(r3)
|
||||||
|
@ -47,15 +39,23 @@ begtext:
|
||||||
! falls through
|
! falls through
|
||||||
|
|
||||||
.define __exit
|
.define __exit
|
||||||
.extern __exit
|
|
||||||
.define EXIT
|
.define EXIT
|
||||||
.extern EXIT
|
|
||||||
__exit:
|
__exit:
|
||||||
EXIT:
|
EXIT:
|
||||||
b EXIT
|
! Halt the CPU. This code halts the default G3 emulation of
|
||||||
|
! qemu-system-ppc. It's wrong for some other CPU models.
|
||||||
|
#define hid0 0x3f0
|
||||||
|
#define mfmsr(r) [[31<<26]|[[r]<<21]|0x0a6]
|
||||||
|
#define mtmsr(r) [[31<<26]|[[r]<<21]|0x124]
|
||||||
|
mfspr r3, hid0
|
||||||
|
oris r3, r3, 0x00e0 ! set DOZE, NAP, SLEEP
|
||||||
|
mtspr hid0, r3 ! in hid0
|
||||||
|
.data4 mfmsr(3)
|
||||||
|
oris r3, r3, 0x0004 ! set POW
|
||||||
|
.data4 mtmsr(3) ! in msr
|
||||||
|
b EXIT ! If we failed to halt, then spin.
|
||||||
|
|
||||||
.define _openfirmware_call
|
.define _openfirmware_call
|
||||||
.extern _openfirmware_call
|
|
||||||
_openfirmware_call:
|
_openfirmware_call:
|
||||||
lwz r3, 0(sp)
|
lwz r3, 0(sp)
|
||||||
li32 r4, __openfirmware_ptr
|
li32 r4, __openfirmware_ptr
|
||||||
|
@ -66,15 +66,10 @@ _openfirmware_call:
|
||||||
! Define symbols at the beginning of our various segments, so that we can find
|
! Define symbols at the beginning of our various segments, so that we can find
|
||||||
! them. (Except .text, which has already been done.)
|
! them. (Except .text, which has already been done.)
|
||||||
|
|
||||||
.sect .data; begdata:
|
|
||||||
.sect .rom; begrom:
|
.sect .rom; begrom:
|
||||||
|
.sect .data; begdata:
|
||||||
.sect .bss; begbss:
|
.sect .bss; begbss:
|
||||||
|
|
||||||
! Some magic data. All EM systems need these.
|
|
||||||
|
|
||||||
.define _errno
|
|
||||||
.comm _errno, 4 ! Posix errno storage
|
|
||||||
|
|
||||||
! The argv and env arrays.
|
! The argv and env arrays.
|
||||||
|
|
||||||
.sect .rom
|
.sect .rom
|
||||||
|
@ -82,6 +77,12 @@ argv: .data4 exename, 0
|
||||||
envp: .data4 0
|
envp: .data4 0
|
||||||
exename: .asciz 'qemuppc.img'
|
exename: .asciz 'qemuppc.img'
|
||||||
|
|
||||||
|
! Some magic data. All EM systems need these.
|
||||||
|
|
||||||
|
.sect .bss
|
||||||
|
.define _errno
|
||||||
|
.comm _errno, 4 ! Posix errno storage
|
||||||
|
|
||||||
.define .trppc, .ignmask
|
.define .trppc, .ignmask
|
||||||
.comm .trppc, 4 ! ptr to user trap handler
|
.comm .trppc, 4 ! ptr to user trap handler
|
||||||
.comm .ignmask, 4 ! user trap ignore mask
|
.comm .ignmask, 4 ! user trap ignore mask
|
||||||
|
|
Loading…
Reference in a new issue