Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 862aa35323
Fetching contributors…

Cannot retrieve contributors at this time

20437 lines (18605 sloc) 849.92 kB
#const.h#0000600010604300001450000000614011042123742012202 0ustar rvaliaveusers#ifndef CONST_H
#define CONST_H
#ifdef _RTX_EVAL_
#include "rtxeval_dummy.h"
#endif
#include "rtx_inc.h"
// Types of PROCESS_STATE
#define INVALID_PROCESS_STATE -1
#define READY 1 // Process on ready queue
#define MIN_PROCESS_STATE READY
#define RUNNING 2 // Process currently executing
#define BLOCKED_ON_MEMORY 3 // Process waiting for an envelope
#define BLOCKED_ON_MESSAGE 4 // Process waiting for another process's message
#define I_PROC 5 // Not running state for i_processes
#define MAX_PROCESS_STATE I_PROC
// Types of MESSAGE_TYPE
#define INVALID_MESSAGE_TYPE -1
#define KEYBOARD_INPUT 0
#define MIN_MESSAGE_TYPE KEYBOARD_INPUT
#define KCD_REGISTER 1
#define KCD_MSG 2
#define TEXT_MSG 3
#define MISC_MSG 4
#define CRT_DISPLAY 5
// for process C1
#define COUNT_REPORT 6
#define WAKEUP10 7
#define MAX_MESSAGE_TYPE WAKEUP10
// Process IDs
#define INVALID_PID -1
#define MIN_PID 1
// PIDs 1-6 reserved for testing processes
#define A1_PID 7
#define B1_PID 8
#define C1_PID 9
#define A2_PID 10
#define B2_PID 11
#define C2_PID 12
#define A3_PID 13
#define NULL_PROCESS_PID 14
#define KCD_PID 15
#define CRT_DISPLAY_PID 16
#define TIMER_I_PID 17
#define UART_I_PID 18
#define SPC_PID 19
#define WALL_CLOCK_PID 20
#define MAX_PID WALL_CLOCK_PID
// Misc
// me: success/error messages should have its own type
#define RTX_SUCCESS 0 // Code for successful procedure execution
#define RTX_ERROR -1
#define MEM_BLOCK_USED 1
#define MEM_BLOCK_UNUSED 0
#define INVALID_PRIORITY_LEVEL -1
#define PRIORITY_LEVEL_0 0
#define MIN_PRIORITY_LEVEL PRIORITY_LEVEL_0
#define PRIORITY_LEVEL_1 1
#define PRIORITY_LEVEL_2 2
#define PRIORITY_LEVEL_3 3
#define PRIORITY_LEVEL_4 4 // For null process only
#define MAX_PRIORITY_LEVEL PRIORITY_LEVEL_4
#define NUM_PRIORITY 5
#define ON 1
#define OFF 0
// current_primitive; used to decide which kernel level handler to call
#define SEND_MESSAGE_PRIMITIVE 1
#define RECEIVE_MESSAGE_PRIMITIVE 2
#define REQUEST_MEMORY_BLOCK_PRIMITIVE 3
#define RELEASE_MEMORY_BLOCK_PRIMITIVE 4
#define RELEASE_PROCESSOR_PRIMITIVE 5
#define DELAYED_SEND_PRIMITIVE 6
#define SET_PROCESS_PRIORITY_PRIMITIVE 7
#define GET_PROCESS_PRIORITY_PRIMITIVE 8
#define RTX_NORMAL 9
#define RTX_INIT 10
#define CONTEXT_SWITCH_TIMER 11
#define CONTEXT_SWITCH_UART 12
// "typedef"s
// The fields sender_process_id, destination_process_id and message_type are all of type int (me: hence PROCESS_ID and MESSAGE_TYPE are #define 'd as int
#define PRIORITY_LEVEL int
#define PROCESS_STATE int
#define PROCESS_ID int
#define SYSTIME int
#define MAX_SYSTIME 1000000
#define MESSAGE_TYPE int
#define ADDR_PTR void* // todo: find correct type and use name ADDR instead
#define BOOL BOOLEAN
#define DEFAULT_PCBCNT MAX_PID
#define DEFAULT_ENVLCNT 30
// system time has units of seconds
#define CLK_UNIT 1
BOOL is_valid_pid(PROCESS_ID in_pid);
BOOL is_valid_priority(PRIORITY_LEVEL in_plvl);
BOOL is_valid_state(PROCESS_STATE in_pstate);
BOOL is_valid_systime(SYSTIME in_time);
BOOL is_valid_message_type(MESSAGE_TYPE in_msgtype);
char* get_process_state_name(PROCESS_STATE in_state);
char* get_message_type_name(MESSAGE_TYPE in_msgtype);
#endif /* CONST_H */
#testproc.c#0000600010604300001450000002300711042123361012710 0ustar rvaliaveusers#include "testproc.h"
/*
#define A1_PID 7
#define B1_PID 8
#define C1_PID 9
#define A2_PID 10
#define B2_PID 11
#define C2_PID 12
#define A3_PID 13
*/
void process_a1() {
#ifdef DEBUG
rtx_dbug_outs("================================================\n\r");
rtx_dbug_outs("Entering process_a1\n\r");
#endif
register_command(*"Z");
#ifdef DEBUG
int i = 0;
//int j = 0;
#endif
envl* tmp_envl = NULL;
while(1) {
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A1] Checking for messages ( ");
rtx_dbug_out_int16(i++);
rtx_dbug_outs(" times run )\n\r");
#endif
tmp_envl = (envl*)receive_message(NULL);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A1] Message received from ");
rtx_dbug_outs(pcb_get_name(peek_pcb(envl_get_sender_id(tmp_envl))));
rtx_dbug_outs("\n\r");
#endif
// check if message contains "%Z"
char* tmp_msgtext = envl_get_msgtext(tmp_envl);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A1] tmp_envl msgtext = ");
rtx_dbug_outs(tmp_msgtext);
rtx_dbug_outs("\n\r");
#endif
if(tmp_msgtext[0] == 0x25 /* % */ &&
tmp_msgtext[1] == 0x5a /* Z */) {
release_memory_block(tmp_envl);
break;
}
else {
release_memory_block(tmp_envl);
}
}
int num = 0;
char buff[33]; // max num of digits in unsigned int +1
while(1) {
/*
#ifdef DEBUG
j++;
rtx_dbug_outs("process_a1 here2 = ");
rtx_dbug_out_int16(j);
rtx_dbug_outs("\n\r");
#endif
*/
tmp_envl = (envl*)request_memory_block();
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A1] Received requested memory block\n\r");
#endif
envl_set_message_type(tmp_envl, COUNT_REPORT);
itoa(num, buff, 10); // buff should be null terminated
envl_set_msgtext(tmp_envl, buff);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A1] tmp_envl msgtext = ");
rtx_dbug_outs(envl_get_msgtext(tmp_envl));
rtx_dbug_outs("\n\r");
#endif
envl_set_message_type(tmp_envl, MISC_MSG);
send_message(B1_PID, (void*)tmp_envl);
num = num +1;
release_processor();
}
}
void process_a2() {
register_command(*"Y");
#ifdef DEBUG
int i = 0;
//int j = 0;
#endif
envl* tmp_envl = NULL;
while(1) {
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A2] Checking for messages ( ");
rtx_dbug_out_int16(i++);
rtx_dbug_outs(" times run )\n\r");
#endif
tmp_envl = (envl*)receive_message(NULL);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A2] Message received from ");
rtx_dbug_outs(pcb_get_name(peek_pcb(envl_get_sender_id(tmp_envl))));
rtx_dbug_outs("\n\r");
#endif
// check if message contains "%Y"
char* tmp_msgtext = envl_get_msgtext(tmp_envl);
if(tmp_msgtext[0] == 0x25 /* % */ &&
tmp_msgtext[1] == 0x59 /* Y */) {
release_memory_block(tmp_envl);
break;
}
else {
release_memory_block(tmp_envl);
}
}
int num = 0;
char buff[33]; // max num of digits in unsigned int +1
while(1) {
tmp_envl = (envl*)request_memory_block();
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A2] Received requested memory block");
#endif
envl_set_message_type(tmp_envl, COUNT_REPORT);
itoa(num, buff, 10); // buff should be null terminated
envl_set_msgtext(tmp_envl, buff);
envl_set_message_type(tmp_envl, MISC_MSG);
send_message(B2_PID, (void*)tmp_envl);
num = num +1;
release_processor();
}
}
void process_a3() {
register_command(*"X");
#ifdef DEBUG
int i = 0;
//int j = 0;
#endif
envl* tmp_envl = NULL;
while(1) {
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A3] Checking for messages ( ");
rtx_dbug_out_int16(i++);
rtx_dbug_outs(" times run )\n\r");
#endif
tmp_envl = (envl*)receive_message(NULL);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A3] Message received from ");
rtx_dbug_outs(pcb_get_name(peek_pcb(envl_get_sender_id(tmp_envl))));
rtx_dbug_outs("\n\r");
#endif
// check if message contains "%X"
char* tmp_msgtext = envl_get_msgtext(tmp_envl);
if(tmp_msgtext[0] == 0x25 /* % */ &&
tmp_msgtext[1] == 0x58 /* X */) {
release_memory_block(tmp_envl);
break;
}
else {
release_memory_block(tmp_envl);
}
}
int num = 0;
char buff[33]; // max num of digits in unsigned int +1
while(1) {
tmp_envl = (envl*)request_memory_block();
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_A3] Received requested memory block");
#endif
envl_set_message_type(tmp_envl, COUNT_REPORT);
itoa(num, buff, 10); // buff should be null terminated
envl_set_msgtext(tmp_envl, buff);
envl_set_message_type(tmp_envl, MISC_MSG);
send_message(B2_PID, (void*)tmp_envl);
num = num +1;
release_processor();
}
}
void process_b1() {
while(1) {
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_B1] Checking for messages\n\r");
#endif
envl* tmp_envl = receive_message(NULL);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_B1] Got a message envelope. Now sending it to C1\n\r");
#endif
// envl should already have a message type set
send_message(C1_PID, (void*)tmp_envl);
}
}
void process_b2() {
while(1) {
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_B2] Checking for messages\n\r");
#endif
envl* tmp_envl = receive_message(NULL);
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_B2] Got a message envelope. Now sending it to C2\n\r");
#endif
// envl should already have a message type set
send_message(C2_PID, (void*)tmp_envl);
}
}
void process_c1() {
envl_deque local_msg_q;
local_msg_q.head = NULL;
local_msg_q.tail = NULL;
process_c1_local_msg_q_addr = &local_msg_q;
envl* tmp_envl = NULL;
while(1) {
//int is_envl_deque_empty(envl_deque* in_deque)
if(is_envl_deque_empty(&local_msg_q)) {
tmp_envl = (envl*)receive_message(NULL);
}
else {
tmp_envl = envl_dequeue(&local_msg_q);
}
if(envl_get_message_type(tmp_envl) == COUNT_REPORT) {
int tmp_num = atoi(envl_get_msgtext(tmp_envl)); // todo: ensure msgtext is null terminated
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_C1] tmp_num = ");
rtx_dbug_out_int10(tmp_num);
rtx_dbug_outs("\n\r");
#endif
if((tmp_num % 20) == 0) {
envl* tmp_envl2 = (envl*)request_memory_block();
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_C1] Received requested memory block\n\r");
#endif
envl_set_msgtext(tmp_envl2, "Process C");
envl_set_message_type(tmp_envl2, CRT_DISPLAY);
send_message(CRT_DISPLAY_PID, tmp_envl2);
// sleep for 10 seconds
tmp_envl = (envl*)request_memory_block();
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_C1] Received requested memory block\n\r");
#endif
envl_set_message_type(tmp_envl, WAKEUP10);
delayed_send(C1_PID, (void*)tmp_envl, 10000);
while(1) {
// block and let other processes execute
tmp_envl = (envl*)receive_message(NULL);
if(envl_get_message_type(tmp_envl) == WAKEUP10) {
break;
}
else {
envl_enque(tmp_envl, &local_msg_q);
}
}
}
}
release_memory_block(tmp_envl);
release_processor();
}
}
void process_c2() {
envl* tmp_envl2 = (envl*)request_memory_block();
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_C2] Received requested memory block\n\r");
#endif
envl_deque local_msg_q;
local_msg_q.head = NULL;
local_msg_q.tail = NULL;
process_c2_local_msg_q_addr = &local_msg_q;
envl* tmp_envl = NULL;
while(1) {
//int is_envl_deque_empty(envl_deque* in_deque)
if(is_envl_deque_empty(&local_msg_q)) {
tmp_envl = (envl*)receive_message(NULL);
}
else {
tmp_envl = envl_dequeue(&local_msg_q);
}
BOOL free = TRUE;
if(envl_get_message_type(tmp_envl) == COUNT_REPORT) {
int tmp_num = atoi(envl_get_msgtext(tmp_envl)); // todo: ensure msgtext is null terminated
#ifdef DEBUG
rtx_dbug_outs("[PROCESS_C2] tmp_num = ");
rtx_dbug_out_int10(tmp_num);
rtx_dbug_outs("\n\r");
#endif
if((tmp_num % 20) == 0) {
envl_set_msgtext(tmp_envl, "Process C");
envl_set_message_type(tmp_envl, CRT_DISPLAY);
send_message(CRT_DISPLAY_PID, tmp_envl);
free = FALSE;
// sleep for 10 seconds
tmp_envl2 = (envl*)request_memory_block();
envl_set_message_type(tmp_envl2, WAKEUP10);
delayed_send(C1_PID, (void*)tmp_envl2, 10000);
while(1) {
// block and let other processes execute
tmp_envl2 = (envl*)receive_message(NULL);
if(envl_get_message_type(tmp_envl2) == WAKEUP10) {
break;
}
else {
envl_enque(tmp_envl2, &local_msg_q);
}
}
}
}
if(free == TRUE) {
release_memory_block(tmp_envl);
}
release_processor();
}
}
#timer.c#0000600010604300001450000001307511042124523012172 0ustar rvaliaveusers#include "timer.h"
void c_timer_handler() {
// assuming the current_process is not an i-process, since i-processes are not supposed to be interruptable
#ifdef DEBUG_IPROC
rtx_dbug_outs("================================================\n\r");
rtx_dbug_outs("[TIMER_INTERRUPT_HANDLER] Entered...\n\r");
#endif
/*
#ifdef DEBUG
// set_process_priority(KCD_PID, PRIORITY_LEVEL_2);
set_priority_command_process(KCD_PID, PRIORITY_LEVEL_2);
rtx_dbug_outs(" Get priority should be 2, returned = ");
rtx_dbug_out_int16(get_process_priority(KCD_PID));
rtx_dbug_outs("\n\r");
// set_process_priority(KCD_PID, PRIORITY_LEVEL_3);
// rtx_dbug_outs(" Process reset back to priority ");
// rtx_dbug_out_int16(get_process_priority(KCD_PID));
// rtx_dbug_outs("\n\r");
#endif
*/
// process_switch(get_pcb(TIMER_I_PID));
// Attempt to Context switch
current_primitive = CONTEXT_SWITCH_TIMER;
asm("TRAP #6");
}
void timer_i_process() {
char cur_time[32];
while (1) {
// mask interrupts (enable atomic)
asm("move.w #0x2700,%SR");
#ifdef DEBUG_IPROC
rtx_dbug_outs("================================================\n\r");
rtx_dbug_outs("[TIMER] Entered...\n\r");
print_ready_queue();
print_blocked_on_receive_queue();
#endif
currtime += CLK_UNIT; // has units of second
delaytime += CLK_UNIT;
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] currtime = ");
rtx_dbug_out_int10(currtime);
rtx_dbug_outs("\n\r");
#endif
TIMER0_TER = 2;
if(!is_envl_deque_empty(delay_send_queue)) {
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] Something on delay_send_queue\n\r");
#endif
// check if it is time to send the message
envl* tmp_envl = envl_peek_head(delay_send_queue);
if(tmp_envl != NULL) {
// implies something on delay_send_queue
SYSTIME dtime = envl_get_delivery_time(tmp_envl);
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] delivery time = ");
rtx_dbug_out_int10(dtime);
rtx_dbug_outs("\n\r");
#endif
if(dtime <= delaytime) {
// is time to deliver
tmp_envl = dequeue_from_delay_send_queue();
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] destination process = ");
rtx_dbug_outs(pcb_get_name(peek_pcb(envl_get_destination_pid(tmp_envl))));
rtx_dbug_outs("\n\r");
#endif
delaySend = TRUE; //used to signal to send_message() to not change the original sender_pid
send_message(envl_get_destination_pid(tmp_envl), (void*)tmp_envl);
}
}
else {
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] Nothing on delay_send_queue\n\r");
#endif
// nothing to deliver, so exit
}
}
if(clock_state == TRUE){
// Incrememnt timer in WC
envl* envl_wall_clock = (envl*)request_memory_block();
envl_set_sender(envl_wall_clock,TIMER_I_PID);
send_message(WALL_CLOCK_PID,envl_wall_clock);
//int j = 0; Reusing LSD for J
/*
//cur_time[5] = 0x7B; // {
cur_time[5] = 0x30; // 0
// cur_time[6] = 0x39; // 9
cur_time[6] = 0x3B; //;
cur_time[7] = 0x32; // 2
cur_time[8] = 0x34; // 4
cur_time[9] = 0x48; // H
cur_time[10] = 0x1B; //Esc
cur_time[11] = 0x5B; //[
cur_time[12] = 0x31; //1
cur_time[13] = 0x4A; // K clear //cur_time[2] = 0x73; //s
cur_time[14] = 0x1B; //Esc
cur_time[15] = 0x5B; //[
cur_time[16] = 0x30; //0
cur_time[17] = 0x4A; // K clear //cur_time[2] = 0x73; //s
while(time!=0){
lsd = time % 10;
tmp_time[i] = "0123456789"[lsd];
time = time / 10; //remove current ones digit
i++;
}
lsd = 18;
while(i > 0){
cur_time[lsd] = tmp_time[i-1];
i--;
lsd++;
}
cur_time[lsd] = 0x0d; // CR
cur_time[++lsd] = 0x1B; //Esc
cur_time[++lsd] = 0x5B; //[
cur_time[++lsd] = 0x75; //restore
#ifdef DISPLAY_TIMER
rtx_dbug_outs("[UART] Requested memory block = ");
rtx_dbug_out_int16((UINT32)tmp_envl_send);
rtx_dbug_outs("\n\r");
rtx_dbug_outs("The Message of the envelope to CRT is \n\r");
rtx_dbug_out_int16((UINT16)tmp_time);
rtx_dbug_outs("\n\r");
#endif
envl_set_message_type(tmp_envl_send, CRT_DISPLAY);
envl_set_msgtext(tmp_envl_send, cur_time);
send_message(CRT_DISPLAY_PID, tmp_envl_send);
*/
}
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] Exiting...\n\r");
rtx_dbug_outs("================================================\n\r");
#endif
// current_primitive = RTX_NORMAL;
// unmask interrupts (disable atomic)
//asm("move.w #0x2000,%SR");
//asm("trap #6");
check_schedule();
}
#ifdef DEBUG_IPROC
rtx_dbug_outs("[TIMER] Should not reach here\n\r");
#endif
/*
current_primitive = RTX_NORMAL;
// unmask interrupts (disable atomic)
//asm("move.w #0x2000,%SR");
asm("trap #6");
*/
// return;
check_schedule();
}
Makefile0000600010604300001450000001371511042127010012233 0ustar rvaliaveusers# the output executable is: main.s19
CC=m68k-elf-gcc
CXX=m68k-elf-g++
CFLAGS=-O0 -Wall -m5200 -pipe -nostdlib
DBGFLAG=-DDEBUG
DBIPROCFLAG=-DDEBUG_IPROC
DBPROCMANFLAG=-DDEBUG_PROCMAN
DBHOTKEYS=-DDEBUG_HOTKEYS
DBKCDFLAGS=-DDBKCD
DBSPCFLAGS=-DDBSPC
DBPROCPRIFLAGS=-DDBPROCPRI
DBCRT=-DDEBUG_CRT
DBIPCFLAGS=-DDBIPC
DBWC=-DDEBUG_WALLCLOCK
DBALL=$(DBGFLAG) $(DBIPROCFLAG) $(DBPROCMANFLAG) $(DBHOTKEYS) $(DBKCDFLAGS) $(DBSPCFLAGS) $(DBPROCPRIFLAGS) $(DBCRT) $(DBWC)
TIMEDISPLAY=-DDISPLAY_TIMER
VT100=
ASMFLAGS=-Wall -nostdlib -m5200 -Tmcf5307.ld -S
LD=m68k-elf-gcc
AS=m68k-elf-as
AR=m68k-elf-ar
ARFLAGS=
OBJCPY=m68k-elf-objcopy
OBJDUMP=m68k-elf-objdump
ASM=start.s trap_entry.s timer_entry.s serial_entry.s
LDFLAGS = -Tmcf5307.ld -Wl,-Map=main.map
main-test: main.c
$(CC) $(CFLAGS) $(DBIPROCFLAG) $(LDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-time: main.c
$(CC) $(CFLAGS) $(DBCRT) $(DBIPROCFLAG) $(DBHOTKEYS) $(TIMEDISPLAY) $(DBWC) $(VT100) $(LDFLAGS) \
-o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-no-dbiproc: main.c
$(CC) $(CFLAGS) $(DBGFLAG) $(DBHOTKEYS) $(DBPROCMANFLAG) $(LDFLAGS) \
-o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-no-dbprocman: main.c
$(CC) $(CFLAGS) $(DBGFLAG) $(DBHOTKEYS) $(DBIPROCFLAG) $(LDFLAGS) \
-o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-no-db: main.c
$(CC) $(CFLAGS) $(LDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-only-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-kcd-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) $(DBKCDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-spc-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) $(DBPROCPRIFLAGS) $(DBSPCFLAGS) $(DBKCDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-procpri-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) $(DBPROCPRIFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-full: main.c
$(CC) $(CFLAGS) $(DBHOTKEYS) $(LDFLAGS) -o main.o $(ASM) main.c init.c const.c \
envl.c envl_deque.c pcb.c pcb_deque.c pcb_pdeque.c \
ipc.c mem.c func.c prim.c procpri.c crt.c nullproc.c procman.c \
timer.c kcd.c scheduler.c timesrv.c spc.c uart.c func.c mem.c \
wall_clock.c testproc.c
$(OBJCPY) --output-format=srec main.o main.s19
main-test-rtx: main.c
$(CC) $(CFLAGS) $(DBHOTKEYS) $(LDFLAGS) -D_RTX_EVAL_ \
-o main.o $(ASM) main.c outs.c rtx_eval1.o rtx_eval2.o rtx_eval3.o \
rtx_eval4.o init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c \
pcb.c pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
# rtxeval_dummy.c // since .o has this already (leads to multiple defintion error that no one can figure out)
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-rtx-db: main.c
$(CC) $(CFLAGS) $(DBALL) $(LDFLAGS) -D_RTX_EVAL_ \
-o main.o $(ASM) main.c outs.c rtx_eval1.o rtx_eval2.o rtx_eval3.o \
rtx_eval4.o init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c \
pcb.c pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
# rtxeval_dummy.c // since .o has this already (leads to multiple defintion error that no one can figure out)
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
clean:
cp start.s start.tmp
rm -f *.s19 *.o *.map *.txt
cp start.tmp start.s
rm start.tmp
Makefile~0000600010604300001450000001373411042126310012434 0ustar rvaliaveusers# the output executable is: main.s19
CC=m68k-elf-gcc
CXX=m68k-elf-g++
CFLAGS=-O0 -Wall -m5200 -pipe -nostdlib
DBGFLAG=-DDEBUG
DBIPROCFLAG=-DDEBUG_IPROC
DBPROCMANFLAG=-DDEBUG_PROCMAN
DBHOTKEYS=-DDEBUG_HOTKEYS
DBKCDFLAGS=-DDBKCD
DBSPCFLAGS=-DDBSPC
DBPROCPRIFLAGS=-DDBPROCPRI
DBCRT=-DDEBUG_CRT
DBIPCFLAGS=-DDBIPC
DBWC=-DDEBUG_WALLCLOCK
DBALL=$(DBGFLAG) $(DBIPROCFLAG) $(DBPROCMANFLAG) $(DBHOTKEYS) $(DBKCDFLAGS) $(DBSPCFLAGS) $(DBPROCPRIFLAGS) $(DBCRT) $(DBWC)
TIMEDISPLAY=-DDISPLAY_TIMER
VT100=
ASMFLAGS=-Wall -nostdlib -m5200 -Tmcf5307.ld -S
LD=m68k-elf-gcc
AS=m68k-elf-as
AR=m68k-elf-ar
ARFLAGS=
OBJCPY=m68k-elf-objcopy
OBJDUMP=m68k-elf-objdump
ASM=start.s trap_entry.s timer_entry.s serial_entry.s
LDFLAGS = -Tmcf5307.ld -Wl,-Map=main.map
main-test: main.c
$(CC) $(CFLAGS) $(DBIPROCFLAG) $(LDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-time: main.c
$(CC) $(CFLAGS) $(DBCRT) $(DBIPROCFLAG) $(DBHOTKEYS) $(TIMEDISPLAY) $(DBWC) $(VT100) $(LDFLAGS) \
-o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-no-dbiproc: main.c
$(CC) $(CFLAGS) $(DBGFLAG) $(DBHOTKEYS) $(DBPROCMANFLAG) $(LDFLAGS) \
-o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-no-dbprocman: main.c
$(CC) $(CFLAGS) $(DBGFLAG) $(DBHOTKEYS) $(DBIPROCFLAG) $(LDFLAGS) \
-o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-no-db: main.c
$(CC) $(CFLAGS) $(LDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-only-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-kcd-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) $(DBKCDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-spc-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) $(DBPROCPRIFLAGS) $(DBSPCFLAGS) $(DBKCDFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-procpri-hotkeys: main.c
$(CC) $(CFLAGS) $(LDFLAGS) $(DBHOTKEYS) $(DBPROCPRIFLAGS) -o main.o $(ASM) main.c outs.c \
init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c pcb.c \
pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-full: main.c
$(CC) $(CFLAGS) $(DBHOTKEYS) $(LDFLAGS) -o main.o $(ASM) main.c init.c const.c \
envl.c envl_deque.c pcb.c pcb_deque.c pcb_pdeque.c \
ipc.c mem.c func.c prim.c procpri.c crt.c nullproc.c procman.c \
timer.c kcd.c scheduler.c timesrv.c spc.c uart.c func.c mem.c \
wall_clock.c testproc.c
$(OBJCPY) --output-format=srec main.o main.s19
main-test-rtx: main.c
$(CC) $(CFLAGS) $(DBHOTKEYS) $(DBIPROCFLAG) $(LDFLAGS) -D_RTX_EVAL_ \
-o main.o $(ASM) main.c outs.c rtx_eval1.o rtx_eval2.o rtx_eval3.o \
rtx_eval4.o init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c \
pcb.c pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
# rtxeval_dummy.c // since .o has this already (leads to multiple defintion error that no one can figure out)
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
main-test-rtx-db: main.c
$(CC) $(CFLAGS) $(DBALL) $(LDFLAGS) -D_RTX_EVAL_ \
-o main.o $(ASM) main.c outs.c rtx_eval1.o rtx_eval2.o rtx_eval3.o \
rtx_eval4.o init.c const.c envl_deque.c func.c envl.c pcb_pdeque.c \
pcb.c pcb_deque.c scheduler.c procman.c mem.c nullproc.c \
swi.c ipc.c procpri.c timesrv.c uart.c wall_clock.c testproc.c \
timer.c crt.c kcd.c spc.c
# rtxeval_dummy.c // since .o has this already (leads to multiple defintion error that no one can figure out)
$(OBJCPY) --output-format=srec main.o main.s19
$(OBJDUMP) -D main.o > list.txt
clean:
cp start.s start.tmp
rm -f *.s19 *.o *.map *.txt
cp start.tmp start.s
rm start.tmp
const.c0000600010604300001450000000272711042040433012071 0ustar rvaliaveusers#include "const.h"
BOOL is_valid_pid(PROCESS_ID in_pid) {
return !(in_pid < MIN_PID || in_pid > MAX_PID);
}
BOOL is_valid_priority(PRIORITY_LEVEL in_plvl) {
return !(in_plvl < MIN_PRIORITY_LEVEL || in_plvl > MAX_PRIORITY_LEVEL);
}
BOOL is_valid_state(PROCESS_STATE in_pstate) {
return !(in_pstate < MIN_PROCESS_STATE || in_pstate > MAX_PROCESS_STATE);
}
BOOL is_valid_systime(SYSTIME in_time) {
return (in_time >= 0 && in_time < MAX_SYSTIME);
}
BOOL is_valid_message_type(MESSAGE_TYPE in_msgtype) {
return !(in_msgtype < MIN_MESSAGE_TYPE || in_msgtype > MAX_MESSAGE_TYPE);
}
char* get_process_state_name(PROCESS_STATE in_state) {
switch(in_state) {
case READY: return "ready"; break;
case RUNNING: return "running"; break;
case BLOCKED_ON_MEMORY: return "blocked on memory"; break;
case BLOCKED_ON_MESSAGE: return "blocked on message"; break;
case I_PROC: return "i-proc"; break;
default: return "unknown"; break;
}
}
char* get_message_type_name(MESSAGE_TYPE in_msgtype) {
switch(in_msgtype) {
case KEYBOARD_INPUT: return "keyboard input"; break;
case KCD_REGISTER: return "kcd register"; break;
case KCD_MSG: return "kcd msg"; break;
case TEXT_MSG: return "text msg"; break;
case MISC_MSG: return "misc msg"; break;
case CRT_DISPLAY: return "crt display"; break;
case COUNT_REPORT: return "count report"; break;
case WAKEUP10: return "wakeup10"; break;
default: return "unknown"; break;
}
}
const.h0000600010604300001450000000613311042125211012067 0ustar rvaliaveusers#ifndef CONST_H
#define CONST_H
#ifdef _RTX_EVAL_
#include "rtxeval_dummy.h"
#endif
#include "rtx_inc.h"
// Types of PROCESS_STATE
#define INVALID_PROCESS_STATE -1
#define READY 1 // Process on ready queue
#define MIN_PROCESS_STATE READY
#define RUNNING 2 // Process currently executing
#define BLOCKED_ON_MEMORY 3 // Process waiting for an envelope
#define BLOCKED_ON_MESSAGE 4 // Process waiting for another process's message
#define I_PROC 5 // Not running state for i_processes
#define MAX_PROCESS_STATE I_PROC
// Types of MESSAGE_TYPE
#define INVALID_MESSAGE_TYPE -1
#define KEYBOARD_INPUT 0
#define MIN_MESSAGE_TYPE KEYBOARD_INPUT
#define KCD_REGISTER 1
#define KCD_MSG 2
#define TEXT_MSG 3
#define MISC_MSG 4
#define CRT_DISPLAY 5
// for process C1
#define COUNT_REPORT 6
#define WAKEUP10 7
#define MAX_MESSAGE_TYPE WAKEUP10
// Process IDs
#define INVALID_PID -1
#define MIN_PID 1
// PIDs 1-6 reserved for testing processes
#define A1_PID 7
#define B1_PID 8
#define C1_PID 9
#define A2_PID 10
#define B2_PID 11
#define C2_PID 12
#define A3_PID 13
#define NULL_PROCESS_PID 14
#define KCD_PID 15
#define CRT_DISPLAY_PID 16
#define TIMER_I_PID 17
#define UART_I_PID 18
#define SPC_PID 19
#define WALL_CLOCK_PID 20
#define MAX_PID WALL_CLOCK_PID
// Misc
// me: success/error messages should have its own type
#define RTX_SUCCESS 0 // Code for successful procedure execution
#define RTX_ERROR -1
#define MEM_BLOCK_USED 1
#define MEM_BLOCK_UNUSED 0
#define INVALID_PRIORITY_LEVEL -1
#define PRIORITY_LEVEL_0 0
#define MIN_PRIORITY_LEVEL PRIORITY_LEVEL_0
#define PRIORITY_LEVEL_1 1
#define PRIORITY_LEVEL_2 2
#define PRIORITY_LEVEL_3 3
#define PRIORITY_LEVEL_4 4 // For null process only
#define MAX_PRIORITY_LEVEL PRIORITY_LEVEL_4
#define NUM_PRIORITY 5
#define ON 1
#define OFF 0
// current_primitive; used to decide which kernel level handler to call
#define SEND_MESSAGE_PRIMITIVE 1
#define RECEIVE_MESSAGE_PRIMITIVE 2
#define REQUEST_MEMORY_BLOCK_PRIMITIVE 3
#define RELEASE_MEMORY_BLOCK_PRIMITIVE 4
#define RELEASE_PROCESSOR_PRIMITIVE 5
#define DELAYED_SEND_PRIMITIVE 6
#define SET_PROCESS_PRIORITY_PRIMITIVE 7
#define GET_PROCESS_PRIORITY_PRIMITIVE 8
#define RTX_NORMAL 9
#define RTX_INIT 10
#define CONTEXT_SWITCH_TIMER 11
#define CONTEXT_SWITCH_UART 12
// "typedef"s
// The fields sender_process_id, destination_process_id and message_type are all of type int (me: hence PROCESS_ID and MESSAGE_TYPE are #define 'd as int
#define PRIORITY_LEVEL int
#define PROCESS_STATE int
#define PROCESS_ID int
#define SYSTIME int
#define MAX_SYSTIME 1000000
#define MESSAGE_TYPE int
#define ADDR_PTR void* // todo: find correct type and use name ADDR instead
#define BOOL BOOLEAN
#define DEFAULT_PCBCNT MAX_PID
#define DEFAULT_ENVLCNT 35
// system time has units of seconds
#define CLK_UNIT 1
BOOL is_valid_pid(PROCESS_ID in_pid);
BOOL is_valid_priority(PRIORITY_LEVEL in_plvl);
BOOL is_valid_state(PROCESS_STATE in_pstate);
BOOL is_valid_systime(SYSTIME in_time);
BOOL is_valid_message_type(MESSAGE_TYPE in_msgtype);
char* get_process_state_name(PROCESS_STATE in_state);
char* get_message_type_name(MESSAGE_TYPE in_msgtype);
#endif /* CONST_H */
const.h~0000600010604300001450000000613311042064745012303 0ustar rvaliaveusers#ifndef CONST_H
#define CONST_H
#ifdef _RTX_EVAL_
#include "rtxeval_dummy.h"
#endif
#include "rtx_inc.h"
// Types of PROCESS_STATE
#define INVALID_PROCESS_STATE -1
#define READY 1 // Process on ready queue
#define MIN_PROCESS_STATE READY
#define RUNNING 2 // Process currently executing
#define BLOCKED_ON_MEMORY 3 // Process waiting for an envelope
#define BLOCKED_ON_MESSAGE 4 // Process waiting for another process's message
#define I_PROC 5 // Not running state for i_processes
#define MAX_PROCESS_STATE I_PROC
// Types of MESSAGE_TYPE
#define INVALID_MESSAGE_TYPE -1
#define KEYBOARD_INPUT 0
#define MIN_MESSAGE_TYPE KEYBOARD_INPUT
#define KCD_REGISTER 1
#define KCD_MSG 2
#define TEXT_MSG 3
#define MISC_MSG 4
#define CRT_DISPLAY 5
// for process C1
#define COUNT_REPORT 6
#define WAKEUP10 7
#define MAX_MESSAGE_TYPE WAKEUP10
// Process IDs
#define INVALID_PID -1
#define MIN_PID 1
// PIDs 1-6 reserved for testing processes
#define A1_PID 7
#define B1_PID 8
#define C1_PID 9
#define A2_PID 10
#define B2_PID 11
#define C2_PID 12
#define A3_PID 13
#define NULL_PROCESS_PID 14
#define KCD_PID 15
#define CRT_DISPLAY_PID 16
#define TIMER_I_PID 17
#define UART_I_PID 18
#define SPC_PID 19
#define WALL_CLOCK_PID 20
#define MAX_PID WALL_CLOCK_PID
// Misc
// me: success/error messages should have its own type
#define RTX_SUCCESS 0 // Code for successful procedure execution
#define RTX_ERROR -1
#define MEM_BLOCK_USED 1
#define MEM_BLOCK_UNUSED 0
#define INVALID_PRIORITY_LEVEL -1
#define PRIORITY_LEVEL_0 0
#define MIN_PRIORITY_LEVEL PRIORITY_LEVEL_0
#define PRIORITY_LEVEL_1 1
#define PRIORITY_LEVEL_2 2
#define PRIORITY_LEVEL_3 3
#define PRIORITY_LEVEL_4 4 // For null process only
#define MAX_PRIORITY_LEVEL PRIORITY_LEVEL_4
#define NUM_PRIORITY 5
#define ON 1
#define OFF 0
// current_primitive; used to decide which kernel level handler to call
#define SEND_MESSAGE_PRIMITIVE 1
#define RECEIVE_MESSAGE_PRIMITIVE 2
#define REQUEST_MEMORY_BLOCK_PRIMITIVE 3
#define RELEASE_MEMORY_BLOCK_PRIMITIVE 4
#define RELEASE_PROCESSOR_PRIMITIVE 5
#define DELAYED_SEND_PRIMITIVE 6
#define SET_PROCESS_PRIORITY_PRIMITIVE 7
#define GET_PROCESS_PRIORITY_PRIMITIVE 8
#define RTX_NORMAL 9
#define RTX_INIT 10
#define CONTEXT_SWITCH_TIMER 11
#define CONTEXT_SWITCH_UART 12
// "typedef"s
// The fields sender_process_id, destination_process_id and message_type are all of type int (me: hence PROCESS_ID and MESSAGE_TYPE are #define 'd as int
#define PRIORITY_LEVEL int
#define PROCESS_STATE int
#define PROCESS_ID int
#define SYSTIME int
#define MAX_SYSTIME 1000000
#define MESSAGE_TYPE int
#define ADDR_PTR void* // todo: find correct type and use name ADDR instead
#define BOOL BOOLEAN
#define DEFAULT_PCBCNT MAX_PID
#define DEFAULT_ENVLCNT 30
// system time has units of seconds
#define CLK_UNIT 1
BOOL is_valid_pid(PROCESS_ID in_pid);
BOOL is_valid_priority(PRIORITY_LEVEL in_plvl);
BOOL is_valid_state(PROCESS_STATE in_pstate);
BOOL is_valid_systime(SYSTIME in_time);
BOOL is_valid_message_type(MESSAGE_TYPE in_msgtype);
char* get_process_state_name(PROCESS_STATE in_state);
char* get_message_type_name(MESSAGE_TYPE in_msgtype);
#endif /* CONST_H */
crt.c0000600010604300001450000000647611042107612011543 0ustar rvaliaveusers#include "crt.h"
void crt_display() {
/*
envl* message_display;
char* message_display_start;
char* vt100_msg;
char* vt100_msg_start;
int i = 0;
vt100_msg_start = '\0';
char_cat(ESC, vt100_msg_start);
str_cat("[1;1H", vt100_msg_start);
str_cat("RAWKOS", vt100_msg_start);
char_cat(ESC, vt100_msg_start);
str_cat("[2;1H", vt100_msg_start);
for (i = 0; i < 80; i++) char_cat('-', vt100_msg_start);
char_cat(ESC, vt100_msg_start);
str_cat("[23;1H", vt100_msg_start);
for (i = 0; i < 80; i++) char_cat('-', vt100_msg_start);
// sets up scroll region
char_cat(ESC, vt100_msg_start);
str_cat("[3;22r", vt100_msg_start);
// move cursor to line 3
char_cat(ESC, vt100_msg_start);
str_cat("[3;1H", vt100_msg_start);
while (vt100_msg_start[i] != '\0')
{
message_display = (envl*)request_memory_block();
*message_display_start = *vt100_msg_start;
send_message (UART_IPROCESS_ID, message_display); // we are sending character by character out to the UART process
SERIAL1_IMR = 3;
i++;
} */
//splash_screen();
while(1) {
#ifdef DEBUG
rtx_dbug_outs("[CRT_DISPLAY] Entering...\n\r");
rtx_dbug_outs("[CRT_DISPLAY] Calling receive_message()\n\r");
#endif
envl* tmp_envl = (envl*)receive_message(NULL);
#ifdef DEBUG
rtx_dbug_outs("[CRT_DISPLAY] Received message envelope = ");
rtx_dbug_out_int16((UINT32)tmp_envl);
rtx_dbug_outs("\n\r");
#endif
// ensure message received intended for CRT_DISPLAY
if(tmp_envl != NULL && envl_get_message_type(tmp_envl) == CRT_DISPLAY) {
// send message to UART to display it on the screen
#ifdef DEBUG_CRT
rtx_dbug_outs("[CRT_DISPLAY] Sending message to UART\n\r");
#endif
char* msg = envl_get_msgtext(tmp_envl);
char* msg_start = msg;
while (*msg_start != 0x00) {
char tmp_array[2];
tmp_array[0] = *msg_start;
tmp_array[1] = 0x00;
envl* forward = (envl*)request_memory_block();
envl_set_msgtext(forward, tmp_array);
envl_set_message_type(forward,CRT_DISPLAY);
send_message(UART_I_PID,forward);
SERIAL1_IMR = 0x03;
msg_start++;
}
#ifdef DEBUG_CRT
rtx_dbug_outs("[CRT_DISPLAY] REACHED NULL TERMINATION\n\r");
#endif
release_memory_block((void*)tmp_envl);
// release_memory_block(msg);
//send_message(UART_I_PID,tmp_envl);
#ifdef DEBUG_CRT
rtx_dbug_outs("[CRT_DISPLAY] Message sent to UART\n\r");
#endif
// enable UART interrupt mask register
SERIAL1_IMR = 0x03;
}
else {
// release anything that is not a CRT_DISPLAY message
release_memory_block(tmp_envl);
#ifdef DEBUG_CRT
rtx_dbug_outs("[CRT_DISPLAY] Memory block released\n\r");
#endif
}
}
}
/*
void splash_screen() {
envl* splash_envl = (envl*)request_memory_block();
char* splash_msg;
splash_msg[0] = '\0';
str_cat("RAWKOS",splash_msg);
envl_set_message_type(splash_msg, CRT_DISPLAY);
envl_set_msgtext(splash_envl,splash_msg);
send_message(CRT_DISPLAY_PID,splash_envl);
}
*/
crt.h0000600010604300001450000000017711042040435011537 0ustar rvaliaveusers#ifndef CRT_H
#define CRT_H
#include "globalvar.h"
#include "ipc.h"
#include "mem.h"
void crt_display();
#endif /* CRT_H */
envl.c0000600010604300001450000000640111042040435011702 0ustar rvaliaveusers#include "envl.h"
// Responsibility for checking if in_envl == NULL left to the caller
// This function does not clear the next and prev pointers because they are not part of the envelope, per-se; they are part of the envl_deque.
int envl_clear(envl* in_envl) {
if(in_envl != NULL) {
in_envl->sender_pid = INVALID_PID;
in_envl->destination_pid = INVALID_PID;
in_envl->msg_type = INVALID_MESSAGE_TYPE;
in_envl->sent_time = 0; // -1; // to reduce space in print out
in_envl->delivery_time = 0; // -1;
in_envl->reserved[0] = '\0';
in_envl->msgtext[0] = '\0';
}
return RTX_SUCCESS;
}
int envl_set_sender(envl* env, PROCESS_ID sender_pid) {
if(!is_valid_pid(sender_pid) || env == NULL) {
return RTX_ERROR;
}
env->sender_pid = sender_pid;
return RTX_SUCCESS;
}
int envl_set_destination(envl* env, PROCESS_ID destination_pid) {
if(!is_valid_pid(destination_pid) || env == NULL) {
return RTX_ERROR;
}
env->destination_pid = destination_pid;
return RTX_SUCCESS;
}
int envl_set_sent_time(envl* in_envl, SYSTIME in_stime) {
if(in_envl == NULL || !is_valid_systime(in_stime)) {
return RTX_ERROR;
}
in_envl->sent_time = in_stime;
return RTX_SUCCESS;
}
int envl_set_delivery_time(envl* in_envl, SYSTIME in_dtime) {
if(in_envl == NULL || !is_valid_systime(in_dtime)) {
return RTX_ERROR;
}
in_envl->delivery_time = in_dtime;
return RTX_SUCCESS;
}
int envl_set_message_type(envl* env, MESSAGE_TYPE msg_type) {
if(env == NULL || !is_valid_message_type(msg_type)) {
return RTX_ERROR;
}
env->msg_type = msg_type;
return RTX_SUCCESS;
}
PROCESS_ID envl_get_sender_id(envl* in_envl) {
if(in_envl == NULL) {
return RTX_ERROR;
}
return in_envl->sender_pid;
}
MESSAGE_TYPE envl_get_message_type(envl* in_envl) {
if(in_envl == NULL) {
return RTX_ERROR;
}
return in_envl->msg_type;
}
PROCESS_ID envl_get_destination_pid(envl* in_envl) {
if(in_envl == NULL) {
return RTX_ERROR;
}
return in_envl->destination_pid;
}
SYSTIME envl_get_sent_time(envl* in_envl) {
if(in_envl == NULL) {
return RTX_ERROR;
}
return in_envl->sent_time;
}
SYSTIME envl_get_delivery_time(envl* in_envl) {
if(in_envl == NULL) {
return RTX_ERROR;
}
return in_envl->delivery_time;
}
char* envl_get_msgtext(envl* in_envl) {
if(in_envl == NULL) {
return NULL;
}
return in_envl->msgtext;
}
int envl_print(envl* in_envl) {
if(in_envl == NULL) {
return RTX_ERROR;
}
rtx_dbug_outs("sender: ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_envl->sender_pid)));
rtx_dbug_outs("; ");
rtx_dbug_outs("dest: ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_envl->destination_pid)));
rtx_dbug_outs("; ");
rtx_dbug_outs("msgtype: ");
rtx_dbug_outs(get_message_type_name(in_envl->msg_type));
rtx_dbug_outs("; ");
rtx_dbug_outs("sent: ");
rtx_dbug_out_int10(in_envl->sent_time);
rtx_dbug_outs("; ");
rtx_dbug_outs("deliv: ");
rtx_dbug_out_int10(in_envl->delivery_time);
rtx_dbug_outs("; ");
rtx_dbug_outs("msgtext: \"");
rtx_dbug_outs(in_envl->msgtext);
rtx_dbug_outs("\"\n\r");
return RTX_SUCCESS;
}
envl.h0000600010604300001450000000350611042040435011712 0ustar rvaliaveusers#ifndef ENVL_H
#define ENVL_H
#include "const.h"
#include "outs.h"
#define ENVL_RESERVED_SIZE 32
#define ENVL_MSGTEXT_SIZE 64
typedef struct envl {
// message header
// 32 bytes
struct envl* next; // used to build message deque
struct envl* prev;
PROCESS_ID sender_pid;
PROCESS_ID destination_pid;
MESSAGE_TYPE msg_type;
SYSTIME sent_time;
SYSTIME delivery_time; // indicates when this message should be received (for delayed_send())
/*
"Test processes will use an offset of 64-bytes from the pointer (to a
message envelope) and use that area (within the message text) for inter
test process communication. So, none of your primitives should modify
this message text area while handling a message envelope
(i.e. deallocate, allocate, delay, etc.). This area, within the message
text, is only used by the test processes while they "own" an
envelope. Of course, your own processes can do anything they want with
this area when they "own" an envelope.
"
*/
// message text
// 96 bytes
char reserved[ENVL_RESERVED_SIZE];
char msgtext[ENVL_MSGTEXT_SIZE];
} envl;
int envl_clear(envl* in_envl);
int envl_set_sender(envl* env, PROCESS_ID sender_pid);
int envl_set_destination(envl* env, PROCESS_ID destination_pid);
int envl_set_sent_time(envl* in_envl, SYSTIME in_stime);
int envl_set_delivery_time(envl* in_envl, SYSTIME in_dtime);
int envl_set_message_type(envl* env, MESSAGE_TYPE msg_type);
//int envl_set_msgtext(envl* in_envl, char* in_msgtext); // moved to func.c
PROCESS_ID envl_get_sender_id(envl* in_envl);
MESSAGE_TYPE envl_get_message_type(envl* in_envl);
PROCESS_ID envl_get_destination_pid(envl* in_envl);
SYSTIME envl_get_sent_time(envl* in_envl);
SYSTIME envl_get_delivery_time(envl* in_envl);
char* envl_get_msgtext(envl* in_envl);
int envl_print(envl* in_envl);
#endif /* ENVL_H */
envl_deque.c0000600010604300001450000002160211042040435013065 0ustar rvaliaveusers#include "envl_deque.h"
envl* envl_dequeue_head(envl_deque* in_deque) {
if(in_deque == NULL) {
return NULL;
}
if(is_envl_deque_empty(in_deque)) {
return NULL; // dequeueing from an empty deque returns a NULL
}
// only 1 element on queue
if(in_deque->head == in_deque->tail) {
envl* curr = in_deque->head;
curr->next = NULL;
curr->prev = NULL;
in_deque->head = NULL;
in_deque->tail = NULL;
return curr;
}
// >1 element on queue
envl* curr = in_deque->head;
curr->next->prev = NULL;
in_deque->head = curr->next;
curr->next = NULL;
return curr;
}
envl* envl_dequeue_tail(envl_deque* in_deque) {
if(in_deque == NULL) {
return NULL;
}
if(is_envl_deque_empty(in_deque)) {
return NULL; // dequeueing from an empty deque returns a NULL
}
// only 1 element on queue
if(in_deque->head == in_deque->tail) {
envl* curr = in_deque->tail;
curr->next = NULL;
curr->prev = NULL;
in_deque->head = NULL;
in_deque->tail = NULL;
return curr; // element now dequeued
}
// >1 element on queue
envl* curr = in_deque->tail;
curr->prev->next = NULL;
in_deque->tail = curr->prev;
curr->prev = NULL;
return curr;
}
int envl_enque_head(envl* in_envl, envl_deque* in_deque) {
if(in_deque == NULL) {
return RTX_ERROR;
}
if(in_envl == NULL) {
return RTX_ERROR;
}
// if both are NULL, xnor both are not NULL
if((in_deque->head == NULL && in_deque->tail == NULL) ==
(in_deque->head != NULL && in_deque->tail != NULL)) {
return RTX_ERROR;
}
// either both NULL, xor neither NULL
// H and T point to nothing (empty deque)
if(in_deque->head == NULL && in_deque->tail == NULL) {
in_deque->head = in_envl;
in_deque->tail = in_envl;
in_envl->next = NULL;
in_envl->prev = NULL;
return RTX_SUCCESS;
}
// H and T point to same envl (only one element in deque)
if(in_deque->head == in_deque->tail) {
if(in_deque->tail == NULL) {
return RTX_ERROR;
}
envl* curr = in_deque->head;
// Element should not be pointing to anything, whether forward or back
if(curr->next != NULL || curr->prev != NULL) {
// me: likely an error
}
in_envl->next = curr;
curr->prev = in_envl;
in_deque->head = in_envl;
in_envl->prev = NULL;
curr->next = NULL;
return RTX_SUCCESS;
}
// H and T point to different envls (>=2 elements on deque)
if(in_deque->head != in_deque->tail) {
envl* curr = in_deque->head;
curr->prev = in_envl;
in_envl->next = curr;
in_deque->head = in_envl;
in_envl->prev = NULL;
return RTX_SUCCESS;
}
return RTX_ERROR; // shouldn't reach here
}
int envl_enque_tail(envl* in_envl, envl_deque* in_deque) {
if(in_deque == NULL) {
return RTX_ERROR;
}
if(in_envl == NULL) {
return RTX_ERROR;
}
// if both are NULL, xnor both are not NULL
if((in_deque->head == NULL && in_deque->tail == NULL) ==
(in_deque->head != NULL && in_deque->tail != NULL)) {
return RTX_ERROR;
}
// either both NULL, xor neither NULL
// H and T point to nothing (empty deque)
if(in_deque->head == NULL && in_deque->tail == NULL) {
in_deque->head = in_envl;
in_deque->tail = in_envl;
in_envl->next = NULL;
in_envl->prev = NULL;
return RTX_SUCCESS;
}
// H and T point to same envl (only one element in deque)
if(in_deque->head == in_deque->tail) {
if(in_deque->tail == NULL) {
return RTX_ERROR;
}
envl* curr = in_deque->tail;
// Element should not be pointing to anything, whether forward or back
if(curr->next != NULL || curr->prev != NULL) {
// me: likely an error
}
curr->next = in_envl;
in_envl->prev = curr;
in_deque->tail = in_envl;
in_envl->next = NULL;
curr->prev = NULL;
return RTX_SUCCESS;
}
// H and T point to different envl (>=2 elements on deque)
if(in_deque->head != in_deque->tail) {
envl* curr = in_deque->tail;
curr->next = in_envl;
in_envl->prev = curr;
in_deque->tail = in_envl;
in_envl->next = NULL;
return RTX_SUCCESS;
}
return RTX_ERROR; // shouldn't reach here
}
envl* envl_get_deque_head(envl_deque* in_deque) {
if(in_deque == NULL) {
return NULL;
}
return in_deque->head;
}
envl* envl_get_deque_tail(envl_deque* in_deque) {
if(in_deque == NULL) {
return NULL;
}
return in_deque->tail;
}
// Present deque as a queue
int envl_enque(envl* in_envl, envl_deque* in_deque) {
return envl_enque_tail(in_envl, in_deque);
}
envl* envl_dequeue(envl_deque* in_deque) {
return envl_dequeue_head(in_deque);
}
int is_envl_deque_empty(envl_deque* in_deque) {
if(in_deque == NULL) {
return RTX_ERROR;
}
return in_deque->head == NULL && in_deque->tail == NULL ? TRUE : FALSE;
}
envl* envl_dequeue_by_sender_pid(envl_deque* in_deque, PROCESS_ID in_pid) {
if(in_deque == NULL || !is_valid_pid(in_pid)) {
return NULL;
}
envl* env = in_deque->head;
while(env != NULL) {
if(env->sender_pid == in_pid) {
return env;
}
else {
env = env->next;
}
}
return NULL;
}
int envl_enque_by_delivery_time(envl_deque* in_deque, envl* in_envl) {
// assume in_deque already sorted by delivery time
// this function should only be called by delayed_send
if(in_deque == NULL || in_envl == NULL) {
return RTX_ERROR;
}
// if both are NULL, xnor both are not NULL
if((in_deque->head == NULL && in_deque->tail == NULL) ==
(in_deque->head != NULL && in_deque->tail != NULL)) {
return RTX_ERROR;
}
// H and T point to nothing (empty deque)
if(in_deque->head == NULL && in_deque->tail == NULL) {
in_deque->head = in_envl;
in_deque->tail = in_envl;
in_envl->next = NULL;
in_envl->prev = NULL;
return RTX_SUCCESS;
}
// H and T point to same envl (only one element in deque)
if(in_deque->head == in_deque->tail) {
if(in_deque->tail == NULL) {
return RTX_ERROR;
}
envl* curr = in_deque->tail;
// Element should not be pointing to anything, whether forward or back
if(curr->next != NULL || curr->prev != NULL) {
// me: likely an error
}
if(in_envl->delivery_time < curr->delivery_time) {
// enque in_envl before curr
in_envl->next = curr;
curr->prev = in_envl;
in_deque->head = in_envl;
in_envl->prev = NULL;
curr->next = NULL;
}
else {
// enque in_envl after curr
curr->next = in_envl;
in_envl->prev = curr;
in_deque->tail = in_envl;
curr->prev = NULL;
in_envl->next = NULL;
}
return RTX_SUCCESS;
}
// H and T point to different envl (>=2 elements on deque)
if(in_deque->head != in_deque->tail) {
if(in_envl->delivery_time < in_deque->head->delivery_time) {
in_envl->next = in_deque->head;
in_deque->head->prev = in_envl;
in_deque->head = in_envl;
in_envl->prev = NULL;
return RTX_SUCCESS;
}
if(in_envl->delivery_time > in_deque->tail->delivery_time) {
in_deque->tail->next = in_envl;
in_envl->prev = in_deque->tail;
in_deque->tail = in_envl;
in_envl->next = NULL;
return RTX_SUCCESS;
}
// in_envl goes somewhere in between (at least 3 elements)
// starting at head and going in ascending order
envl* curr = in_deque->head->next;
while(curr != in_deque->tail) {
if(in_envl->delivery_time < curr->delivery_time) {
in_envl->next = curr;
in_envl->prev = curr->prev;
curr->prev->next = in_envl;
curr->prev = in_envl;
return RTX_SUCCESS;
}
curr = curr->next;
}
}
return RTX_ERROR; // shouldn't reach here
}
envl* envl_peek_head(envl_deque* in_deque) {
if(in_deque == NULL) {
return NULL;
}
return in_deque->head;
}
int envl_print_deque(envl_deque* in_deque) {
if(in_deque == NULL) {
return RTX_ERROR;
}
envl* curr = in_deque->head;
if(curr == NULL) {
return RTX_SUCCESS;
}
while(curr != in_deque->tail) {
envl_print(curr);
curr = curr->next;
}
envl_print(curr); // print last element
return RTX_SUCCESS;
}
envl_deque.h0000600010604300001450000000156411042040436013100 0ustar rvaliaveusers#ifndef ENVL_DEQUE_H
#define ENVL_DEQUE_H
#include "envl.h"
typedef struct {
envl* head;
envl* tail;
} envl_deque;
envl* envl_get_deque_head(envl_deque* in_deque);
envl* envl_get_deque_tail(envl_deque* in_deque);
envl* envl_dequeue_tail(envl_deque* in_deque);
envl* envl_dequeue_head(envl_deque* in_deque);
envl* envl_dequeue(envl_deque* in_deque); // note: NULL deques return NULL envelopes
int envl_enque_tail(envl* in_envl, envl_deque* in_deque);
int envl_enque_head(envl* in_envl, envl_deque* in_deque);
int envl_enque(envl* in_envl, envl_deque* in_deque);
int is_envl_deque_empty(envl_deque* in_deque);
envl* envl_dequeue_by_sender_pid(envl_deque* in_deque, PROCESS_ID in_pid);
int envl_enque_by_delivery_time(envl_deque* in_deque, envl* in_envl);
envl* envl_peek_head(envl_deque* in_deque);
int envl_print_deque(envl_deque* in_deque);
#endif /* ENVL_DEQUE_H */
func.c0000600010604300001450000005671211042102003011671 0ustar rvaliaveusers#include "func.h"
// Traverse through pcb table/list and return process with given pid
// Return NULL if nothing found
// Returns pcb with given in_pid if found. Dequeues the pcb if it is on any queue
pcb* get_pcb(PROCESS_ID in_pid) {
int i = 0;
pcb* found_pcb = NULL;
for(; i<pcbcnt; i++) {
if(pcb_table[i] != NULL) {
if(pcb_table[i]->pid == in_pid) {
found_pcb = pcb_table[i];
break;
}
}
else {
// me: shouldn't be any null pointers in pcb list
}
}
if(found_pcb == NULL) {
// couldn't find the process
return NULL;
}
PROCESS_STATE curr_state = pcb_get_state(found_pcb);
BOOLEAN i_proc = pcb_is_i_process(found_pcb);
if(i_proc == TRUE) {
// i-process is not on any queue (or shouldn't be)
return found_pcb;
}
if(curr_state == READY) {
found_pcb = dequeue_from_ready_queue(in_pid);
}
else if(curr_state == BLOCKED_ON_MEMORY) {
found_pcb = dequeue_from_blocked_on_memory_queue(in_pid);
}
else if(curr_state == BLOCKED_ON_MESSAGE) {
found_pcb = dequeue_from_blocked_on_receive_queue(in_pid);
}
else if(curr_state == RUNNING) {
found_pcb = current_process;
}
else {
// me: error
return NULL;
}
if(found_pcb == NULL) {
return NULL; // couldn't find in the queue given by the pcb's current state
}
return found_pcb;
}
pcb* peek_pcb(PROCESS_ID in_pid) {
int i = 0;
for(; i<pcbcnt; i++) {
if(pcb_table[i] != NULL) {
if(pcb_table[i]->pid == in_pid) {
return pcb_table[i];
}
}
else {
// me: shouldn't be any null pointers in pcb list
}
}
// couldn't find the process
return NULL;
}
envl* get_envl_by_sender_pid(pcb* in_pcb, PROCESS_ID* in_pid) {
if(in_pcb == NULL) {
return NULL;
}
if(in_pid == NULL) {
return envl_dequeue(pcb_get_message_queue(in_pcb)); // return first envelope
}
else {
return envl_dequeue_by_sender_pid(pcb_get_message_queue(in_pcb), *in_pid); // deques first envl with given in_pid
}
}
envl* dequeue_from_free_mem_queue() {
--free_mem_queue_cnt;
return envl_dequeue(free_mem_queue); // will return NULL if nothing available
}
int enque_onto_free_mem_queue(envl* in_envl) {
if(in_envl == NULL) {
return RTX_SUCCESS; // successfully freed nothing
}
envl_clear(in_envl);
envl_enque(in_envl, free_mem_queue);
++free_mem_queue_cnt;
return RTX_SUCCESS;
}
envl* dequeue_from_blocked_mem_queue() {
--blocked_mem_queue_cnt;
return envl_dequeue(blocked_mem_queue); // will return NULL if nothing available
}
int enque_onto_blocked_mem_queue(envl* in_envl) {
if(in_envl == NULL) {
return RTX_SUCCESS; // successfully freed nothing
}
envl_enque(in_envl, blocked_mem_queue);
++blocked_mem_queue_cnt;
return RTX_SUCCESS;
}
envl* dequeue_from_delay_send_queue() {
--delay_send_queue_cnt;
return envl_dequeue(delay_send_queue); // will return NULL if nothing available
}
int enque_onto_delay_send_queue(envl* in_envl) {
if(in_envl == NULL) {
return RTX_SUCCESS; // successfully freed nothing
}
envl_enque(in_envl, delay_send_queue);
++delay_send_queue_cnt;
return RTX_SUCCESS;
}
int enque_onto_delay_send_queue_by_delivery_time(envl* in_envl) {
if(in_envl == NULL) {
return RTX_SUCCESS; // successfully enqued nothing
}
envl_enque_by_delivery_time(delay_send_queue, in_envl);
++delay_send_queue_cnt;
return RTX_SUCCESS;
}
int clear_buffer(char* in_buf, int count) {
if(count <= 0) {
return RTX_ERROR;
}
if(in_buf == NULL) {
return RTX_SUCCESS;
}
int i;
for(i=0; i<count; i++) {
in_buf[i] = '\0';
}
return RTX_SUCCESS;
}
int copy_buffer(char* in_src_buf, char* in_dest_buf, int in_num) {
// note: sizeof(in_dest_buf) >= sizeof(in_src_buf)
// also, in_src_buf should be null terminated
// also, in_dest_buf will NOT be null_terminated if sizeof(in_src_buf) >= in_num
int cnt = 0; // current index
// copy upto in_num
while(in_src_buf[cnt] != '\0') {
if(cnt >= in_num) {
return RTX_SUCCESS;
}
in_dest_buf[cnt] = in_src_buf[cnt];
++cnt;
}
// sizeof(in_src_buf) < sizeof(in_dest_buf)
// Pad remainder of in_dest_buf with null chars
while(cnt < in_num) {
in_dest_buf[cnt] = '\0';
++cnt;
}
return RTX_SUCCESS;
}
/*
int set_process_state(pcb* in_proc, PROCESS_STATE in_state) {
return pcb_set_state(in_proc, in_state);
}
*/
int enque_onto_ready_queue(pcb* in_pcb, PRIORITY_LEVEL in_plvl) {
if(in_pcb == NULL || !is_valid_priority(in_plvl)) {
return RTX_ERROR;
}
pcb_set_state(in_pcb, READY);
pcb_set_priority(in_pcb, in_plvl);
int res = 0;
res = pcb_enque(in_pcb, &ready_queue[in_plvl]);
#ifdef DEBUG
if(res == RTX_ERROR) {
rtx_dbug_outs("[ENQUE_ONTO_READY_QUEUE][ERROR] Failed to enque");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs("\n\r");
}
else {
rtx_dbug_outs("[ENQUE_ONTO_READY_QUEUE] Successfully enqued ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" at plvl ");
rtx_dbug_out_int10(pcb_get_priority(in_pcb));
rtx_dbug_outs(" with state ");
rtx_dbug_outs(get_process_state_name(pcb_get_state(in_pcb)));
rtx_dbug_outs("\n\r");
/*
// very slow if used
// I used this to detect if something was actually enqued onto this queue
rtx_dbug_outs("[ENQUE_ONTO_READY_QUEUE] Printing ready_queue\n\r");
print_ready_queue();
*/
}
#endif
return RTX_SUCCESS;
}
int enque_onto_blocked_on_receive_queue(pcb* in_pcb, PRIORITY_LEVEL in_plvl) {
if(in_pcb == NULL || !is_valid_priority(in_plvl)) {
return RTX_ERROR;
}
pcb_set_state(in_pcb, BLOCKED_ON_MESSAGE);
pcb_set_priority(in_pcb, in_plvl);
int res = 0;
res = pcb_enque(in_pcb, &blocked_on_receive_queue[in_plvl]);
#ifdef DEBUG
if(res == RTX_ERROR) {
rtx_dbug_outs("[ENQUE_ONTO_BLOCKED_ON_RECEIVE_QUEUE][ERROR] Failed to enque");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs("\n\r");
}
else {
rtx_dbug_outs("[ENQUE_ONTO_BLOCKED_ON_RECEIVE_QUEUE] Successfully enqued ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" at plvl ");
rtx_dbug_out_int10(pcb_get_priority(in_pcb));
rtx_dbug_outs(" with state ");
rtx_dbug_outs(get_process_state_name(pcb_get_state(in_pcb)));
rtx_dbug_outs("\n\r");
/*
// very slow if used
// I used this to detect if something was actually enqued onto this queue
rtx_dbug_outs("[ENQUE_ONTO_BLOCKED_ON_RECEIVE_QUEUE] Printing blocked_on_receive_queue\n\r");
print_blocked_on_receive_queue();
*/
}
#endif
return RTX_SUCCESS;
}
int enque_onto_blocked_on_memory_queue(pcb* in_pcb, PRIORITY_LEVEL in_plvl) {
if(in_pcb == NULL || !is_valid_priority(in_plvl)) {
return RTX_ERROR;
}
pcb_set_state(in_pcb, BLOCKED_ON_MEMORY);
pcb_set_priority(in_pcb, in_plvl);
int res = 0;
res = pcb_enque(in_pcb, &blocked_on_memory_queue[in_plvl]);
#ifdef DEBUG
if(res == RTX_ERROR) {
rtx_dbug_outs("[ENQUE_ONTO_BLOCKED_ON_MEMORY_QUEUE][ERROR] Failed to enque");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs("\n\r");
}
else {
rtx_dbug_outs("[ENQUE_ONTO_BLOCKED_ON_MEMORY_QUEUE] Successfully enqued ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" at plvl ");
rtx_dbug_out_int10(pcb_get_priority(in_pcb));
rtx_dbug_outs(" with state ");
rtx_dbug_outs(get_process_state_name(pcb_get_state(in_pcb)));
rtx_dbug_outs("\n\r");
/*
// very slow if used
// I used this to detect if something was actually enqued onto this queue
rtx_dbug_outs("[ENQUE_ONTO_BLOCKED_ON_MEMORY_QUEUE] Printing blocked_on_memory_queue\n\r");
print_blocked_on_memory_queue();
*/
}
#endif
return RTX_SUCCESS;
}
pcb* dequeue_from_ready_queue(PROCESS_ID in_pid) {
int i = 0;
pcb* found_pcb = NULL;
int res = 0;
for(; i < NUM_PRIORITY; i++) {
res = is_pcb_deque_empty(&ready_queue[i]);
if(res == FALSE) {
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_READY_QUEUE] Searching for ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" on ready_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("]\n\r");
#endif
found_pcb = pcb_dequeue_by_pid(&ready_queue[i], in_pid);
if(found_pcb != NULL) {
/*
#ifdef DEBUG
rtx_dbug_outs("found_pcb = ");
rtx_dbug_out_int16(found_pcb);
rtx_dbug_outs("\n\r");
#endif
*/
return found_pcb;
}
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_READY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" not found on ready_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("]\n\r");
#endif
}
if(res == RTX_ERROR) {
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_READY_QUEUE][ERROR] ready_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("] is empty\n\r");
#endif
}
/*
// problematic code
if(!is_pcb_deque_empty(&ready_queue[i])) {
found_pcb = pcb_dequeue_by_pid(&ready_queue[i], in_pid);
if(found_pcb != NULL) {
return found_pcb;
}
}
*/
}
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_READY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" not found on ready_queue\n\r");
#endif
return NULL;
}
pcb* dequeue_from_blocked_on_receive_queue(PROCESS_ID in_pid) {
int i = 0;
pcb* found_pcb = NULL;
int res = 0;
for(; i < NUM_PRIORITY; i++) {
res = is_pcb_deque_empty(&blocked_on_receive_queue[i]);
if(res == FALSE) {
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_RECEIVE_QUEUE] Searching for ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" on blocked_on_receive_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("]\n\r");
#endif
found_pcb = pcb_dequeue_by_pid(&blocked_on_receive_queue[i], in_pid);
if(found_pcb != NULL) {
/*
#ifdef DEBUG
rtx_dbug_outs("found_pcb = ");
rtx_dbug_outs(pcb_get_name(found_pcb));
rtx_dbug_outs("\n\r");
#endif
*/
return found_pcb;
}
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_RECEIVE_QUEUE] ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" not found on blocked_on_receive_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("]\n\r");
#endif
}
else if(res == RTX_ERROR) {
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_RECEIVE_QUEUE] blocked_on_receive_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("] is empty\n\r");
#endif
}
/*
// problematic code
if(!is_pcb_deque_empty(&blocked_on_receive_queue[i])) {
found_pcb = pcb_dequeue_by_pid(&blocked_on_receive_queue[i], in_pid);
if(found_pcb != NULL) {
return found_pcb;
}
}
*/
}
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_RECEIVE_QUEUE] ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" not found on blocked_on_receive_queue\n\r");
#endif
return NULL;
}
pcb* dequeue_from_blocked_on_memory_queue(PROCESS_ID in_pid) {
int i = 0;
pcb* found_pcb = NULL;
int res = 0;
for(; i < NUM_PRIORITY; i++) {
res = is_pcb_deque_empty(&blocked_on_memory_queue[i]);
if(res == FALSE) {
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_MEMORY_QUEUE] Searching for ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" on blocked_on_memory_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("]\n\r");
#endif
found_pcb = pcb_dequeue_by_pid(&blocked_on_memory_queue[i], in_pid);
if(found_pcb != NULL) {
/*
#ifdef DEBUG
rtx_dbug_outs("found_pcb = ");
rtx_dbug_out_int16(found_pcb);
rtx_dbug_outs("\n\r");
#endif
*/
return found_pcb;
}
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_MEMORY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" not found on blocked_on_memory_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("]\n\r");
#endif
}
else if(res == RTX_ERROR) {
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_MEMORY_QUEUE][ERROR] blocked_on_memory_queue[");
rtx_dbug_out_int10(i);
rtx_dbug_outs("] is empty\n\r");
#endif
}
/*
// problematic code
if(!is_pcb_deque_empty(&blocked_on_memory_queue[i])) {
found_pcb = pcb_dequeue_by_pid(&blocked_on_memory_queue[i], in_pid);
if(found_pcb != NULL) {
return found_pcb;
}
}
*/
}
#ifdef DEBUG
rtx_dbug_outs("[DEQUEUE_FROM_BLOCKED_ON_MEMORY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(peek_pcb(in_pid)));
rtx_dbug_outs(" not found on blocked_on_memory_queue");
#endif
return NULL;
}
int atomic(int in_state) {
/*
UINT32 mask;
if(in_state == ON) { // Disable Interrupts
mask = SIM_IMR;
mask |= 0xFFFFFFFF;
SIM_IMR = mask;
return RTX_SUCCESS;
}
else if(in_state == OFF) { // Enable Interrupts
mask = SIM_IMR;
mask &= 0x0003cdff;
SIM_IMR = mask;
return RTX_SUCCESS;
}
else {
return RTX_ERROR;
}
*/
return RTX_SUCCESS;
}
// Converts from a char that is a number to a real number or else will return -1
int char_to_int(char in_num) {
switch((int)in_num){
case((int)('0')): return 0;
case((int)('1')): return 1;
case((int)('2')): return 2;
case((int)('3')): return 3;
case((int)('4')): return 4;
case((int)('5')): return 5;
case((int)('6')): return 6;
case((int)('7')): return 7;
case((int)('8')): return 8;
case((int)('9')): return 9;
default: return RTX_ERROR;
}
}
// Returns -1 as the integer if there are letters or special chars in the input param
int atoi(char* in_string) {
char * tmp_string = in_string;
int tmp_int = 0;
int result = 0;
for(; *tmp_string != '\0'; tmp_string++) {
result = char_to_int(*tmp_string);
if (result != RTX_ERROR) {
tmp_int = (tmp_int * 10) + result;
}
else {
return RTX_ERROR;
}
}
return tmp_int;
}
char int_to_char(int in_num) {
switch(in_num) {
case(0): return '0';
case(1): return '1';
case(2): return '2';
case(3): return '3';
case(4): return '4';
case(5): return '5';
case(6): return '6';
case(7): return '7';
case(8): return '8';
case(9): return '9';
default: return RTX_ERROR;
}
}
char* itoa(int value, char* str, int base) {
// for our itoa, base = 10
// str should be null terminated at the end of this
int i = 0;
int lsd = 0;
char res = '\0';
while(1) {
lsd = value % 10;
res = int_to_char(lsd);
str[i] = res;
++i;
value /= 10;
if(value == 0) {
// i gives count of number of characters in string
// reverse string
char tmp = NULL;
int j = 0;
for(;j<(i/2); j++) {
tmp = str[j];
str[j] = str[(i -1) -j];
str[(i -1) -j] = tmp;
}
str[i] = '\0';
return str;
}
}
}
int change_priority(pcb* in_pcb, PRIORITY_LEVEL in_plvl) {
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Changing ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" 's priority to ");
rtx_dbug_out_int10(in_plvl);
rtx_dbug_outs("\n\r");
#endif
if(in_pcb == NULL) {
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] in_pcb = NULL\n\r");
#endif
return RTX_ERROR;
}
if(!is_valid_priority(in_plvl)) {
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Invalid priority\n\r");
#endif
return RTX_ERROR;
}
// in_pcb != NULL
// in_plvl is valid
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Checking if ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" on ready_queue\n\r");
#endif
pcb* res_pcb = NULL;
res_pcb = dequeue_from_ready_queue(pcb_get_pid(in_pcb));
if(res_pcb != NULL) {
// is on ready queue
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Re-enqueing ");
rtx_dbug_outs(pcb_get_name(res_pcb));
rtx_dbug_outs(" onto the ready_queue\n\r");
#endif
return enque_onto_ready_queue(res_pcb, in_plvl);
}
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Checking if ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" on blocked_on_receive_queue\n\r");
#endif
res_pcb = dequeue_from_blocked_on_receive_queue(pcb_get_pid(in_pcb));
if(res_pcb != NULL) {
// is on blocked_on_receive_queue
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Re-enqueing ");
rtx_dbug_outs(pcb_get_name(res_pcb));
rtx_dbug_outs(" onto the blocked_on_receive_queue\n\r");
#endif
return enque_onto_blocked_on_receive_queue(res_pcb, in_plvl);
}
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Checking if ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" on blocked_on_memory_queue\n\r");
#endif
res_pcb = dequeue_from_blocked_on_memory_queue(pcb_get_pid(in_pcb));
if(res_pcb != NULL) {
// is on blocked_on_memory_queue
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] Re-enqueing ");
rtx_dbug_outs(pcb_get_name(res_pcb));
rtx_dbug_outs(" onto the blocked_on_memory_queue\n\r");
#endif
return enque_onto_blocked_on_memory_queue(res_pcb, in_plvl);
}
// res_pcb == NULL
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" not on any queue\n\r");
#endif
if(pcb_get_pid(in_pcb) == NULL_PROCESS_PID) {
#ifdef DEBUG
rtx_dbug_outs("[CHANGE PRIORITY][ERROR] Cannot change priority of Null process\n\r");
return RTX_ERROR;
#endif
}
// me: check if i-process, and disallow change as well?
// in_pcb not on any queue
pcb_set_priority(in_pcb, in_plvl);
return RTX_SUCCESS;
}
int envl_set_msgtext(envl* in_envl, char* in_msgtext) {
if(in_envl == NULL) {
return RTX_ERROR;
}
return copy_buffer(in_msgtext, in_envl->msgtext, ENVL_MSGTEXT_SIZE);
}
void print_ready_queue() {
int i = 0;
for(; i<NUM_PRIORITY; i++) {
pcb_print_pcb_deque(&ready_queue[i]);
}
}
void print_blocked_on_receive_queue() {
int i = 0;
for(; i<NUM_PRIORITY; i++) {
pcb_print_pcb_deque(&blocked_on_receive_queue[i]);
}
}
void print_blocked_on_memory_queue() {
int i = 0;
for(; i<NUM_PRIORITY; i++) {
pcb_print_pcb_deque(&blocked_on_memory_queue[i]);
}
}
void print_pcb_table() {
int i = 0;
for(; i<pcbcnt; i++) {
if(pcb_table[i] != NULL) {
pcb_print(pcb_table[i]);
}
}
}
void print_envl_table() {
int i = 0;
for(; i<envlcnt; i++) {
if(envl_table[i] != NULL) {
envl_print(envl_table[i]);
}
}
}
int is_pcb_on_ready_queue(pcb* in_pcb) {
if(in_pcb == NULL) {
return RTX_ERROR;
}
int i = 0;
for(; i<NUM_PRIORITY; i++) {
if(is_pcb_on_deque(&ready_queue[i], in_pcb) == TRUE) {
#ifdef DEBUG
rtx_dbug_outs("[IS_PCB_ON_READY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" found on ready_queue\n\r");
#endif
return TRUE;
}
}
#ifdef DEBUG
rtx_dbug_outs("[IS_PCB_ON_READY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" not found on ready_queue\n\r");
#endif
return FALSE;
}
int is_pcb_on_blocked_on_receive_queue(pcb* in_pcb) {
if(in_pcb == NULL) {
return RTX_ERROR;
}
int i = 0;
for(; i<NUM_PRIORITY; i++) {
if(is_pcb_on_deque(&blocked_on_receive_queue[i], in_pcb) == TRUE) {
#ifdef DEBUG
rtx_dbug_outs("[IS_PCB_ON_BLOCKED_ON_RECEIVE_QUEUE] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" found on blocked_on_receive_queue\n\r");
#endif
return TRUE;
}
}
#ifdef DEBUG
rtx_dbug_outs("[IS_PCB_ON_BLOCKED_ON_RECEIVE_QUEUE] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" not found on blocked_on_receive_queue\n\r");
#endif
return FALSE;
}
int is_pcb_on_blocked_on_memory_queue(pcb* in_pcb) {
if(in_pcb == NULL) {
return RTX_ERROR;
}
int i = 0;
for(; i<NUM_PRIORITY; i++) {
if(is_pcb_on_deque(&blocked_on_memory_queue[i], in_pcb) == TRUE) {
#ifdef DEBUG
rtx_dbug_outs("[IS_PCB_ON_BLOCKED_ON_MEMORY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" found on blocked_on_memory_queue\n\r");
#endif
return TRUE;
}
}
#ifdef DEBUG
rtx_dbug_outs("[IS_PCB_ON_BLOCKED_ON_MEMORY_QUEUE] ");
rtx_dbug_outs(pcb_get_name(in_pcb));
rtx_dbug_outs(" not found on blocked_on_memory_queue\n\r");
#endif
return FALSE;
}
int time_to_int(char* in_time) {
if (in_time == NULL){
return 0;
}
// assume well-formed, ie. "hh:mm:ss"
char hh[2+1] = {'\0','\0','\0'};
char mm[2+1] = {'\0','\0','\0'};
char ss[2+1] = {'\0','\0','\0'};
hh[0] = in_time[0];
hh[1] = in_time[1];
mm[0] = in_time[3];
mm[1] = in_time[4];
ss[0] = in_time[6];
ss[1] = in_time[7];
return 60*60*atoi(hh) +60*atoi(mm) +atoi(ss);
}
char* int_to_time(int in_time, char* in_buf) {
// in_buf should have format hh:mm:ss (size >= 8+1)
char tmpbuf[16];
int hour = in_time / (60*60); // 60 m/h * 60 s/m
in_time -= (hour*60*60);
int min = in_time / 60; // 60 s/m
in_time -= (min*60);
int sec = in_time;
itoa(hour, tmpbuf, 10);
if(hour == 0) {
in_buf[0] = '0';
in_buf[1] = '0';
}
else if(hour >= 1 && hour <= 9) {
in_buf[0] = '0';
in_buf[1] = tmpbuf[0];
}
else {
in_buf[0] = tmpbuf[0];
in_buf[1] = tmpbuf[1];
}
in_buf[2] = ':';
itoa(min, tmpbuf, 10);
if(min == 0) {
in_buf[3] = '0';
in_buf[4] = '0';
}
else if(min >= 1 && min <= 9) {
in_buf[3] = '0';
in_buf[4] = tmpbuf[0];
}
else {
in_buf[3] = tmpbuf[0];
in_buf[4] = tmpbuf[1];
}
in_buf[5] = ':';
itoa(sec, tmpbuf, 10);
if(sec == 0) {
in_buf[6] = '0';
in_buf[7] = '0';
}
else if(sec >= 1 && sec <= 9) {
in_buf[6] = '0';
in_buf[7] = tmpbuf[0];
}
else {
in_buf[6] = tmpbuf[0];
in_buf[7] = tmpbuf[1];
}
in_buf[8] = '\0';
return in_buf;
}
func.h0000600010604300001450000000344011042102003011664 0ustar rvaliaveusers#ifndef FUNC_H
#define FUNC_H
#include "globalvar.h"
#include "outs.h"
// Contains all functions that operate on globalvar.h
pcb* get_pcb(PROCESS_ID in_pid);
pcb* peek_pcb(PROCESS_ID in_pid);
envl* get_envl_by_sender_pid(pcb* in_pcb, PROCESS_ID* in_pid);
envl* dequeue_from_free_mem_queue();
int enque_onto_free_mem_queue(envl* in_envl);
envl* dequeue_from_blocked_mem_queue();
int enque_onto_blocked_mem_queue(envl* in_envl);
envl* dequeue_from_delay_send_queue();
int enque_onto_delay_send_queue(envl* in_envl);
int enque_onto_delay_send_queue_by_delivery_time(envl* in_envl);
int clear_buffer(char* in_buf, int count);
int copy_buffer(char* in_src_buf, char* in_dest_buf, int in_num);
//int set_process_state(pcb* in_proc, PROCESS_STATE in_state);
int enque_onto_ready_queue(pcb* in_pcb, PRIORITY_LEVEL in_plvl);
int enque_onto_blocked_on_receive_queue(pcb* in_pcb, PRIORITY_LEVEL in_plvl);
int enque_onto_blocked_on_memory_queue(pcb* in_pcb, PRIORITY_LEVEL in_plvl);
pcb* dequeue_from_ready_queue(PROCESS_ID in_pid);
pcb* dequeue_from_blocked_on_receive_queue(PROCESS_ID in_pid);
pcb* dequeue_from_blocked_on_memory_queue(PROCESS_ID in_pid);
int atomic(int in_state);
int char_to_int(char in_num);
int atoi(char* in_string);
char int_to_char(int in_num);
char* itoa(int value, char* str, int base);
int change_priority(pcb* in_pcb, PRIORITY_LEVEL in_plvl);
int envl_set_msgtext(envl* in_envl, char* in_msgtext);
void print_ready_queue();
void print_blocked_on_receive_queue();
void print_blocked_on_memory_queue();
void print_pcb_table();
void print_envl_table();
int is_pcb_on_ready_queue(pcb* in_pcb);
int is_pcb_on_blocked_on_receive_queue(pcb* in_pcb);
int is_pcb_on_blocked_on_memory_queue(pcb* in_pcb);
int time_to_int(char* in_time);
char* int_to_time(int in_time, char* in_buf);
#endif /* FUNC_H */
globalvar.h0000600010604300001450000000523111042123527012720 0ustar rvaliaveusers#ifndef GLOBALVAR_H
#define GLOBALVAR_H
#include "const.h"
#include "pcb_pdeque.h"
#include "envl_deque.h"
pcb* current_process; // Refers to currently executing process (ie. to PCB)
int pcbcnt; // Number of PCBs in the system
int envlcnt; // Number of envelopes in the system
BOOL clock_state; // true = ON, false = OFF
SYSTIME currtime; // Updated in the Timer I-process // has units of seconds
BOOL delaySend; //Used for delayed_send() to signal whether or not the sender of the message should be changed
SYSTIME delaytime;
pcb* pcb_table[DEFAULT_PCBCNT]; // table of pointers to PCBs
envl* envl_table[DEFAULT_ENVLCNT]; // table of pointers to envelopes
// priority levels implicitly 1-to-1 with array indicies
// implicitly 0 is highest priority
pcb_deque blocked_on_receive_queue[NUM_PRIORITY]; // processes waiting for a message
pcb_deque blocked_on_memory_queue[NUM_PRIORITY]; // processes waiting for memory to send messages
pcb_deque ready_queue[NUM_PRIORITY];
envl_deque* free_mem_queue;
int free_mem_queue_cnt; // number of elements on free_mem_queue
envl_deque* blocked_mem_queue;
int blocked_mem_queue_cnt;
envl_deque* delay_send_queue; // should be always sorted by least delay
int delay_send_queue_cnt;
// PCB Stuff
// __end is where the compiler thinks the free memory starts
extern void * __end;
// goAddress is where we think the OS will start to reside in memory
//void * goAddress = 10100000;
// startAddress is the start of free memory
const void * pcbStartAddress;
void * pcbEndAddress;
void * envlEndAddress;
// For communication from a user visible primative to swi_handler()
// Since atomic mode is turned on, then trap is called, then swi_handler() calls the appropriate kernel primtive, these values should not change in-between
int current_primitive;
UINT32 swi_handler_param1;
UINT32 swi_handler_param2;
UINT32 swi_handler_param3;
//env swi_handler_env;
void* swi_handler_env;
// Likewise, when swi_handler() returns, it is still in atomic mode, so these values should not change in-between
// For the return value, this is only set after a kernel primitive finishes, at which point swi_handler() returns. Only one of these values should be returned.
int swi_handler_int_ret;
void* swi_handler_voidp_ret;
// me: I do this to avoid using the current_process's stack, and to avoid having to write assembly
//variable to count the number of times the timer interrupt fires for the timer_i_process
UINT32 timer_count;
//variable used for the acknowledgment of serial interrupt
BYTE uart_ack;
char tmp_char;
BOOLEAN key_in;
int cmd_table_cnt;
envl_deque* process_c1_local_msg_q_addr;
envl_deque* process_c2_local_msg_q_addr;
#endif /* GLOBALVAR_H */
globalvar.h~0000600010604300001450000000520611042073411013114 0ustar rvaliaveusers#ifndef GLOBALVAR_H
#define GLOBALVAR_H
#include "const.h"
#include "pcb_pdeque.h"
#include "envl_deque.h"
pcb* current_process; // Refers to currently executing process (ie. to PCB)
int pcbcnt; // Number of PCBs in the system
int envlcnt; // Number of envelopes in the system
BOOL clock_state; // true = ON, false = OFF
SYSTIME currtime; // Updated in the Timer I-process // has units of seconds
BOOL delaySend; //Used for delayed_send() to signal whether or not the sender of the message should be changed
pcb* pcb_table[DEFAULT_PCBCNT]; // table of pointers to PCBs
envl* envl_table[DEFAULT_ENVLCNT]; // table of pointers to envelopes
// priority levels implicitly 1-to-1 with array indicies
// implicitly 0 is highest priority
pcb_deque blocked_on_receive_queue[NUM_PRIORITY]; // processes waiting for a message
pcb_deque blocked_on_memory_queue[NUM_PRIORITY]; // processes waiting for memory to send messages
pcb_deque ready_queue[NUM_PRIORITY];
envl_deque* free_mem_queue;
int free_mem_queue_cnt; // number of elements on free_mem_queue
envl_deque* blocked_mem_queue;
int blocked_mem_queue_cnt;
envl_deque* delay_send_queue; // should be always sorted by least delay
int delay_send_queue_cnt;
// PCB Stuff
// __end is where the compiler thinks the free memory starts
extern void * __end;
// goAddress is where we think the OS will start to reside in memory
//void * goAddress = 10100000;
// startAddress is the start of free memory
const void * pcbStartAddress;
void * pcbEndAddress;
void * envlEndAddress;
// For communication from a user visible primative to swi_handler()
// Since atomic mode is turned on, then trap is called, then swi_handler() calls the appropriate kernel primtive, these values should not change in-between
int current_primitive;
UINT32 swi_handler_param1;
UINT32 swi_handler_param2;
UINT32 swi_handler_param3;
//env swi_handler_env;
void* swi_handler_env;
// Likewise, when swi_handler() returns, it is still in atomic mode, so these values should not change in-between
// For the return value, this is only set after a kernel primitive finishes, at which point swi_handler() returns. Only one of these values should be returned.
int swi_handler_int_ret;
void* swi_handler_voidp_ret;
// me: I do this to avoid using the current_process's stack, and to avoid having to write assembly
//variable to count the number of times the timer interrupt fires for the timer_i_process
UINT32 timer_count;
//variable used for the acknowledgment of serial interrupt
BYTE uart_ack;
char tmp_char;
BOOLEAN key_in;
int cmd_table_cnt;
envl_deque* process_c1_local_msg_q_addr;
envl_deque* process_c2_local_msg_q_addr;
#endif /* GLOBALVAR_H */
init.c0000600010604300001450000007313011042127441011707 0ustar rvaliaveusers#include "init.h"
void init_swi_handler() {
#ifndef ASM_OFF
//Setting up the vector trap #6 (0x80 + # *4)
asm("move.l %d0, -(%a7)");
asm("move.l #asm_trap_entry, %d0");
asm("move.l %d0, 0x10000098");
asm("move.l (%a7)+, %d0");
#endif
}
void init_timer_interrupt() {
UINT32 interrupt_mask;
#ifndef ASM_OFF
asm("move.l %D0,-(%A7)");
asm("move.l #asm_timer_entry,%D0");
asm("move.l %D0,0x10000078");
asm("move.l (%A7)+,%D0");
//clear the timer event register
TIMER0_TER = 0x03;
//setup timer interrupt controller register
//bit 1-0 = IP = 10 -> interrupt priority (high)
//bit 4-2 = IL = 110 -> interrupt level (6)
//bit 6-5 = 00 -> reserved
//bit 7 = AVEC = 1 -> autovector enable generating SIM during interrupt ack cycle
TIMER0_ICR = 0x9B;
//set to approx 1s
//(1/45)x(16)x(256+1)(2AEA = 10986) = 1.0039s
//TIMER0_TRR = 0xD5BD; // 5 seconds
//TIMER0_TRR = 0x26D0; // <1 second
// TIMER0_TRR = 0x2AEA; // 1 second
TIMER0_TRR = 175; // 10 ms
//setup the timer mode stuff
//bit 0 = RST = 1 -> enable timer
//bit 2-1 = CLK = 01 -> system bus clock divided by 16
//bit 3 = FRR = 1 -> restart. timer counter is reset after reaching ref
//bit 4 = ORI = 1 -> enable interrupt upon reaching the reference value
//bit 5 = OM = 1 -> toggle output
//bit 7-6 = CE = 00 -> disable interrupt on capture event
//bit 15-8 = PS = 0xFF -> prescaler to divide the clock by 256
TIMER0_TMR = 0xFF3D;
//mask the timer interrupt
interrupt_mask = SIM_IMR;
interrupt_mask &= 0x0003fdff;
SIM_IMR = interrupt_mask;
#endif
}
void init_uart_interrupt() {
UINT32 interrupt_mask;
#ifndef ASM_OFF
//UART init
asm("move.l %D0,-(%A7)");
asm("move.l #asm_serial_entry,%D0");
asm("move.l %D0,0x10000100");
asm("move.l (%A7)+,%D0");
// Reset the Entire UART
SERIAL1_UCR = 0x10;
// Reset the receiever
SERIAL1_UCR = 0x20;
// Reset the transmitter
SERIAL1_UCR = 0x30;
// Reset the error condition
SERIAL1_UCR = 0x40;
//setup UART interrupt controller register
//bit 1-0 = IP = 10 -> interrupt priority (high)
//bit 4-2 = IL = 110 -> interrupt level (6)
SERIAL1_ICR = 0x17; //9A;
//set UART interrupt vector registor
SERIAL1_IVR = 0x40;
//set the UART interrupt mask register
SERIAL1_IMR = 0x02;
//setup UART to transmit and receive
SERIAL1_UCR = 0x05;
//mask the UART interrupt
interrupt_mask = SIM_IMR;
interrupt_mask &= 0x0003dfff;
SIM_IMR = interrupt_mask;
#endif
}
/*
void init_pcb_init_table() {
int i = 0;
#ifdef _RTX_EVAL_
setTestProcs();
for (; i < NUM_TEST_PROCS; i++) {
pcb_init_table[i].pid = RTXEVAL_TEST_PROCS[i].pid;
pcb_init_table[i].priority = RTXEVAL_TEST_PROCS[i].priority;
pcb_init_table[i].stack_size = RTXEVAL_TEST_PROCS[i].stacksize;
pcb_init_table[i].code_pointer = RTXEVAL_TEST_PROCS[i].rtxeval_proc_entry;
}
#endif
pcb_init_table[i].pid = NULL_PROCESS_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_4;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &null_process;
++i;
pcb_init_table[i].pid = A1_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a1;
++i;
pcb_init_table[i].pid = B1_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_b1;
++i;
pcb_init_table[i].pid = C1_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_c1;
++i;
pcb_init_table[i].pid = A2_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a2;
++i;
pcb_init_table[i].pid = B2_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_b2;
++i;
pcb_init_table[i].pid = C2_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_c2;
++i;
pcb_init_table[i].pid = A3_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a3;
++i;
pcb_init_table[i].pid = A3_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a3;
++i;
pcb_init_table[i].pid = KCD_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &keyboard_command_decoder;
++i;
pcb_init_table[i].pid = CRT_DISPLAY_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &crt_display;
++i;
pcb_init_table[i].pid = TIMER_I_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &timer_i_process;
++i;
pcb_init_table[i].pid = UART_I_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &uart_i_process;
++i;
pcb_init_table[i].pid = SPC_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &set_priority_command_process;
++i;
pcb_init_table[i].pid = WALL_CLOCK_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &wall_clock_display_process;
++i;
}
*/
void clear_block(void* in_start_addr, void* in_end_addr) {
// check that start_addr <= in_end_addr; otherwise, return
if(in_start_addr > in_end_addr) {
return;
}
void* tmp_addr = in_start_addr;
while(tmp_addr >= in_end_addr) {
*((char*)tmp_addr) = 0x00;
tmp_addr += 1; // todo: get size of increment
}
}
void set_initial_stack_state(pcb* in_pcb) {
/*
non i-processes
================ top of memory block
.
.
.
addr x16 (16 x 4 bytes) = 0x00000000 <-- SP
SR (2 bytes) = 0x0000
PC (4 bytes) = code pointer
================ bottom of memory block (and bottom of stack)
i-processes
================ top of memory block
.
.
.
addr x16 (16 x 4 bytes) = 0x00000000 <-- SP
SR (2 bytes) = 0x2700
PC (4 bytes) = code pointer
================ bottom of memory block (and bottom of stack)
*/
void *stack_ptr = NULL;
void *proc_code = NULL;
SINT32 proc_sr = 0;
stack_ptr = in_pcb->stack_pointer;
proc_code = in_pcb->code_pointer;
proc_sr = in_pcb->exception_stack_frame;
/*
#ifdef DEBUG
rtx_dbug_outs("[SET_INITIAL_STACK_STATE] Local stack_ptr = ");
rtx_dbug_out_int16(stack_ptr);
rtx_dbug_outs("\n\r");
rtx_dbug_outs("[SET_INITIAL_STACK_STATE] Real stack_pointer = ");
rtx_dbug_out_int16(in_pcb->stack_pointer);
rtx_dbug_outs("\n\r");
#endif
*/
// We use A0 as a temporary stack pointer
asm("move.l %a0, -(%a7)");
// We utilize D0 in this set of instructions, therefore save it
asm("move.l %d0, -(%a7)");
asm("move.l -4(%a6), %a0"); //A0 points to in_pcb->stack_pointer
asm("move.l -8(%a6), %d0");
asm("move.l %d0, -(%a0)");
asm("move.l -12(%a6), %d0");
asm("move.l %d0, -(%a0)");
// Initialize these bad boys to zero
asm("move.l #0, -(%a0)"); //d0
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //d7
asm("move.l #0, -(%a0)"); //a0
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //a6
// This is so context_swich() doesn't explode
asm("move.l #asm_trap_exit, %d0");
asm("move.l %d0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l %a0, %d0");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l %d0, -(%a0)");
asm("move.l %a0, -4(%a6)");
in_pcb->stack_pointer = stack_ptr;
asm("move.l (%a7)+, %d0");
asm("move.l (%a7)+, %a0");
return;
/*
pcb_set_stack_pointer(in_pcb, pcb_get_stack_end_addr(in_pcb)); // start at bottom
void* tmp_sp = pcb_get_stack_end_addr(in_pcb);
void* tmp_cp = pcb_get_code_pointer(in_pcb);
tmp_sp -= 4 +1; // todo: check size of decrement // note: sizeof coldfire address is 32-bit (4 bytes) // +1 since boundry byte location is writeable (and hence is part of the stack)
asm("nop");
// set bottom of stack to code pointer
*((long*)tmp_sp) = (long)tmp_cp;
tmp_sp -= 4;
// MS16bits are format, FS[3-2], VEC, and FS[1-0]
// LS16bits are SR
if(pcb_is_i_process(in_pcb) == TRUE) {
*((long*)tmp_sp) = 0x40800000
}
else {
*((long*)tmp_sp) = 0x40800000;
}
int i = 0;
for(; i<4*16; i++) { // note: sizeof(long_{coldfire}) = 4 Bytes
--tmp_sp;
*((char*)tmp_sp) = 0x00;
}
asm("move.l #asm_trap_exit, %d0");
asm("move.l %d0, -4(%a6)");
tmp_sp -= 4;
int j = 0;
for(; j<4*16; j++) { // note: sizeof(long_{coldfire}) = 4 Bytes
--tmp_sp;
*((char*)tmp_sp) = 0x0;
}
pcb_set_stack_pointer(in_pcb, (char*)tmp_sp); // might cause a problem going from long* to char*
*/
}
int init() {
//extern void * pcbStartAddress;
//extern void * __end;
#ifndef ASM_OFF
void* data_struct_start_addr = &__end;
#else
// since __end undefined on my machine
// 1 << 10 = 2^{20} B = 1 MB since OS needs 1 MB of space
//void* __start = malloc(1<<20);
void* __start = malloc(1<<(10+5)); // 32 k
void* data_struct_start_addr = __start;
//
#endif
// ================================================================
// Initialize hardware, then interrupts
init_swi_handler();
init_timer_interrupt();
init_uart_interrupt();
// ================================================================
// Global variables initialize
// me: do we need to initialize them here? We could just set these default values when they are declared
pcbcnt = 0;
envlcnt = 0;
clock_state = FALSE; // ie. OFF
currtime = 0;
cmd_table_cnt = 0;
delaySend = FALSE;
delaytime = 0;
// ================================================================
// Data structures allocation
void* data_struct_end_addr = data_struct_start_addr;
// note: these priority queues fixed to 5 levels
int pcb_pdeque_size = sizeof(pcb_deque)*NUM_PRIORITY;
int a = 0;
for(; a<NUM_PRIORITY; a++) {
blocked_on_receive_queue[a].head = NULL;
blocked_on_receive_queue[a].tail = NULL;
blocked_on_memory_queue[a].head = NULL;
blocked_on_memory_queue[a].tail = NULL;
ready_queue[a].head = NULL;
ready_queue[a].tail = NULL;
}
// blocked_on_receive_queue = (pcb_deque*)data_struct_end_addr;
data_struct_end_addr += pcb_pdeque_size;
// blocked_on_memory_queue = (pcb_deque*)data_struct_end_addr;
data_struct_end_addr += pcb_pdeque_size;
// ready_queue = (pcb_deque*)data_struct_end_addr;
data_struct_end_addr += pcb_pdeque_size;
int envl_deque_size = sizeof(envl_deque);
free_mem_queue = data_struct_end_addr;
free_mem_queue->head = NULL;
free_mem_queue->tail = NULL;
free_mem_queue_cnt = 0;
data_struct_end_addr += envl_deque_size;
blocked_mem_queue = data_struct_end_addr;
blocked_mem_queue->head = NULL;
blocked_mem_queue->tail = NULL;
blocked_mem_queue_cnt = 0;
data_struct_end_addr += envl_deque_size;
delay_send_queue = data_struct_end_addr;
delay_send_queue->head = NULL;
delay_send_queue->tail = NULL;
delay_send_queue_cnt = 0;
data_struct_end_addr += envl_deque_size;
// ================================================================
// PCB allocation
void* pcb_start_addr = data_struct_end_addr +2;
// Fill table with addresses of PCBs
int pcb_size = sizeof(pcb);
int i = 0;
for(; i<DEFAULT_PCBCNT; i++) {
pcb_table[i] = (pcb_start_addr +(pcb_size * i));
}
void* pcb_end_addr = (pcb_start_addr +(pcb_size * i));
// ================================================================
// Memory (envelopes) allocation
void* envl_start_addr = pcb_end_addr +2;
int envl_size = sizeof(envl);
int j = 0;
envl* new_envl = NULL;
for(; j<DEFAULT_ENVLCNT; j++) {
// allocating envelopes sequentially
new_envl = (envl*)(envl_start_addr +(envl_size * j));
// keeping track of them through the table
envl_table[j] = new_envl;
++envlcnt;
// enque all envelopes onto the free_mem_queue
enque_onto_free_mem_queue(new_envl);
envl_clear(new_envl);
}
void* envl_end_addr = (envl_start_addr +(envl_size * j));
// ================================================================
// Process stack allocation
void* proc_stack_start_addr = envl_end_addr +2;
void* proc_stack_end_addr = proc_stack_start_addr;
int proc_stack_size = 1<<15; // 32 kiB// todo: find out size of actual process stack
int k = 0;
// assume pcbcnt = 0 here
#ifdef _RTX_EVAL_
// for automated test processes
// allocate stacks and pcbs
setTestProcs();
for(; k<NUM_TEST_PROCS; k++) {
pcb_set_stack_start_addr(pcb_table[pcbcnt],proc_stack_end_addr);
proc_stack_end_addr += RTXEVAL_TEST_PROCS[pcbcnt].stacksize; // note: it is an error to add two void* (they should be cast to int or something first)
pcb_set_stack_end_addr(pcb_table[pcbcnt],proc_stack_end_addr);
proc_stack_end_addr += 4 +2; // the "buffer" space between stacks (me: I don't think any address is longer than long)
clear_block(pcb_get_stack_start_addr(pcb_table[pcbcnt]), pcb_get_stack_end_addr(pcb_table[pcbcnt]));
pcb_set_stack_pointer(pcb_table[pcbcnt], pcb_get_stack_end_addr(pcb_table[pcbcnt]));
//
pcb_table[pcbcnt]->pid = RTXEVAL_TEST_PROCS[pcbcnt].pid;
pcb_table[pcbcnt]->priority = RTXEVAL_TEST_PROCS[k].priority;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
pcb_table[pcbcnt]->stack_size = RTXEVAL_TEST_PROCS[k].stacksize;
enque_onto_ready_queue(pcb_table[pcbcnt], pcb_get_priority(pcb_table[pcbcnt]));
pcb_set_code_pointer(pcb_table[pcbcnt], RTXEVAL_TEST_PROCS[k].rtxeval_proc_entry);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
}
// assuming NUM_TEST_PROCS == 6
pcb_table[0]->name = "rtx_test1";
pcb_table[1]->name = "rtx_test2";
pcb_table[2]->name = "rtx_test3";
pcb_table[3]->name = "rtx_test4";
pcb_table[4]->name = "rtx_test5";
pcb_table[5]->name = "rtx_test6";
// assert k == NUM_TEST_PROCS
// assert pcbcnt = NUM_TEST_PROCS
#endif
for(; k < DEFAULT_PCBCNT; k++) {
/*
note:
end of block k: N
start of block k +1: N + buffer size +1
This means that anything in the address range [N +1, N +buffer size] does not belong to any process, and should not be written to. This also implies that at least 1 byte will seperate the boundry between the end of block k and the start of block k +1.
For reasons of simplier math I think, the actual contents of the boundry locations should not be used. Therefore, [N, N +buffer size +1] should be used by nobody (me: OR perhaps those 1 bytes (me: >1?) should be occupied with some sorta of special boundry byte sequence or something like that.
*/
pcb_set_stack_start_addr(pcb_table[k],proc_stack_end_addr);
proc_stack_end_addr += (proc_stack_size * (k +1)); // note: it is an error to add two void* (they should be cast to int or something first)
pcb_set_stack_end_addr(pcb_table[k],proc_stack_end_addr);
proc_stack_end_addr += 4 +2; // the "buffer" space between stacks (me: I don't think any address is longer than long)
clear_block(pcb_get_stack_start_addr(pcb_table[k]), pcb_get_stack_end_addr(pcb_table[k]));
pcb_set_stack_pointer(pcb_table[k], pcb_get_stack_end_addr(pcb_table[k])); // start at bottom
}
// void* proc_stack_end_addr = (proc_stack_start_addr +(proc_stack_size * k));
// ================================================================
// Reserved space allocation
// ================================================================
// Initialize PCBs
pcb_table[pcbcnt]->pid = NULL_PROCESS_PID;
pcb_table[pcbcnt]->name = "Null process";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_4;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
pcb_enque(pcb_table[pcbcnt], &ready_queue[PRIORITY_LEVEL_4]);
pcb_set_code_pointer(pcb_table[pcbcnt], &null_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
/*
pcb_table[pcbcnt]->pid = TEST_1_PID;
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &test_1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
*/
// PIDs 1-6 reserved for testing processes
pcb_table[pcbcnt]->pid = A1_PID;
pcb_table[pcbcnt]->name = "A1";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_a1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = B1_PID;
pcb_table[pcbcnt]->name = "B1";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_b1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = C1_PID;
pcb_table[pcbcnt]->name = "C1";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_c1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = A2_PID;
pcb_table[pcbcnt]->name = "A2";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_a2);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = B2_PID;
pcb_table[pcbcnt]->name = "B2";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_b2);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = C2_PID;
pcb_table[pcbcnt]->name = "C2";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_c2);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = A3_PID;
pcb_table[pcbcnt]->name = "A3";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_a3);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = KCD_PID;
pcb_table[pcbcnt]->name = "KCD";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_0);
pcb_set_code_pointer(pcb_table[pcbcnt], &keyboard_command_decoder);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = CRT_DISPLAY_PID;
pcb_table[pcbcnt]->name = "CRT";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
pcb_table[pcbcnt]->messages.tail = NULL;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_0);
pcb_set_code_pointer(pcb_table[pcbcnt], &crt_display);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = TIMER_I_PID;
pcb_table[pcbcnt]->name = "Timer";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = TRUE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40802700;
//enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &timer_i_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = UART_I_PID;
pcb_table[pcbcnt]->name = "UART";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = TRUE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40802700;
//enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &uart_i_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = SPC_PID;
pcb_table[pcbcnt]->name = "SPC";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_1;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_1);
pcb_set_code_pointer(pcb_table[pcbcnt], &set_priority_command_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = WALL_CLOCK_PID;
pcb_table[pcbcnt]->name = "Wall clock";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_1;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_1);
pcb_set_code_pointer(pcb_table[pcbcnt], &wall_clock_display_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
//current_process = get_pcb(NULL_PROCESS_PID);
#ifdef SPLASH
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs(" @@@@@@@ @@@@@@ @@@ @@@ @@@ @@@ @@@ \n\r");
rtx_dbug_outs(" @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@ @@@ \n\r");
rtx_dbug_outs(" @@! @@@ @@! @@@ @@! @@! @@! @@! !@@ \n\r");
rtx_dbug_outs(" !@! @!@ !@! @!@ !@! !@! !@! !@! @!! \n\r");
rtx_dbug_outs(" @!@!!@! @!@!@!@! @!! !!@ @!@ @!@@!@! \n\r");
rtx_dbug_outs(" !!@!@! !!!@!!!! !@! !!! !@! !!@!!! \n\r");
rtx_dbug_outs(" !!: :!! !!: !!! !!: !!: !!: !!: :!! ,---.,---. \n\r");
rtx_dbug_outs(" :!: !:! :!: !:! :!: :!: :!: :!: !:! | |`---. \n\r");
rtx_dbug_outs(" :: ::: :: ::: :::: :: ::: :: ::: | | | \n\r");
rtx_dbug_outs(" : : : : : : :: : : : : ::: `---'`---' \n\r");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("INITIALIZING MEMORY STACK FRAMES.....................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("ROOT USER LOG IN.....................................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("KERNEL PANIC!........................................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("ASSUME THE PARTY POSITION............................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("THE CAKE IS A LIE....................................[FAILED]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("CRITICAL ERROR - CORE DUMP IMMINENT..................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("INITIALIZING BLUE SCREEN OF DEATH....................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("OOPS THE SYSTEM WAS UNABLE TO PERFORM YOUR OPERATION [SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("ERROR IS ERROR.......................................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("HACK.EXE.............................................[SUCCESS]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("THE OPERATION COMPLETED SUCCESSFULLY.................[FAILED]\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
rtx_dbug_outs("\r\n");
sleep(3);
int l = 0;
for(; l < pcbcnt; l++){
rtx_dbug_outs("======== INITIALIZE PCB STACK ========\n\r");
rtx_dbug_outs(" ");
rtx_dbug_outs(pcb_get_name(pcb_table[l]));
rtx_dbug_outs("\n\r");
rtx_dbug_outs(" pid = ");
rtx_dbug_out_int10(pcb_get_pid(pcb_table[l]));
rtx_dbug_outs("\n\r");
rtx_dbug_outs(" stack_start_addr = ");
rtx_dbug_out_int16((UINT32)pcb_get_stack_start_addr(pcb_table[l]));
rtx_dbug_outs("\n\r");
rtx_dbug_outs(" stack_end_addr = ");
rtx_dbug_out_int16((UINT32)pcb_get_stack_end_addr(pcb_table[l]));
rtx_dbug_outs("\n\r");
rtx_dbug_outs(" stack_pointer = ");
rtx_dbug_out_int16((UINT32)pcb_get_stack_pointer(pcb_table[l]));
rtx_dbug_outs("\n\r");
rtx_dbug_outs(" i_process = ");
rtx_dbug_out_int16(pcb_is_i_process(pcb_table[l]));
rtx_dbug_outs("\n\r");
}
rtx_dbug_outs("\n\r ****DONE INIT PCB STACK**** \n\r");
sleep(3);
#endif
// DO NOT CHANGE THIS!!!!
current_process = NULL;
// Start the OS
// Initialize stack pointer!
// asm("move.l 4(%a7),%a7");
//TIMER0_TER = 2;
asm( "move.w #0x2000,%sr" );
currtime = 0; // Setting curr_time to reference start of OS
current_primitive = RTX_INIT;
asm("trap #6");
return 0;
}
init.c~0000600010604300001450000007313011042123547012110 0ustar rvaliaveusers#include "init.h"
void init_swi_handler() {
#ifndef ASM_OFF
//Setting up the vector trap #6 (0x80 + # *4)
asm("move.l %d0, -(%a7)");
asm("move.l #asm_trap_entry, %d0");
asm("move.l %d0, 0x10000098");
asm("move.l (%a7)+, %d0");
#endif
}
void init_timer_interrupt() {
UINT32 interrupt_mask;
#ifndef ASM_OFF
asm("move.l %D0,-(%A7)");
asm("move.l #asm_timer_entry,%D0");
asm("move.l %D0,0x10000078");
asm("move.l (%A7)+,%D0");
//clear the timer event register
TIMER0_TER = 0x03;
//setup timer interrupt controller register
//bit 1-0 = IP = 10 -> interrupt priority (high)
//bit 4-2 = IL = 110 -> interrupt level (6)
//bit 6-5 = 00 -> reserved
//bit 7 = AVEC = 1 -> autovector enable generating SIM during interrupt ack cycle
TIMER0_ICR = 0x9B;
//set to approx 1s
//(1/45)x(16)x(256+1)(2AEA = 10986) = 1.0039s
//TIMER0_TRR = 0xD5BD; // 5 seconds
//TIMER0_TRR = 0x26D0; // <1 second
// TIMER0_TRR = 0x2AEA; // 1 second
TIMER0_TRR = 255; // 10 ms
//setup the timer mode stuff
//bit 0 = RST = 1 -> enable timer
//bit 2-1 = CLK = 01 -> system bus clock divided by 16
//bit 3 = FRR = 1 -> restart. timer counter is reset after reaching ref
//bit 4 = ORI = 1 -> enable interrupt upon reaching the reference value
//bit 5 = OM = 1 -> toggle output
//bit 7-6 = CE = 00 -> disable interrupt on capture event
//bit 15-8 = PS = 0xFF -> prescaler to divide the clock by 256
TIMER0_TMR = 0xFF3D;
//mask the timer interrupt
interrupt_mask = SIM_IMR;
interrupt_mask &= 0x0003fdff;
SIM_IMR = interrupt_mask;
#endif
}
void init_uart_interrupt() {
UINT32 interrupt_mask;
#ifndef ASM_OFF
//UART init
asm("move.l %D0,-(%A7)");
asm("move.l #asm_serial_entry,%D0");
asm("move.l %D0,0x10000100");
asm("move.l (%A7)+,%D0");
// Reset the Entire UART
SERIAL1_UCR = 0x10;
// Reset the receiever
SERIAL1_UCR = 0x20;
// Reset the transmitter
SERIAL1_UCR = 0x30;
// Reset the error condition
SERIAL1_UCR = 0x40;
//setup UART interrupt controller register
//bit 1-0 = IP = 10 -> interrupt priority (high)
//bit 4-2 = IL = 110 -> interrupt level (6)
SERIAL1_ICR = 0x17; //9A;
//set UART interrupt vector registor
SERIAL1_IVR = 0x40;
//set the UART interrupt mask register
SERIAL1_IMR = 0x02;
//setup UART to transmit and receive
SERIAL1_UCR = 0x05;
//mask the UART interrupt
interrupt_mask = SIM_IMR;
interrupt_mask &= 0x0003dfff;
SIM_IMR = interrupt_mask;
#endif
}
/*
void init_pcb_init_table() {
int i = 0;
#ifdef _RTX_EVAL_
setTestProcs();
for (; i < NUM_TEST_PROCS; i++) {
pcb_init_table[i].pid = RTXEVAL_TEST_PROCS[i].pid;
pcb_init_table[i].priority = RTXEVAL_TEST_PROCS[i].priority;
pcb_init_table[i].stack_size = RTXEVAL_TEST_PROCS[i].stacksize;
pcb_init_table[i].code_pointer = RTXEVAL_TEST_PROCS[i].rtxeval_proc_entry;
}
#endif
pcb_init_table[i].pid = NULL_PROCESS_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_4;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &null_process;
++i;
pcb_init_table[i].pid = A1_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a1;
++i;
pcb_init_table[i].pid = B1_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_b1;
++i;
pcb_init_table[i].pid = C1_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_c1;
++i;
pcb_init_table[i].pid = A2_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a2;
++i;
pcb_init_table[i].pid = B2_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_b2;
++i;
pcb_init_table[i].pid = C2_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_c2;
++i;
pcb_init_table[i].pid = A3_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a3;
++i;
pcb_init_table[i].pid = A3_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &process_a3;
++i;
pcb_init_table[i].pid = KCD_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &keyboard_command_decoder;
++i;
pcb_init_table[i].pid = CRT_DISPLAY_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_3;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &crt_display;
++i;
pcb_init_table[i].pid = TIMER_I_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &timer_i_process;
++i;
pcb_init_table[i].pid = UART_I_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &uart_i_process;
++i;
pcb_init_table[i].pid = SPC_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &set_priority_command_process;
++i;
pcb_init_table[i].pid = WALL_CLOCK_PID;
pcb_init_table[i].priority = PRIORITY_LEVEL_0;
pcb_init_table[i].stack_size = ; // todo: decide on stack size
pcb_init_table[i].code_pointer = &wall_clock_display_process;
++i;
}
*/
void clear_block(void* in_start_addr, void* in_end_addr) {
// check that start_addr <= in_end_addr; otherwise, return
if(in_start_addr > in_end_addr) {
return;
}
void* tmp_addr = in_start_addr;
while(tmp_addr >= in_end_addr) {
*((char*)tmp_addr) = 0x00;
tmp_addr += 1; // todo: get size of increment
}
}
void set_initial_stack_state(pcb* in_pcb) {
/*
non i-processes
================ top of memory block
.
.
.
addr x16 (16 x 4 bytes) = 0x00000000 <-- SP
SR (2 bytes) = 0x0000
PC (4 bytes) = code pointer
================ bottom of memory block (and bottom of stack)
i-processes
================ top of memory block
.
.
.
addr x16 (16 x 4 bytes) = 0x00000000 <-- SP
SR (2 bytes) = 0x2700
PC (4 bytes) = code pointer
================ bottom of memory block (and bottom of stack)
*/
void *stack_ptr = NULL;
void *proc_code = NULL;
SINT32 proc_sr = 0;
stack_ptr = in_pcb->stack_pointer;
proc_code = in_pcb->code_pointer;
proc_sr = in_pcb->exception_stack_frame;
/*
#ifdef DEBUG
rtx_dbug_outs("[SET_INITIAL_STACK_STATE] Local stack_ptr = ");
rtx_dbug_out_int16(stack_ptr);
rtx_dbug_outs("\n\r");
rtx_dbug_outs("[SET_INITIAL_STACK_STATE] Real stack_pointer = ");
rtx_dbug_out_int16(in_pcb->stack_pointer);
rtx_dbug_outs("\n\r");
#endif
*/
// We use A0 as a temporary stack pointer
asm("move.l %a0, -(%a7)");
// We utilize D0 in this set of instructions, therefore save it
asm("move.l %d0, -(%a7)");
asm("move.l -4(%a6), %a0"); //A0 points to in_pcb->stack_pointer
asm("move.l -8(%a6), %d0");
asm("move.l %d0, -(%a0)");
asm("move.l -12(%a6), %d0");
asm("move.l %d0, -(%a0)");
// Initialize these bad boys to zero
asm("move.l #0, -(%a0)"); //d0
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //d7
asm("move.l #0, -(%a0)"); //a0
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //.
asm("move.l #0, -(%a0)"); //a6
// This is so context_swich() doesn't explode
asm("move.l #asm_trap_exit, %d0");
asm("move.l %d0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l %a0, %d0");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l #0, -(%a0)");
asm("move.l %d0, -(%a0)");
asm("move.l %a0, -4(%a6)");
in_pcb->stack_pointer = stack_ptr;
asm("move.l (%a7)+, %d0");
asm("move.l (%a7)+, %a0");
return;
/*
pcb_set_stack_pointer(in_pcb, pcb_get_stack_end_addr(in_pcb)); // start at bottom
void* tmp_sp = pcb_get_stack_end_addr(in_pcb);
void* tmp_cp = pcb_get_code_pointer(in_pcb);
tmp_sp -= 4 +1; // todo: check size of decrement // note: sizeof coldfire address is 32-bit (4 bytes) // +1 since boundry byte location is writeable (and hence is part of the stack)
asm("nop");
// set bottom of stack to code pointer
*((long*)tmp_sp) = (long)tmp_cp;
tmp_sp -= 4;
// MS16bits are format, FS[3-2], VEC, and FS[1-0]
// LS16bits are SR
if(pcb_is_i_process(in_pcb) == TRUE) {
*((long*)tmp_sp) = 0x40800000
}
else {
*((long*)tmp_sp) = 0x40800000;
}
int i = 0;
for(; i<4*16; i++) { // note: sizeof(long_{coldfire}) = 4 Bytes
--tmp_sp;
*((char*)tmp_sp) = 0x00;
}
asm("move.l #asm_trap_exit, %d0");
asm("move.l %d0, -4(%a6)");
tmp_sp -= 4;
int j = 0;
for(; j<4*16; j++) { // note: sizeof(long_{coldfire}) = 4 Bytes
--tmp_sp;
*((char*)tmp_sp) = 0x0;
}
pcb_set_stack_pointer(in_pcb, (char*)tmp_sp); // might cause a problem going from long* to char*
*/
}
int init() {
//extern void * pcbStartAddress;
//extern void * __end;
#ifndef ASM_OFF
void* data_struct_start_addr = &__end;
#else
// since __end undefined on my machine
// 1 << 10 = 2^{20} B = 1 MB since OS needs 1 MB of space
//void* __start = malloc(1<<20);
void* __start = malloc(1<<(10+5)); // 32 k
void* data_struct_start_addr = __start;
//
#endif
// ================================================================
// Initialize hardware, then interrupts
init_swi_handler();
init_timer_interrupt();
init_uart_interrupt();
// ================================================================
// Global variables initialize
// me: do we need to initialize them here? We could just set these default values when they are declared
pcbcnt = 0;
envlcnt = 0;
clock_state = FALSE; // ie. OFF
currtime = 0;
cmd_table_cnt = 0;
delaySend = FALSE;
delaytime = 0;
// ================================================================
// Data structures allocation
void* data_struct_end_addr = data_struct_start_addr;
// note: these priority queues fixed to 5 levels
int pcb_pdeque_size = sizeof(pcb_deque)*NUM_PRIORITY;
int a = 0;
for(; a<NUM_PRIORITY; a++) {
blocked_on_receive_queue[a].head = NULL;
blocked_on_receive_queue[a].tail = NULL;
blocked_on_memory_queue[a].head = NULL;
blocked_on_memory_queue[a].tail = NULL;
ready_queue[a].head = NULL;
ready_queue[a].tail = NULL;
}
// blocked_on_receive_queue = (pcb_deque*)data_struct_end_addr;
data_struct_end_addr += pcb_pdeque_size;
// blocked_on_memory_queue = (pcb_deque*)data_struct_end_addr;
data_struct_end_addr += pcb_pdeque_size;
// ready_queue = (pcb_deque*)data_struct_end_addr;
data_struct_end_addr += pcb_pdeque_size;
int envl_deque_size = sizeof(envl_deque);
free_mem_queue = data_struct_end_addr;
free_mem_queue->head = NULL;
free_mem_queue->tail = NULL;
free_mem_queue_cnt = 0;
data_struct_end_addr += envl_deque_size;
blocked_mem_queue = data_struct_end_addr;
blocked_mem_queue->head = NULL;
blocked_mem_queue->tail = NULL;
blocked_mem_queue_cnt = 0;
data_struct_end_addr += envl_deque_size;
delay_send_queue = data_struct_end_addr;
delay_send_queue->head = NULL;
delay_send_queue->tail = NULL;
delay_send_queue_cnt = 0;
data_struct_end_addr += envl_deque_size;
// ================================================================
// PCB allocation
void* pcb_start_addr = data_struct_end_addr +2;
// Fill table with addresses of PCBs
int pcb_size = sizeof(pcb);
int i = 0;
for(; i<DEFAULT_PCBCNT; i++) {
pcb_table[i] = (pcb_start_addr +(pcb_size * i));
}
void* pcb_end_addr = (pcb_start_addr +(pcb_size * i));
// ================================================================
// Memory (envelopes) allocation
void* envl_start_addr = pcb_end_addr +2;
int envl_size = sizeof(envl);
int j = 0;
envl* new_envl = NULL;
for(; j<DEFAULT_ENVLCNT; j++) {
// allocating envelopes sequentially
new_envl = (envl*)(envl_start_addr +(envl_size * j));
// keeping track of them through the table
envl_table[j] = new_envl;
++envlcnt;
// enque all envelopes onto the free_mem_queue
enque_onto_free_mem_queue(new_envl);
envl_clear(new_envl);
}
void* envl_end_addr = (envl_start_addr +(envl_size * j));
// ================================================================
// Process stack allocation
void* proc_stack_start_addr = envl_end_addr +2;
void* proc_stack_end_addr = proc_stack_start_addr;
int proc_stack_size = 1<<15; // 32 kiB// todo: find out size of actual process stack
int k = 0;
// assume pcbcnt = 0 here
#ifdef _RTX_EVAL_
// for automated test processes
// allocate stacks and pcbs
setTestProcs();
for(; k<NUM_TEST_PROCS; k++) {
pcb_set_stack_start_addr(pcb_table[pcbcnt],proc_stack_end_addr);
proc_stack_end_addr += RTXEVAL_TEST_PROCS[pcbcnt].stacksize; // note: it is an error to add two void* (they should be cast to int or something first)
pcb_set_stack_end_addr(pcb_table[pcbcnt],proc_stack_end_addr);
proc_stack_end_addr += 4 +2; // the "buffer" space between stacks (me: I don't think any address is longer than long)
clear_block(pcb_get_stack_start_addr(pcb_table[pcbcnt]), pcb_get_stack_end_addr(pcb_table[pcbcnt]));
pcb_set_stack_pointer(pcb_table[pcbcnt], pcb_get_stack_end_addr(pcb_table[pcbcnt]));
//
pcb_table[pcbcnt]->pid = RTXEVAL_TEST_PROCS[pcbcnt].pid;
pcb_table[pcbcnt]->priority = RTXEVAL_TEST_PROCS[k].priority;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
pcb_table[pcbcnt]->stack_size = RTXEVAL_TEST_PROCS[k].stacksize;
enque_onto_ready_queue(pcb_table[pcbcnt], pcb_get_priority(pcb_table[pcbcnt]));
pcb_set_code_pointer(pcb_table[pcbcnt], RTXEVAL_TEST_PROCS[k].rtxeval_proc_entry);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
}
// assuming NUM_TEST_PROCS == 6
pcb_table[0]->name = "rtx_test1";
pcb_table[1]->name = "rtx_test2";
pcb_table[2]->name = "rtx_test3";
pcb_table[3]->name = "rtx_test4";
pcb_table[4]->name = "rtx_test5";
pcb_table[5]->name = "rtx_test6";
// assert k == NUM_TEST_PROCS
// assert pcbcnt = NUM_TEST_PROCS
#endif
for(; k < DEFAULT_PCBCNT; k++) {
/*
note:
end of block k: N
start of block k +1: N + buffer size +1
This means that anything in the address range [N +1, N +buffer size] does not belong to any process, and should not be written to. This also implies that at least 1 byte will seperate the boundry between the end of block k and the start of block k +1.
For reasons of simplier math I think, the actual contents of the boundry locations should not be used. Therefore, [N, N +buffer size +1] should be used by nobody (me: OR perhaps those 1 bytes (me: >1?) should be occupied with some sorta of special boundry byte sequence or something like that.
*/
pcb_set_stack_start_addr(pcb_table[k],proc_stack_end_addr);
proc_stack_end_addr += (proc_stack_size * (k +1)); // note: it is an error to add two void* (they should be cast to int or something first)
pcb_set_stack_end_addr(pcb_table[k],proc_stack_end_addr);
proc_stack_end_addr += 4 +2; // the "buffer" space between stacks (me: I don't think any address is longer than long)
clear_block(pcb_get_stack_start_addr(pcb_table[k]), pcb_get_stack_end_addr(pcb_table[k]));
pcb_set_stack_pointer(pcb_table[k], pcb_get_stack_end_addr(pcb_table[k])); // start at bottom
}
// void* proc_stack_end_addr = (proc_stack_start_addr +(proc_stack_size * k));
// ================================================================
// Reserved space allocation
// ================================================================
// Initialize PCBs
pcb_table[pcbcnt]->pid = NULL_PROCESS_PID;
pcb_table[pcbcnt]->name = "Null process";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_4;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
pcb_enque(pcb_table[pcbcnt], &ready_queue[PRIORITY_LEVEL_4]);
pcb_set_code_pointer(pcb_table[pcbcnt], &null_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
/*
pcb_table[pcbcnt]->pid = TEST_1_PID;
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &test_1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
*/
// PIDs 1-6 reserved for testing processes
pcb_table[pcbcnt]->pid = A1_PID;
pcb_table[pcbcnt]->name = "A1";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_a1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = B1_PID;
pcb_table[pcbcnt]->name = "B1";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_b1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = C1_PID;
pcb_table[pcbcnt]->name = "C1";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_c1);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = A2_PID;
pcb_table[pcbcnt]->name = "A2";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_a2);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = B2_PID;
pcb_table[pcbcnt]->name = "B2";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_b2);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = C2_PID;
pcb_table[pcbcnt]->name = "C2";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_c2);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = A3_PID;
pcb_table[pcbcnt]->name = "A3";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_3;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &process_a3);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = KCD_PID;
pcb_table[pcbcnt]->name = "KCD";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_0);
pcb_set_code_pointer(pcb_table[pcbcnt], &keyboard_command_decoder);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = CRT_DISPLAY_PID;
pcb_table[pcbcnt]->name = "CRT";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
pcb_table[pcbcnt]->messages.tail = NULL;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_0);
pcb_set_code_pointer(pcb_table[pcbcnt], &crt_display);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = TIMER_I_PID;
pcb_table[pcbcnt]->name = "Timer";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = TRUE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40802700;
//enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &timer_i_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = UART_I_PID;
pcb_table[pcbcnt]->name = "UART";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_0;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = TRUE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40802700;
//enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_3);
pcb_set_code_pointer(pcb_table[pcbcnt], &uart_i_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = SPC_PID;
pcb_table[pcbcnt]->name = "SPC";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_1;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_1);
pcb_set_code_pointer(pcb_table[pcbcnt], &set_priority_command_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
pcb_table[pcbcnt]->pid = WALL_CLOCK_PID;
pcb_table[pcbcnt]->name = "Wall clock";
pcb_table[pcbcnt]->priority = PRIORITY_LEVEL_1;
pcb_table[pcbcnt]->state = READY;
pcb_table[pcbcnt]->i_process = FALSE;
pcb_table[pcbcnt]->messages.head = NULL;
pcb_table[pcbcnt]->messages.tail = NULL;
pcb_table[pcbcnt]->exception_stack_frame = 0x40800000;
enque_onto_ready_queue(pcb_table[pcbcnt], PRIORITY_LEVEL_1);
pcb_set_code_pointer(pcb_table[pcbcnt], &wall_clock_display_process);
set_initial_stack_state(pcb_table[pcbcnt]);
pcbcnt++;
//current_process = get_pcb(NULL_PROCESS_PID);