1251881Speter/* SPDX-License-Identifier: GPL-2.0-or-later */ 2251881Speter/* 3251881Speter * crt0_r.S: Entry function for SPU-side context restore. 4251881Speter * 5251881Speter * Copyright (C) 2005 IBM 6251881Speter * 7251881Speter * Entry and exit function for SPU-side of the context restore 8251881Speter * sequence. Sets up an initial stack frame, then branches to 9251881Speter * 'main'. On return, restores all 128 registers from the LSCSA 10251881Speter * and exits. 11251881Speter */ 12251881Speter 13251881Speter#include <asm/spu_csa.h> 14251881Speter 15251881Speter.data 16251881Speter.align 7 17251881Speter.globl regs_spill 18251881Speterregs_spill: 19251881Speter.space SIZEOF_SPU_SPILL_REGS, 0x0 20251881Speter 21251881Speter.text 22251881Speter.global _start 23251881Speter_start: 24251881Speter /* Initialize the stack pointer to point to 16368 25251881Speter * (16kb-16). The back chain pointer is initialized 26251881Speter * to NULL. 27251881Speter */ 28251881Speter il $0, 0 29251881Speter il $SP, 16368 30251881Speter stqd $0, 0($SP) 31251881Speter 32251881Speter /* Allocate a minimum stack frame for the called main. 33251881Speter * This is needed so that main has a place to save the 34251881Speter * link register when it calls another function. 35251881Speter */ 36251881Speter stqd $SP, -160($SP) 37251881Speter ai $SP, $SP, -160 38251881Speter 39251881Speter /* Call the program's main function. */ 40251881Speter brsl $0, main 41251881Speter 42251881Speter.global exit 43251881Speter.global _exit 44251881Speterexit: 45251881Speter_exit: 46251881Speter /* SPU Context Restore, Step 5: Restore the remaining 112 GPRs. */ 47251881Speter ila $3, regs_spill + 256 48251881Speterrestore_regs: 49251881Speter lqr $4, restore_reg_insts 50251881Speterrestore_reg_loop: 51251881Speter ai $4, $4, 4 52251881Speter .balignl 16, 0x40200000 53251881Speterrestore_reg_insts: /* must be quad-word aligned. */ 54251881Speter lqd $16, 0($3) 55251881Speter lqd $17, 16($3) 56251881Speter lqd $18, 32($3) 57251881Speter lqd $19, 48($3) 58251881Speter andi $5, $4, 0x7F 59251881Speter stqr $4, restore_reg_insts 60251881Speter ai $3, $3, 64 61251881Speter brnz $5, restore_reg_loop 62251881Speter 63251881Speter /* SPU Context Restore Step 17: Restore the first 16 GPRs. */ 64251881Speter lqa $0, regs_spill + 0 65251881Speter lqa $1, regs_spill + 16 66251881Speter lqa $2, regs_spill + 32 67251881Speter lqa $3, regs_spill + 48 68251881Speter lqa $4, regs_spill + 64 69251881Speter lqa $5, regs_spill + 80 70251881Speter lqa $6, regs_spill + 96 71251881Speter lqa $7, regs_spill + 112 72251881Speter lqa $8, regs_spill + 128 73251881Speter lqa $9, regs_spill + 144 74251881Speter lqa $10, regs_spill + 160 75251881Speter lqa $11, regs_spill + 176 76251881Speter lqa $12, regs_spill + 192 77251881Speter lqa $13, regs_spill + 208 78251881Speter lqa $14, regs_spill + 224 79251881Speter lqa $15, regs_spill + 240 80251881Speter 81251881Speter /* Under normal circumstances, the 'exit' function 82251881Speter * terminates with 'stop SPU_RESTORE_COMPLETE', 83251881Speter * indicating that the SPU-side restore code has 84251881Speter * completed. 85251881Speter * 86251881Speter * However it is possible that instructions immediately 87251881Speter * following the 'stop 0x3ffc' have been modified at run 88251881Speter * time so as to recreate the exact SPU_Status settings 89251881Speter * from the application, e.g. illegal instruciton, halt, 90251881Speter * etc. 91251881Speter */ 92251881Speter.global exit_fini 93251881Speter.global _exit_fini 94251881Speterexit_fini: 95251881Speter_exit_fini: 96251881Speter stop SPU_RESTORE_COMPLETE 97251881Speter stop 0 98251881Speter stop 0 99 stop 0 100 101 /* Pad the size of this crt0.o to be multiple of 16 bytes. */ 102.balignl 16, 0x0 103