Teach qemuppc to halt the cpu on _exit().
authorGeorge Koehler <xkernigh@netscape.net>
Wed, 7 Dec 2016 23:11:12 +0000 (18:11 -0500)
committerGeorge Koehler <xkernigh@netscape.net>
Wed, 7 Dec 2016 23:11:12 +0000 (18:11 -0500)
Without this, qemu-system-ppc spins the host cpu until I close its
window.  I assume the default G3 emulation.  The emulator yields the
host cpu if I set certain flags in hid0 then msr.  The hid0 flag can
be any of DOZE, NAP, SLEEP, so I just set all 3.  I encode mfmsr and
mtmsr with .data4, because our assembler doesn't know instructions for
supervisor mode.

Also move some common symbols from .rom to .bss.  Our assembler puts
common symbols in any section.

Also clean up the file.  Delete a comment about linuxppc that is wrong
here.  Delete redundant .extern because .define is the same.

plat/qemuppc/boot.s

index 2dd9a4c..1100f38 100644 (file)
 .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 msr0
+       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