245 |
|
// Restore PowerPC registers |
246 |
|
lwz r1,XLM_EMUL_RETURN_STACK(0) |
247 |
|
RESTORE_SYSTEM_R2 |
248 |
– |
RESTORE_SYSTEM_R13 |
248 |
|
lmw r13,20(r1) |
249 |
|
lfd f14,20+19*4+0*8(r1) |
250 |
|
lfd f15,20+19*4+1*8(r1) |
810 |
|
// Enter nanokernel |
811 |
|
mtlr r3 |
812 |
|
blr |
813 |
+ |
|
814 |
+ |
|
815 |
+ |
/* |
816 |
+ |
* Define signal handlers with alternate stack initialization magic |
817 |
+ |
*/ |
818 |
+ |
|
819 |
+ |
#define SIG_STACK_SIZE 0x10000 |
820 |
+ |
|
821 |
+ |
ASM_MACRO_START do_define_signal_handler \ |
822 |
+ |
ASM_MACRO_ARG0_DEF /* name */ \ |
823 |
+ |
ASM_MACRO_ARG1_DEF /* stack */ \ |
824 |
+ |
ASM_MACRO_ARG2_DEF /* stack id */ \ |
825 |
+ |
ASM_MACRO_ARG3_DEF /* signal handler */ |
826 |
+ |
|
827 |
+ |
// Alternate stack lower base for this signal handler |
828 |
+ |
.lcomm ASM_MACRO_ARG1,SIG_STACK_SIZE,ASM_ALIGN_2(4) |
829 |
+ |
ASM_TYPE(ASM_MACRO_ARG1,@object) |
830 |
+ |
|
831 |
+ |
// Represents the current nest level for this signal handler |
832 |
+ |
// Note that in SheepShaver, SIGUSR2 signals are blocked while |
833 |
+ |
// handling other signals so, it's unlikely we ever get a nest |
834 |
+ |
// level greater than 1 |
835 |
+ |
.lcomm ASM_MACRO_ARG2,4,ASM_ALIGN_2(2) |
836 |
+ |
ASM_TYPE(ASM_MACRO_ARG2,@object) |
837 |
+ |
|
838 |
+ |
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ASM_MACRO_ARG0) |
839 |
+ |
C_SYMBOL_NAME(ASM_MACRO_ARG0): |
840 |
+ |
// Preserve args in scratch registers |
841 |
+ |
mflr r14 |
842 |
+ |
mr r15,r3 |
843 |
+ |
mr r16,r4 |
844 |
+ |
mr r17,r5 |
845 |
+ |
mr r18,r1 |
846 |
+ |
|
847 |
+ |
// Atomically increase stack_id |
848 |
+ |
lis r19,ASM_HA16(ASM_MACRO_ARG2) |
849 |
+ |
la r19,ASM_LO16(ASM_MACRO_ARG2,r19) |
850 |
+ |
li r4,1 |
851 |
+ |
mr r3,r19 |
852 |
+ |
bl C_SYMBOL_NAME(atomic_add) |
853 |
+ |
cmpwi r3,0 |
854 |
+ |
bne- 1f |
855 |
+ |
|
856 |
+ |
// ID was 0, we can use the local stack |
857 |
+ |
lis r9,ASM_HA16(ASM_MACRO_ARG1) |
858 |
+ |
lis r3,(SIG_STACK_SIZE>>16) |
859 |
+ |
la r9,ASM_LO16(ASM_MACRO_ARG1,r9) |
860 |
+ |
addi r3,r3,((SIG_STACK_SIZE&0xffff)-64) |
861 |
+ |
add r1,r9,r3 |
862 |
+ |
|
863 |
+ |
1: // Invoke signal handler |
864 |
+ |
stwu r1,-16(r1) |
865 |
+ |
mr r3,r15 |
866 |
+ |
mr r4,r16 |
867 |
+ |
mr r5,r17 |
868 |
+ |
bl C_SYMBOL_NAME(ASM_MACRO_ARG3) |
869 |
+ |
addi r1,r1,16 |
870 |
+ |
|
871 |
+ |
// Atomically decrease stack id |
872 |
+ |
mr r3,r19 |
873 |
+ |
li r4,-1 |
874 |
+ |
bl C_SYMBOL_NAME(atomic_add) |
875 |
+ |
|
876 |
+ |
// Restore kernel stack and return |
877 |
+ |
mtlr r14 |
878 |
+ |
mr r1,r18 |
879 |
+ |
blr |
880 |
+ |
ASM_MACRO_END |
881 |
+ |
|
882 |
+ |
#define DEFINE_SIGNAL_HANDLER(NAME) \ |
883 |
+ |
do_define_signal_handler \ |
884 |
+ |
NAME##_handler_init ASM_MACRO_ARG_SEP \ |
885 |
+ |
NAME##_stack ASM_MACRO_ARG_SEP \ |
886 |
+ |
NAME##_stack_id ASM_MACRO_ARG_SEP \ |
887 |
+ |
NAME##_handler |
888 |
+ |
|
889 |
+ |
DEFINE_SIGNAL_HANDLER(sigusr2) |