;;; -*- Mode:LISP; Package:LISP-INTERNALS; Base:10; Readtable:CL -*- ;; User provides a piece of code which is in two parts, each of which ;; resides on one page (probably using up less than half a page) ;; This code will be written using defafuns which can jump between ;; each other, finally jumping to a constant location, the copy routine. ;; The copy routine will work from an image of the code in low memory ;; and copy it to two pages at offsets which are different and change ;; each time the routine is called. All the other virtual pages should ;; map to a page of all halt instructions. The unused instructions on ;; the copied pages are halt instuctions. #| Questions: We need to make a type of defafun which is an alignment within a page. Defafuns need to provide us with program length. The user program must guarantee that it does not use A6-A15 ever. These are reserved for the copy program so that we can both call and jump to the user program. We do not handle dispatch instructions. To do this, the relocator will need to be smarter. Set Up. Memory layout Page 0 Trap code Copy code Page 2 User1 Page 3 User2 Page 4 Halt instructions. Remaining pages are possible candidates for copying to. Begin Loop select two new physical pages select two new virtual pages Map virtual pages to the physical pages Fill the virtual pages with halt bit (using the function boundary marker) select two new offsets in the pages Copy each of the instructions Relocate the jump instructions scan function looking for conditional jump opcode, add offset to low 12 bits also, scan function looking for calls/long jumps to other function and fix them Jump to the first Copied user function ... Map the used virtual pages back to the halt page. Loop. |# (eval-when (compile load eval) (global:defconst Virtual-address-original-user1 0) (global:defconst Virtual-address-original-user2 (1+ Virtual-address-original-user1)) (global:defconst Copy-location-user1 2) (global:defconst Copy-location-user2 (1+ Copy-location-user1)) (global:defconst Length-user1 4) (global:defconst Length-user2 (1+ Length-user1)) (global:defconst %%copy-offset (byte 12. -1))) ;;Assumes that this code is jumped to with A15 holding the address of a Memory structure ;;Assumes that Copy to locations + Length will be on the same page. ;; This structure holds: ;; Virtual Address of Original User1 ;; Virtual Address of Original User2 ;; Copy to location for User1 ;; Copy to location for User2 ;; Length of User1 ;; Length of User2 ;;;Copy each of the instructions ;;; Relocate the jump instructions ;;; scan function looking for conditional jump opcode, add offset to low 12 bits ;;; also, scan function looking for calls/long jumps to other function and fix them (defafun Copy-and-relocate () (move a14 gr:*zero*) (movei a1 '010) ;;Opcode for Jump or call instruction. (movei a13 '#.Virtual-address-original-user1) User1/2-loop (alu l+r a13 a13 a14 bw-24) ;;Increment copy-from index for user1 vs user2 (alu l+r vma-start-read-no-transport a15 a13 bw-24 unboxed-vma unboxed-md) (movei a12 '#.Copy-location-user1) (move a13 md) ;;Address of copy-from location (alu-field field-extract-r a3 ignore a13 (byte 24. -1)) ;;Turn copy-from Address into PC type (alu l+r a12 a12 a14 bw-24) ;;Increment copy-to index for user1 vs user2 (alu l+r vma-start-read-no-transport a15 a12 bw-24 unboxed-vma unboxed-md) (movei a11 '#.Length-user1) (move a12 md) ;;Addres of copy-to location (alu-field field-extract-r a2 ignore a12 (byte 24. -1)) ;;Turn copy-to address into PC type (alu-field field-extract-r a5 ignore a12 %%copy-offset) ;;Offset within the page we are copying to. (alu l+r a11 a11 a14 bw-24) ;;Increment lenth index for user1 vs user2 (alu l+r vma-start-read-no-transport a15 a11 bw-24 unboxed-vma unboxed-md) (move a10 gr:*zero*) ;;wait for MD; Zero length counter. (move a4 md) ;;Length of code to copy Loop-for-each-instruction ;;incrementing A10 before repeating (alu l+1 vma-start-read-no-transport a13 ignore unboxed-vma unboxed-md) (alu l+1 a10 a10 ignore bw-24) ;;Wait for MD; Increment inst loop counter -- a10 (move a7 md) ;;high inst word (move vma-start-read-no-transport a13 unboxed-vma unboxed-md) ;;start read of low inst word (alu-field field-extract-r a6 ignore a7 (byte 3. -26.)) ;;Wait for MD; Opcode of high inst -- hw:%%i-op-code-high (move a8 md) ;;low inst word (move vma-start-read-will-write a12 unboxed-vma unboxed-md) ;;Set up vma for copy of low inst below ;;; Is it a conditional jump? (alu-field aligned-field-xor nop gr:*zero* a6 (byte 2 0)) ;;low two bits of opcode (alu-field field-extract-r nop ignore a7 (byte 2 -24.) br-not-equal) ;; next pc (branch maybe-call-or-jump (alu l+2 a13 a13 ignore br-not-equal)) ;;Increment from-address (branch copy-it (move md-start-write-no-gc-trap a8)) ;;Copy low word inst ;;;We have a Branch inst ;;or a CALL-Z instruction (unconditional-branch copy-it (alu l+r md-start-write-no-gc-trap a8 a5 bw-24));;Assume this does not affect bits above 12th Maybe-call-or-jump (alu xor nop a1 a6 bw-24) (alu l-r a0 a8 a3 bw-24 br-not-equal) ;;Subtract base source address from jump address (branch copy-it (move md-start-write-no-gc-trap a8)) ;;Copy low word inst ;;;We have a jump or call inst (alu l+r md-start-write-no-gc-trap a0 a2 bw-24) ;;Add back base destination address to jump address Copy-it ;;Low word is already copied. (alu l+1 vma-start-read-will-write a12 ignore unboxed-vma unboxed-md) (alu l-r nop a10 a4 bw-24) (move md-start-write-no-gc-trap a7 br-not-equal) ;;copy high word inst (branch Loop-for-each-instruction (alu l+2 a12 a12 ignore bw-24)) ;;Increment To-address ;;;Check for loop again for next piece of code. (alu l-1 nop a14 ignore bw-24 boxed) (movei a13 '#.Virtual-address-original-user1 br-not-equal) (branch User1/2-loop (alu l+1 a14 a14 ignore bw-24 boxed)))