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> 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_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_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_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); }
|
||||
|
@ -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_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_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_SI u5 ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
||||
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
||||
|
@ -237,4 +237,14 @@ lia
|
|||
$$ = target & 0x03FFFFFD;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
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
|
||||
|
||||
begtext:
|
||||
! This code is placed at the beginning of the ELF executable and is the
|
||||
! first thing that runs.
|
||||
! This code is the first thing that runs. The booloader
|
||||
! 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+(4*argc) env (X quads)
|
||||
! sp+4+(4*argc) NULL
|
||||
! sp+4 argv (argc quads)
|
||||
! sp+8 environment pointer
|
||||
! sp+4 argv as a pointer
|
||||
! sp argc
|
||||
!
|
||||
! The ACK actually expects:
|
||||
!
|
||||
! sp+8 argc
|
||||
! sp+4 ptr to argv
|
||||
! sp ptr to env
|
||||
|
||||
li32 r3, __openfirmware_ptr
|
||||
stw r5, 0(r3)
|
||||
|
@ -47,15 +39,23 @@ begtext:
|
|||
! falls through
|
||||
|
||||
.define __exit
|
||||
.extern __exit
|
||||
.define EXIT
|
||||
.extern 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
|
||||
.extern _openfirmware_call
|
||||
_openfirmware_call:
|
||||
lwz r3, 0(sp)
|
||||
li32 r4, __openfirmware_ptr
|
||||
|
@ -66,15 +66,10 @@ _openfirmware_call:
|
|||
! Define symbols at the beginning of our various segments, so that we can find
|
||||
! them. (Except .text, which has already been done.)
|
||||
|
||||
.sect .data; begdata:
|
||||
.sect .rom; begrom:
|
||||
.sect .data; begdata:
|
||||
.sect .bss; begbss:
|
||||
|
||||
! Some magic data. All EM systems need these.
|
||||
|
||||
.define _errno
|
||||
.comm _errno, 4 ! Posix errno storage
|
||||
|
||||
! The argv and env arrays.
|
||||
|
||||
.sect .rom
|
||||
|
@ -82,6 +77,12 @@ argv: .data4 exename, 0
|
|||
envp: .data4 0
|
||||
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
|
||||
.comm .trppc, 4 ! ptr to user trap handler
|
||||
.comm .ignmask, 4 ! user trap ignore mask
|
||||
|
|
Loading…
Reference in a new issue