Upcall handler

Peter Naulls peter at chocky.org
Sun Dec 16 17:51:02 PST 2001


In message <837603ea4a.Jo at village.uunet.be>
          John Tytgat <John.Tytgat at aaug.net> wrote:

> In message <0eb366e94a.peter at moo.chocky.org>
>           Peter Naulls <peter at chocky.org> wrote:
> 

> >   I'm going to investigate having a support module.
> 
> Cool ! But don't underestimate the work.

Quite.  Here it is below. The new module follows the diff.

Index: riscos-aof/ld/ld.c
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/riscos-aof/ld/ld.c,v
retrieving revision 1.7.2.5
diff -u -r1.7.2.5 ld.c
--- riscos-aof/ld/ld.c	2001/08/16 11:24:13	1.7.2.5
+++ riscos-aof/ld/ld.c	2001/12/17 01:43:36
@@ -1459,7 +1459,7 @@
 
   out ("The following Drlink linker commands are recognised:");
   out ("  -acornmap, -area[map] <file>, -aif, -aof, -bin, -case");
-  out ("  -leave[weak], -map, -no[unused], -output, -qui[et]");
+  out ("  -leave[weak], -map, -m[odule], -no[unused], -output, -qui[et]");
   out ("  -res[can], -throwback, -via <file>, -verbose\n");
 
 #ifndef CROSS_COMPILE
@@ -1695,7 +1695,7 @@
   strcpy (tmp, fname);
   len = strlen (tmp);
   /* If the filetype suffix already exists then don't add it again.  */
-  if (len < 4 || (strcmp (tmp + len - 4, ",ff8") && len < 252))
+  if (len < 4 || (tmp[len - 4] != ',' && len < 252))
     strcat (tmp, ",ff8");
 #else
   const char *tmp = fname;
@@ -1752,6 +1752,7 @@
 #define OPTION_AOF			160
 #define OPTION_BIN			161
 #define OPTION_QUIET			162
+#define OPTION_MODULE			163
 
   static struct option longopts[] = {
     {"acornmap", no_argument, NULL, OPTION_MAP},
@@ -1765,6 +1766,7 @@
     {"leave", no_argument, NULL, OPTION_LEAVEWEAK},
     {"leaveweak", no_argument, NULL, OPTION_LEAVEWEAK},
     {"map", no_argument, NULL, OPTION_MAP},
+    {"module", no_argument, NULL, OPTION_MODULE},
     {"no", no_argument, NULL, OPTION_NOUNUSED},
     {"nounused", no_argument, NULL, OPTION_NOUNUSED},
     {"nounusedareas", no_argument, NULL, OPTION_NOUNUSED},
@@ -1830,6 +1832,9 @@
 	  break;
 	case OPTION_MAP:
 	  add_option ("-map");
+	  break;
+	case OPTION_MODULE:
+	  add_option ("-module");
 	  break;
 	case OPTION_NOUNUSED:
 	  add_option ("-nounused");
Index: unixlib/Makefile
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/unixlib/Makefile,v
retrieving revision 1.3.2.2
diff -u -r1.3.2.2 Makefile
--- unixlib/Makefile	2001/10/04 12:44:20	1.3.2.2
+++ unixlib/Makefile	2001/12/17 01:43:48
@@ -20,5 +20,6 @@
 	mkdir -p $(upath)/stdio/o $(upath)/stdlib/o $(upath)/scl/o
 	mkdir -p $(upath)/string/o $(upath)/sys/o $(upath)/time/o
 	mkdir -p $(upath)/termios/o $(upath)/unix/o $(upath)/wchar/o
+	mkdir -p $(upath)/module/o
 	$(MAKE) -C source
 
Index: unixlib/source/Makefile
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/unixlib/source/Makefile,v
retrieving revision 1.4.2.8
diff -u -r1.4.2.8 Makefile
--- unixlib/source/Makefile	2001/09/13 14:22:29	1.4.2.8
+++ unixlib/source/Makefile	2001/12/17 01:43:52
@@ -201,6 +202,8 @@
 	$(libunixobj)/locale/strxfrm.o \
 	$(libunixobj)/locale/territory.o
 
+MODULE = $(libunixobj)/module/sharedunixlib.o
+
 NETLIB = $(libunixobj)/netlib/accept.o \
 	$(libunixobj)/netlib/bind.o \
 	$(libunixobj)/netlib/connect.o \
@@ -584,7 +587,8 @@
 	$(SIGNAL_ASM) $(STDIO_ASM) $(SCL_ASM) $(SYS_ASM) $(TIME_ASM) \
 	$(UNIX_ASM)
 
-all:	$(ux_gcc_bin_dir)/$(TRG)/unixlib.o $(ro_gcc_bin_dir)/$(TRG)/o/unixlib
+all:	$(ux_gcc_bin_dir)/$(TRG)/unixlib.o $(ro_gcc_bin_dir)/$(TRG)/o/unixlib \
+        $(ro_gccpkg)/SharedULib,ffa
 
 install_headers:
 	$(insthdr) clib "*.h" unixlib $(ux_gccpkg)/$(gn_cross_include_dir) $(ro_gccpkg)/$(gn_cross_include_dir)
@@ -600,6 +604,9 @@
 
 $(ro_gcc_bin_dir)/$(TRG)/o/unixlib:	$(C_OBJS) $(ASM_OBJS)
 	$(CROSS_AR) $(CROSS_AR_FLAGS) $@ $(C_OBJS) $(ASM_OBJS)
+
+$(ro_gccpkg)/SharedULib,ffa:	$(MODULE)
+	$(CROSS_CC) $(MODULE) -Xlinker -module -o $@
 
 # Static dependencies:
 $(libunixobj)/abort.o: abort.c
Index: unixlib/source/clib/unixlib/asm_dec.s
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/unixlib/source/clib/unixlib/asm_dec.s,v
retrieving revision 1.2.2.3
diff -u -r1.2.2.3 asm_dec.s
--- unixlib/source/clib/unixlib/asm_dec.s	2001/10/02 10:19:55	1.2.2.3
+++ unixlib/source/clib/unixlib/asm_dec.s	2001/12/17 01:43:53
@@ -295,12 +295,22 @@
 XOS_BPut			EQU	&00000B + X_Bit
 XOS_GBPB			EQU	&00000C + X_Bit
 XOS_Find			EQU	&00000D + X_Bit
+XOS_ReadLine			EQU	&00000E + X_Bit
+XOS_Control			EQU	&00000F + X_Bit
 XOS_GetEnv			EQU	&000010 + X_Bit
+XOS_Exit			EQU	&000011 + X_Bit
 XOS_SetEnv			EQU	&000012 + X_Bit
 XOS_IntOn			EQU	&000013 + X_Bit
+XOS_IntOff			EQU	&000014 + X_Bit
+XOS_CallBack			EQU	&000015 + X_Bit
 XOS_EnterOS			EQU	&000016 + X_Bit
+XOS_BreakPt			EQU	&000017 + X_Bit
+XOS_BrealCtrl			EQU	&000018 + X_Bit
 
+XOS_UpdateMEMC			EQU	&00001A + X_Bit
 XOS_SetCallBack			EQU	&00001B + X_Bit
+XOS_Mouse			EQU	&00001C + X_Bit
+XOS_Heap			EQU	&00001D + X_Bit
 XOS_Module			EQU	&00001E + X_Bit
 XOS_ReadUnsigned		EQU	&000021 + X_Bit
 XOS_ReadVarVal			EQU	&000023 + X_Bit
@@ -400,5 +410,8 @@
 XTaskWindow_TaskInfo		EQU	&043380 + X_Bit
 XWimp_ReadSysInfo		EQU	&0400F2 + X_Bit
 XDDEUtils_SetCLSize		EQU	&042581 + X_Bit
+
+XSharedUnixLibrary_RegisterUpCall	EQU	&55c80 + X_Bit
+XSharedUnixLibrary_DeRegisterUpCall	EQU	&55c81 + X_Bit
 
 	END
Index: unixlib/source/sys/_syslib.s
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/unixlib/source/sys/_syslib.s,v
retrieving revision 1.3.2.7
diff -u -r1.3.2.7 _syslib.s
--- unixlib/source/sys/_syslib.s	2001/09/06 14:52:00	1.3.2.7
+++ unixlib/source/sys/_syslib.s	2001/12/17 01:44:01
@@ -11,8 +11,9 @@
 	GET	clib/unixlib/asm_dec.s
 
 	; Keep in sync with error_table.
-NO_MEMORY * 0
+NO_MEMORY   * 0
 NO_CALLASWI * 1
+NO_SUL      * 2
 
 	AREA	|C$$code|, CODE, READONLY
 
@@ -37,6 +38,9 @@
 
 	EXPORT	|__main|
 
+|rmensure|
+	DCB "RMEnsure SharedUnixLibrary 1.00 RMLoad System:Modules.SharedULib", 0
+
 	ENTRY
 |__main|
 	; Read environment parameters
@@ -120,7 +124,12 @@
 	BNE	exit_with_error
 
 	MOV	ip, v1		; Restore ip.
-	
+
+	LDR	a1, =|rmensure|
+	SWI	XOS_CLI
+	MOVVS	a1, #NO_SUL
+	BVS	exit_with_error
+
 	; use of da's explicitly overridden if __dynamic_no_da is declared
 	LDR	a1, =|__dynamic_no_da|
 	TEQ	a1, #0
@@ -345,11 +354,14 @@
 error_table
 	DCD	error_no_memory
 	DCD	error_no_callaswi
+	DCD	error_no_sharedunixlib
 
 error_no_callaswi
 	DCB	"Module CallASWI is not present.", 13, 10, 0
 error_no_memory
 	DCB	"Insufficient memory for application", 13, 10, 0
+error_no_sharedunixlib
+	DCB	"This application requires version 1.00 of the SharedUnixLibrary module", 13, 10, 0
 	ALIGN
 
 check_for_callaswi
@@ -440,6 +452,7 @@
 	IMPORT	|__ul_errbuf|
 |__env_unixlib|
 	STMFD	sp!, {a1, a2, a3, a4, v1, v2, lr}
+	SWI	XOS_IntOff
 	MOV	v1, #0
 	ADR	v2, handlers
 t06
@@ -455,6 +468,15 @@
 	ADD	v1, v1, #1
 	CMP	v1, #17
 	BLT	t06
+
+	LDR	r1, =|__env_riscos|
+	SWI	XSharedUnixLibrary_RegisterUpCall
+	LDR	r0, =|__sharedunixlibrary_key|
+	STR	r2, [r0]
+	MOV	r0, #16
+	SWI	XOS_ChangeEnvironment
+
+	SWI	XOS_IntOn
 	LDMFD	sp!, {a1, a2, a3, a4, v1, v2, pc}^
 	
 handlers
@@ -474,9 +496,13 @@
 	DCD	0		; Exception registers
 	DCD	0		; Application space
 	DCD	0		; Currently active object
-	DCD	|__h_upcall|	; Up call
+	DCD	0		; UpCall
 
-	
+	EXPORT	|__sharedunixlibrary_key|
+|__sharedunixlibrary_key|
+	DCD	0
+
+
 	IMPORT	|__unixlib_raise_signal|
 	EXPORT	|x$stack_overflow|
 	EXPORT	|__rt_stkovf_split_small|
Index: unixlib/source/unix/unix.c
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/unixlib/source/unix/unix.c,v
retrieving revision 1.2.2.7
diff -u -r1.2.2.7 unix.c
--- unixlib/source/unix/unix.c	2001/09/14 14:01:17	1.2.2.7
+++ unixlib/source/unix/unix.c	2001/12/17 01:44:07
@@ -270,6 +270,12 @@
 _exit (int return_code)
 {
   int status;
+  extern int __sharedunixlibrary_key;
+  int regs[10];
+
+  regs[2] = __sharedunixlibrary_key;
+  __os_swi(0x55c81, regs);
+
 
   /* Interval timers must be stopped.  */
   if (__u)




;----------------------------------------------------------------------------
;
; $Source$
; $Date$
; $Revision$
; $State$
; $Author$
;
;----------------------------------------------------------------------------


        GET     clib/unixlib/asm_dec.s

        AREA    REL, CODE, READONLY

chunk   EQU     0x55c80    ; SharedUnixLibrary SWI Chunk 
error   EQU     0x0081a400 ; SharedUnixLibrary Error block




|module_start|
        DCD     0                          ; Start code
        DCD     init_code   - module_start ; Initialisation code
        DCD     final_code  - module_start ; Finalisation code
        DCD     0                          ; Service handler
        DCD     title       - module_start ; Title string
        DCD     help        - module_start ; Help string
        DCD     0                          ; Command table
        DCD     chunk                      ; SWI Base
        DCD     swi_handler - module_start ; SWI Handler
        DCD     swi_table   - module_start ; SWI Table
        DCD     0                          ; SWI Decoder

|help|
        DCB     "SharedUnixLibrary	1.00 (16th Dec 2001) © Peter Naulls, 2001 ", 0


|title|
|swi_table|
        DCB     "SharedUnixLibrary", 0
        DCB     "RegisterUpCall", 0
        DCB     "DeRegisterUpCall", 0
        ALIGN

|error_swi|
        DCD     error + 0
        DCB     "Unknown SharedUnixLibrary SWI call", 0
        ALIGN

|error_unknown|
        DCD     error + 1
        DCB     "Unknown SharedUnixLibrary Key", 0
        ALIGN

|error_active|
        DCD     error + 2
        DCB     "There are still clients active", 0
        ALIGN


|swi_handler|
        CMP     r11, #0
        BEQ     register
        CMP     r11, #1
        BEQ     deregister
        ADR     r0, error_swi - module_start
        ORRS    pc, r14, #VFlag


        ; Application UpCall handler, PRM 1-291
        ;
        ; The address of this handler is passed back via The RegisterUpCall SWI.
        ; The caller application then provides that address to OS_ChangeEnvironment
        ; Having this handler in a module enables it to be validly called when
        ; the application isn't paged in.  This is despite the fact that most of
        ; the UpCalls we are not interested in at all.

|upcall_handler|
        TEQ     a1, #256          ; New Application UpCall
        MOVNES  pc, lr

        MOV     r2, r12           ; Key passed to handler in R12
        LDR     r1,  [r2, #4]     ; Get handler address
        LDR     r12, [r2, #8]     ; Get module's private word

        STMFD   sp!, {lr}
        BL      |delink|          ; Delink the handler
        CMP     r2, #0
        LDMEQIA sp!, {pc}^
        LDMIA   sp!, {lr}

        MOV     pc, r1            ; Jump to application handler


        ; Register an application with the module.
        ;
        ; This SWI registers an application as an intended recipient of UpCalls
        ; After calling this method, it should then call OS_ChangeEnvironment
        ; with R0 = 16, and values returned from this SWI.
        ;
        ; The application may deregister its interest by calling DeRegister_UpCall,
        ; such as during an application's Exit and Error handlesr, or for other reasons.
        ; It is important that the application does so, as the module will not
        ; exit if any claimants remain.
        ;
        ; The is no need to deregister if UpCall 256 occurs; the module will do
        ; that automatically.
        ;
        ; Entry
        ;    R1 = Address of application's handler function
        ;
        ; Exit
        ;    R1 = Address of UpCall handler to pass in R1 to OS_ChangeEnvironment
        ;    R2 = SharedUnixLibrary key, required for deregistration, and
        ;         passed in R2 to OS_ChangeEnvironment 


|register|
        STMFD   sp!, {r0, r3, lr}

        ; The memory claimed for now merely provides a way validate a caller.
        ; Later on, it will be used to store information on a per-client basis.

        MOV     r0, #6
        MOV     r3, #12
        SWI     XOS_Module        ; Claim memory to use
        LDMVSIA sp!, {r0, r3, pc}^

        ; result in R2, return to caller
        LDR     r0,  [r12, #0]    ; Get head of list
        STR     r0,  [r2, #0]     ; Store in new block
        STR     r2,  [r12, #0]    ; Set to head of list

        STR     r1,  [r2, #4]     ; Set handler function address
        STR     r12, [r2, #8]     ; Set module private word

        ; return UpCall handler address in R1
        ADR     r1, upcall_handler - module_start

        LDMIA   sp!, {r0, r3, pc}^


        ; Deregister a previously registered handler
        ;
        ; Entry
        ;    R2 = Key provided when registering
        ;
        ; Exit
        ;    R2 = 1
        ;
        ; An error will be generated if the key is invalid, for example
        ; if the handler has already been deregistered

|deregister|
        STMFD   sp!, {lr}
        BL      |delink|
        LDMIA   sp!, {lr}

        CMP     r2, #0
        ADREQ   r0, error_unknown - module_start
        ORREQS  pc, lr, #VFlag

        MOVS    pc, lr


        ; Delink the handler
        ;
        ; Entry
        ;    R2 = Key
        ;
        ; Exit
        ;    R2 - 1 = Success, 0 = Key not found

|delink|
        STMFD   sp!, {r0-r1, lr}

        ; Try to find reference
        MOV     r1, r12           ; Previous point in list
        LDR     r0, [r12, #0]     ; Get first item in list

|delink_find|
        CMP     r0, #0
        MOVEQ   r2, #0
        LDMEQIA sp!, {r0-r1, pc}^ ; End of list, not found

        CMP     r0, r2            ; Compare passed key
        MOVNE   r1, r0            ; Set to current point in list
        LDRNE   r0, [r0, #0]      ; Get next item
        BNE     |delink_find|

        LDR     r0, [r0, #0]      ; Get next item
        STR     r0, [r1, #0]      ; Fix up list

        MOV     r0, #7
        SWI     XOS_Module        ; Free block

        MOV     r2, #1
        LDMIA   sp!, {r0-r1, pc}^


        ; Module initialisation
        ;
        ; Claim 4 bytes initially to use as the head of a list

|init_code|
        CMP     r12, #0
        MOVNES  pc, lr            ; Ignore reinitialisation

        MOV     r0, #6
        MOV     r3, #4
        SWI     XOS_Module        ; Claim memory to use
        MOVVSS  pc, lr
        MOV     r12, r2

        MOV     r0, #0
        STR     r0, [r12, #0]     ; List of blocks

        MOVS    pc, lr


        ; Module finalisation
        ;
        ; Only allow exit if there are no claimants

|final_code|
        LDR     r0, [r12, #0]
        CMP     r0, #0

        ADRNE   r0, error_active - module_start
        ORRNES  pc, r14, #VFlag
        MOVS    pc, lr

        END



-- 
------------------------------------------------------------------------
 Peter Naulls - peter at chocky.org
 RISC OS Projects Initiative  -  http://www.chocky.org/initiative/
 Java for RISC OS and ARM     -  http://www.chocky.org/java/
 Debian Linux on RiscPCs      -  http://www.chocky.org/debian/
------------------------------------------------------------------------



More information about the gcc mailing list