Lec-3-Hw-4-trap Reading: P&P chp 5: 5.4.5-5.5 and P&P Appendix C: page 521 (LC3 memory layout) page 541 (the TRAP instruction), page 543 (the LC3 OS's system calls) (We do not have an LC3 OS program, but we could write one like the one they describe.) Problems: ----(1.) The first 512 memory locations in the LC3 are called the "Vector Table", VT. The VT is divided in sections, the Trap Vector Table, TVT, the Exception Vector Table, EVT, and the Interrupt Vector Table, IVT. All three sections are used similarly; so, we will not distinguish between them here. At system start up time, "boot" time, the program loaded at address h0200 starts executing. This would typically be the Operating System's boot program. One of the tasks the OS undertakes is to initialize the TVT with addresses so that TRAP instructions will function correctly: the TVT is a jump table, each location in the TVT holds an address of a function that can be jumped to by fetching its address from the TVT and loading that address into the PC. That is what the TRAP instruction does, jump to a function via an address stored in the TVT. Suppose a part of the OS program is a function that displays a "help" message. Let's call the function HELP. Suppose HELP was loaded into memory at address h1000 (recall P&P use "x" for hex notation). To simplify our language, let's call that address the "pointer to" HELP, and let's call the memory location that holds that pointer the "TVT slot" for the function HELP. To jump to HELP, we need to know which TVT slot holds the pointer. You are the designer of the LC3's OS. Your tasks are: (a) Decide which TVT slot holds the pointer to HELP. Recall that the TVT is the first 256 memory locations (addresses x0000 to x00ff). Fill in the address of that slot and its content: address Memory content ------- -------------- h : (b) Complete the OS code that loads HELP's TVT slot with the pointer to HELP. It is written in P&P's LC3 assembly language, the Global Data Table is at address x0202, and execution begins at address x0200: .ORIG x0200 LEA R7, x2 ;-- Prepare to jump over GDT JMP R7 ;-- jump over GDT .FILL x ________ ;-- GDT: location of HELP's TVT slot .FILL x ________ ;-- GDT: HELP's pointer LEA R4, x-3 ;-- R4 <=== address of GDT (x0202) LDR R0, R4, __ ;-- R0 <=== location of HELP's TVT slot LDR R1, R4, __ ;-- R1 <=== HELP's pointer STR R_, R_, 0 ;-- Store HELP's pointer in HELP's TVT slot ;-- ... (the rest of the OS is below here) .END (c) Complete the entry in the OS's manual for the HELP function. This entry shows how to call HELP using the TRAP instruction. The TRAP instruction has a field to specify which TVT slot to use, the 8-bit "trapvect8" field. That 8-bit field is extended to 16 bits by appending 8 zeroes on its left end when the TRAP instruction is executed. Those 16 bits form the address of the TVT slot that TRAP accesses to get the jump pointer. LC3 OS Manual --- HELP Displays a message for the user that lists shell commands and how to use them. Usage: TRAP x ________ ----(2.a) Recall that at startup, memory intialization sets all memory words to h0000 before the OS boot program code is loaded at h0200. Explain what will happen if at boot time memory is as follows, address Memory content ------- ------------------ h0200 : 1111 0000 0000 0000 -----(2.b) Explain what will happen if after booting memory is as follows, address Memory content ------- ------------------ h0080 : 0000 0011 1000 0000 ... h0380 : 1111 0000 1000 0000 and PC = h0380. ----(3.) Consider this LC3 code: AND R0, R0, 0 ;--- R0 <=== 0 ADD R0, R0, x5 ;--- R0 <=== 5 LDR R7, R0, 0 ;--- R7 <=== Mem[ R0 ] JMP R7 ;--- call TRAP x5 Explain in what way this code is identical to TRAP x5, and in what way it differs. ----(4.a) Suppose the code for the HELP trap is as follows, HELP: ;-- This is a P&P assembly language "label", not an instruction. LEA R1, x5 ;-- R1 <=== address of local DataTable. LDR R0, R1, 0 ;-- R0 <=== 'A' TRAP x21 ;-- call OUT( R0 ), the character display service LDR R0, R1, 1 ;-- R0 <=== 'B' TRAP x21 ;-- call OUT( R0 ), the character display service JMP R7 ;-- return .FILL x0041 ;-- DataTable: ASCII 'A' .FILL x0042 ;-- DataTable: ASCII 'B' .FILL x0043 ;-- DataTable: ASCII 'C' TRAP x21 calls the function OUT(), which sends whatever is in R0 to the LC3's display device. Suppose we have also implemented the code for TRAP x21, and the TVT slots for both trap functions have been initialized at boot time. Do you see any potential problem that might occur in executing the last instruction of HELP? What is in R7? ----(4.b) Do you think we could rewrite the TRAP x21 function to avoid this problem? Make a suggestion. ----(4.c) Could we rewrite HELP to avoid any possibility of such a problem occurring? Make a suggestion. ----(5.) The LC4 does not have a system call instruction. However, it should be added to the LC4. Taking a clue from the fact that Linux only uses one TVT slot for all system calls; e.g., TRAP x80; we can easily implement system call functionality in the LC4. There are three things that need to be done in Electric to change your copy of the LC4, LC4-v1-base.jelib: (a) Add a read-only register to the LC4 that contains a permanent 16-bit address. This address will be the memory location that all system calls jump to. Make the address h1000. Put it to the left of the PC. (b) Add a 16-bit, 2X1 MUX to the PC's input. You can copy/paste the mux that feeds the PC's input. (You can rotate the new mux by selecting it and doing CTL-J or CMD-J.) Delete the bus nextPC[15:0] and attach the new mux's in0 to the original mux's out. Attach the new mux's out to PC's in. Attach the new mux's in1 to the output of you read-only register. Check that all your connections are actually connected. (c) The only thing left to do is detect when a system call instruction is the current instruction and set the new mux's select input accordingly. The Decode logic determines which instruction is executing. We could add a new column to Decode that controls the mux. It would have a 1 only for the opcode of our new instruction. This would be almost the same as Decode's BRR column. However, we can instead do it even more simply by extending our Decode logic externally to the Decode unit. We can add some simple logic that detects if the current opcode matches the opcode for our system call. This logic would feed 1 into the new mux's select when the instruction was a system call. At all other times it would feed a 0 to the select. Let's call our new instruction, SYS. Now we need to pick an opcode for it. In the LC4, we have already picked BRR to have opcode 1111; so, we cannot use the same opcode as LC3 uses. Let's pick another. The LC4 opcodes that are already being used are 0000, 0001, 0010, 0100, 1000, and 1111 (ALU, LIM, LDR, STR, LEA, and BRR). Let's pick 1110 to be our opcode for SYS. How can we detect that the current instruction, IR[15:0], is a SYS? Here's the logic written in verilog syntax that outputs a 1 if IR[15:12] == 4'b1110: sel = ( IR[15] & IR[14] ) & ( IR[13] & (~IR[12]) ) This uses just three two-input AND gates and a NOT gate. Drop in three AND gates and a buffer. Wire up the logic per the above with input wires named IR[15], IR[14] and so on, toggle the buffer's output to make it a NOT (select its ouput crosshair and do CTL-T). Attach the output wire to the new mux's sel select input. This will be the first step in completing your LC4 project. You will be implementing the other instructions by setting the bits in Decode.