;;; -*- 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. (defconst min-phys-adr xxx) (defconst max-phys-adr xxx) (defconst phys-adr-1 xxx) (defconst phys-adr-2 xxx) ;initial map has pages 0-4 mapped to low five pages of phys mem, and mapped to ;low five pages of instruction and data space. last page is filled with halt instructions ;phys-page-1 is set to phys page after halt pages ;a15 is pointer to base of memory table (defafun march-copier () ;;a0 = 0 means first user function; a0 = 1 means second move-loop (movei a0 0) select-loop ;;select new physical location ;; for now, skip to by one page, and increment offset by 64 bits ;;read current phys adr for function (movei vma #.phys-adr-1) (alu add vma a0) ;first or second pass (alu l+r vma-start-read-no-transport vma a15) (nop) (movei a14 #.(+ 1024. 2)) (alu l+r a14 a14 md) (move a13 a14) (alu and a14 #.(lognot 1023.)) (alu and a13 1023.) ;;see if this is the last page by adding ;;the maximum size, and comparing with the max address (movei a1 1024.) (alu add a1 a1 a14) (movei vma #.max-phys-adr) (alu l+r vma-start-read-no-transport vma a15) (nop) (alu sub nop a1 md) (test br-less-than) (branch page-ok ()) (movei vma #.min-phys-adr) (alu l+r vma-start-read-no-transport vma a15) (nop) (move a14 md) page-ok (alu nop a0) (test br-equal) (branch page-ok-1) ;;this is the second pass, must not select same page as first pass (movei vma #.phys-adr-1) (alu l_r vma-start-read-no-transport vma a15) (nop) (alu sub a14 md) (test br-equal) (branch select-loop) page-ok-1 (movei vma #.length-1) (alu add vma a0) ;first or second pass (alu l+r vma-start-read-no-transport vma a15) (nop) (alu add a12 a13 md) (movei a11 1024.) (alu sub a12 a11) (test br-less-than) (branch off-ok ()) (movei a13 0) off-ok ;;now a14 is address of base of physical page and a13 is offset ;;store updated phys adr (alu add md a14 a13) (movei vma #.phys-adr-1) (alu add vma a0) (alu add vma-start-write vma a15) (nop) ;;select virtual page (movei vma #.user-virtual-1) (alu add vma a0) ;first or second pass (alu l+r vma-start-read-no-transport vma a15) (nop) (move a12 md) (movei a11 1024.) (alu add a12 a12 a11) (test br-not-equal) (branch virt-ok) (movei a12 #.(+ (ash 1 25.) (* 16. 1024.))) virt-ok ;;a12 is base of virtual page to use (move md a12) (movei vma #.user-virtual-1) (alu add vma a0) (alu l+r vma-start-write vma a15) ;;set up the map (movei vma 0) (nop) (nop) (nop) (move a11 memory-map) (alu and a11 a11 #xff) (move a10 a14) ;phys word address ;;multiply by 4 (alu add a10 a10 a10) (alu add a10 a10 a10) (alu add a10 a10 a11) ;add in permission bits (move vma a12) ;base virtual page (nop) (nop) (nop) (move memory-map a10) ;;store halts (move vma a12) (movei a0 1024.) (alu add a0 a0 vma) (movei md #xffffffff) store-halt-loop (move vma-start-write vma) (nop) (alu l+1 vma vma vma) (alu sub vma a0) (test br-not-equal) (branch store-halt-loop ()) (alu nop a0) (test br-not-equal) (branch do-relocate) (alu l+1 a0 a0 a0) (jump select-loop) do-relocte ...relocate... ;;flush icache (movei vma #.user-virtual-1) (alu add vma-start-read-no-transport vma a15) (nop) (ash vma -1) (movei a0 #.(ash 1 25.)) (alu add nop vma a0) (nop) ;;call user program (dispatch open-call) ;;unmap user pages (movei vma #.(ash halt-page 10.)) (nop) (nop) (nop) (move a1 memory-map) (movei a0 0) finish-loop (movei vma #.user-virutal-1) (alu add vma a0) (alu add vma-start-read-no-transport vma a15) (nop) (move vma md) (nop) (nop) (nop) (move memory-map a1) (alu nop a0) (test br-not-equal) (jump move-loop) (alu l+1 a0 a0 a0) (jump finish-loop) ) 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.