home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / documentation / documents / a252cmhg < prev    next >
Internet Message Format  |  1999-04-27  |  4KB

  1. From: enevill@acorn.co.uk (Edward Nevill)
  2. Subject: Re: Modules in C
  3. Date: 4 Oct 91 14:01:06 GMT
  4.  
  5. In article <1991Oct01.212021.16581@demon.co.uk> pmoore@cix.compulink.co.uk (Paul Moore) writes:
  6.  
  7. >The second problem is more of a pain. I have worked out that I should
  8. >declare my vector handler to CMHG as an IRQ handler, so that I get the
  9. >proper veneer round my code. BUT... the vector I want to claim is (you
  10. >guessed it!) OS_ReadLine, which requires the C flag to be set on exit
  11. >based on the results of the call. As far as I can see, the standard
  12. >veneer does not allow the setting of flags on return.
  13. >
  14. >As far as I can see, the only way round this is to write my own entry
  15. >veneer for the handler. However, I'm not 100% sure what the 'standard'
  16. >veneer does. I can probably work it out by disassembling the code
  17. >generated by CMHG, but can anybody *tell* me what it does - to save me
  18. >some work? If so, I'd be very grateful. Also, maybe later versions of
  19. >CMHG would benefit from an extra keyword 'irq-handlers-c' or some such?
  20. >
  21.  
  22. irq_entry       STMDB   sp!, {r0-r9, sl, fp, lr}  ; Save regs on IRQ | SVC stack
  23.                 MOV     r0, sp           ; Set up _kernel_swi_regs * argument
  24. +               ADD     r2, sp, #12 * 4  ; Set up pointer to carry arg (= LR!!!)
  25.                 MOV     r6, pc
  26.                 BIC     r6, r6, #3
  27.                 TEQP    r3, #3           ; To SVC mode, preserve IRQ / FIQ state
  28.                 MOV     fp, #0           ; Halt C backtrace at this stack level
  29.                 MOV     r7, lr           ; Save SVC lr
  30.                 MOV     sl, sp, LSR #20
  31.                 MOV     sl, sl, ASL #20  ; Get LWM of SVC stack
  32.                 LDMIA   sl, {r4, r5}     ; Save static data relocations across fn call
  33.                 MOV     r1, r12          ; Set up private workspace argument
  34.                 LDR     r12, [r12]       ; Get pointer to static relocations for module
  35.                 LDMIB   r12, {r12, lr}   ; IB skips first word
  36.                 STMIA   sl, {r12, lr}    ; Set up static data relocations
  37.                 ADD     sl, sl, #512+40  ; 40 = size of stack chunk structure
  38.                 BL      c_function       ; Do the function
  39.                 SUB     sl, sl, #512+40  ; Point back to base of SVC stack
  40.                 STMIA   sl, {r4, r5}     ; Restore old static data relocations
  41.                 MOV     lr, r7           ; Restore SVC lr
  42.                 TEQP    r6, #0           ; Back to entry mode
  43.                 CMPS    r0, #0           ; Intercept?
  44.                 LDMNEIA sp!, {r0-r9, sl, fp, pc}^ ; No (carry arg will not be written!!!)
  45. -               LDMIA   sp!, {r0-r9, sl, fp, lr, pc}^ ; Yes
  46. +               LDMIA   sp!, {r0-r9, sl, fp, ip, lr} ; Yes (ip = carry value to ret)
  47. +               BIC     lr, lr, #1:SHL:29
  48. +               CMP     ip, #0
  49. +               ORRNE   lr, lr, #1:SHL:29
  50. +               MOVS    pc, lr
  51.  
  52. The veneer genererated for an IRQ handler by cmhg is something like the above
  53. without the '+' lines. Remove the '-' line and add the '+' lines to produce a
  54. veneer which allows you to return the carry flag.
  55.  
  56. The declaration the a handler using this looks something like
  57.  
  58. int c_function(_kernel_swi_regs *r, void *pw, int *carry);
  59.  
  60. NOTE: you must not write the carry arg unless you are intercepting the call
  61. (ie you are returning 0 from c_function). Doing so will lead to disaster
  62. (it will continue executing at the address you write to carry, so if you
  63. write 0 it will continue executing at location 0!!!). I may consider making
  64. this more robust in a later version.
  65.  
  66. To claim the vector in your init code
  67.  
  68. extern int irq_entry;
  69.  
  70. _kernel_oserror *user_init(char *cmd_tail, int podule_base, void *pw)
  71. {
  72.     _kernel_swi_regs r;
  73.     ...
  74.     r.r[0] = 0x0e; /* ReadLineV */
  75.     r.r[1] = (int)&irq_entry;
  76.     r.r[2] = (int)pw;
  77.     _kernel_swi(OS_Claim, &r, &r);
  78.     ...
  79.     return 0;
  80. }
  81.  
  82. NOTE: If you claim a vector in your initialisation code like this you must
  83. either return 0 indicating no error or release the vector before returning an
  84. error (your finalisation is not called if there is an error in initialisation).
  85.  
  86. Have fun,
  87. Edward.
  88.  
  89.