.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)
! 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
! 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
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