Skip to content

Commit

Permalink
Added Memory Protection Unit
Browse files Browse the repository at this point in the history
Now the system includes a memory protection unit (initially inactive)
that is able to restrict the writing access into the memory map.
  • Loading branch information
parraman committed Feb 21, 2018
1 parent c9b4906 commit 9c47834
Show file tree
Hide file tree
Showing 6 changed files with 430 additions and 81 deletions.
44 changes: 23 additions & 21 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,28 +136,30 @@ export class AppComponent implements AfterViewInit {
'the value on the textual display.\n\n\tJMP start\n\tJMP isr\t\t; Interrupt ' +
'vector\n\tJMP svc\t\t; System call vector\n\nkeypressed:\t\t; 1 = key ' +
'pressed\n\tDB 0\t\t; 0 = No key pressed\n\nvalue:\t\t\t; The number of ' +
'the\n\tDB 0\t\t; key pressed in ASCII\n\nstart:\n\tMOV SP, 0x7F\t; Set ' +
'the\n\tDB 0\t\t; key pressed in ASCII\n\nstart:\n\tMOV SP, 0xFF\t; Set ' +
'Supervisor SP\n\tMOV A, 1\t\t; Set bit 0 of IRQMASK\n\tOUT 0\t\t\t; Unmask ' +
'keypad IRQ\n\tPUSH 0x0010\t\t; User Task SR: IRQMASK = 1\n\tPUSH 0x17F\t\t; ' +
'User Task SP = 0x17F\n\tPUSH task\t\t; User Task IP = task\n\tSRET\t\t\t; Jump ' +
'to user mode\n\tHLT\t\t\t\t; Parachute\n\nisr:\t\t\t\n\tPUSH A\t\t; Read the ' +
'key pressed\n\tIN 6\t\t; and store the ASCII\n\tADDB AL, 0x30\n\tMOVB [value], ' +
'AL\n\tMOVB AL, 1\n\tMOVB [keypressed], AL\n\tMOV A, 1\n\tOUT 2\t\t; Write to ' +
'signal IRQEOI\n\tPOP A\n\tIRET\n\nsvc:\t\t\t\t; Supervisor call\n\tCMP A, ' +
'0\t\t; A = syscall number\n\tJNZ .not0\t\t; 0 -> readchar\n\tCLI\n\tMOV A, ' +
'[keypressed]\t; Write vars\n\tPUSH B\t\t\t\t; with IRQs\n\tMOV B, 0\t\t\t; ' +
'disabled\n\tMOV [keypressed], B\n\tPOP B\n\tSTI\n\tJMP .return\n.not0:\n\tCMP ' +
'A, 1\t\t; 1 -> putchar\n\tJNZ .return\n\tMOVB [0x2F0], ' +
'BL\n.return:\n\tSRET\t\t\t; Return to user space\n\n\tORG 0x100\t; Following ' +
'instructions\n\t\t\t\t; will be assembled at 0x100\n\ntask:\t\t\t; The user ' +
'task\n\tMOV A, 0\n\tMOV B, 0\nloop:\n\tCALL readchar\t; Polls the ' +
'keypad\n\tCMPB AH, 1\t\t; using readchar\n\tJNZ loop\n\tMOVB BL, AL\t\t; If key ' +
'was pressed use\n\tCALL putchar\t; putchar to print it\n\tJMP loop ' +
'\n\nreadchar:\t\t; User space wrapper\n\tMOV A, 0\t; for readchar ' +
'syscall\n\tSVC\t\t\t; Syscall #0\n\tRET\t\t\t; A -> syscall ' +
'number\n\nputchar:\t\t; User space wrapper\n\tPUSH A\t\t; for putchar ' +
'syscall\n\tMOV A, 1\t; Syscall #1\n\tSVC\t\t\t; A -> syscall number\n\tPOP ' +
'A\t\t; BL -> char to print\n\tRET';
'keypad IRQ\n\tMOV A, 0x02EF\t; Set the end of the\n\tOUT 8\t\t\t; protection ' +
'to 0x02EF\n\tMOV A, 0x0109\t; Protection in seg. mode\n\tOUT 7\t\t\t; from ' +
'0x0100, S=1, U=0\n\tPUSH 0x0010\t\t; User Task SR: IRQMASK = 1\n\tPUSH ' +
'0x1FF\t\t; User Task SP = 0x1FF\n\tPUSH task\t\t; User Task IP = ' +
'task\n\tSRET\t\t\t; Jump to user mode\n\tHLT\t\t\t\t; ' +
'Parachute\n\nisr:\t\t\t\n\tPUSH A\t\t; Read the key pressed\n\tIN 6\t\t; and ' +
'store the ASCII\n\tADDB AL, 0x30\n\tMOVB [value], AL\n\tMOVB AL, 1\n\tMOVB ' +
'[keypressed], AL\n\tMOV A, 1\n\tOUT 2\t\t; Write to signal IRQEOI\n\tPOP ' +
'A\n\tIRET\n\nsvc:\t\t\t\t; Supervisor call\n\tCMP A, 0\t\t; A = syscall ' +
'number\n\tJNZ .not0\t\t; 0 -> readchar\n\tCLI\n\tMOV A, [keypressed]\t; Write ' +
'vars\n\tPUSH B\t\t\t\t; with IRQs\n\tMOV B, 0\t\t\t; disabled\n\tMOV ' +
'[keypressed], B\n\tPOP B\n\tSTI\n\tJMP .return\n.not0:\n\tCMP A, 1\t\t; 1 -> ' +
'putchar\n\tJNZ .return\n\tMOVB [0x2F0], BL\n.return:\n\tSRET\t\t\t; Return to ' +
'user space\n\n\tORG 0x100\t; Following instructions\n\t\t\t\t; will be ' +
'assembled at 0x100\n\ntask:\t\t\t; The user task\n\tMOV A, 0\n\tMOV B, ' +
'0\nloop:\n\tCALL readchar\t; Polls the keypad\n\tCMPB AH, 1\t\t; using ' +
'readchar\n\tJNZ loop\n\tMOVB BL, AL\t\t; If key was pressed use\n\tCALL ' +
'putchar\t; putchar to print it\n\tJMP loop \n\nreadchar:\t\t; User space ' +
'wrapper\n\tMOV A, 0\t; for readchar syscall\n\tSVC\t\t\t; Syscall ' +
'#0\n\tRET\t\t\t; A -> syscall number\n\nputchar:\t\t; User space ' +
'wrapper\n\tPUSH A\t\t; for putchar syscall\n\tMOV A, 1\t; Syscall ' +
'#1\n\tSVC\t\t\t; A -> syscall number\n\tPOP A\t\t; BL -> char to print\n\tRET';

public codeText = '';
private instance: any;
Expand Down
32 changes: 21 additions & 11 deletions src/app/cpu.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';

import { OpCode, OperandType, Instruction, instructionSet, InstructionSpec } from './instrset';
import { MemoryService } from './memory.service';
import { MemoryService, MemoryAccessActor } from './memory.service';
import { IORegMapService } from './ioregmap.service';
import { ClockService} from './clock.service';
import { Exception, ExceptionType } from './exceptions';
Expand Down Expand Up @@ -439,15 +439,17 @@ export class CPUService {
protected pushByte(value: number) {

const currentSP = this.SP.value;
this.memoryService.storeByte(currentSP, value);
this.memoryService.storeByte(currentSP, value,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
this.SP.pushByte();

}

protected pushWord(value: number) {

const currentSP = this.SP.value;
this.memoryService.storeWord(currentSP - 1, value);
this.memoryService.storeWord(currentSP - 1, value,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
this.SP.pushWord();

}
Expand Down Expand Up @@ -925,7 +927,8 @@ export class CPUService {
}

try {
this.memoryService.storeWord(toAddress, this.registersBank.get(fromRegister).value);
this.memoryService.storeWord(toAddress, this.registersBank.get(fromRegister).value,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand All @@ -946,7 +949,8 @@ export class CPUService {
}

try {
this.memoryService.storeWord(toAddress, this.registersBank.get(fromRegister).value);
this.memoryService.storeWord(toAddress, this.registersBank.get(fromRegister).value,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand Down Expand Up @@ -974,7 +978,8 @@ export class CPUService {
private instrMOV_WORD_TO_ADDRESS(toAddress: number, word: number): boolean {

try {
this.memoryService.storeWord(toAddress, word);
this.memoryService.storeWord(toAddress, word,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand All @@ -988,7 +993,8 @@ export class CPUService {
private instrMOV_WORD_TO_REGADDRESS(toAddress: number, word: number): boolean {

try {
this.memoryService.storeWord(toAddress, word);
this.memoryService.storeWord(toAddress, word,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand Down Expand Up @@ -1084,7 +1090,8 @@ export class CPUService {
const byteFromRegister = CPUService.getByteFrom8bitsGPR(fromRegister);

try {
this.memoryService.storeByte(toAddress, this.registersBank.get(fromRegister)[byteFromRegister]);
this.memoryService.storeByte(toAddress, this.registersBank.get(fromRegister)[byteFromRegister],
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand All @@ -1107,7 +1114,8 @@ export class CPUService {
const byteFromRegister = CPUService.getByteFrom8bitsGPR(fromRegister);

try {
this.memoryService.storeByte(toAddress, this.registersBank.get(fromRegister)[byteFromRegister]);
this.memoryService.storeByte(toAddress, this.registersBank.get(fromRegister)[byteFromRegister],
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand Down Expand Up @@ -1138,7 +1146,8 @@ export class CPUService {
private instrMOVB_BYTE_TO_ADDRESS(toAddress: number, byte: number): boolean {

try {
this.memoryService.storeByte(toAddress, byte);
this.memoryService.storeByte(toAddress, byte,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand All @@ -1152,7 +1161,8 @@ export class CPUService {
private instrMOVB_BYTE_TO_REGADDRESS(toAddress: number, byte: number): boolean {

try {
this.memoryService.storeByte(toAddress, byte);
this.memoryService.storeByte(toAddress, byte,
(this.SR.supervisor === 1 ? MemoryAccessActor.CPU_SUPERVISOR : MemoryAccessActor.CPU_USER));
} catch (e) {
throw new Exception(ExceptionType.MEMORY_ACCESS_ERROR,
e.message, this.IP.value, this.SP.value, this.SR.value, toAddress);
Expand Down

0 comments on commit 9c47834

Please sign in to comment.