From 94c8335cd157ffe2f83bfea58cb19fa50251925e Mon Sep 17 00:00:00 2001
From: Zefan Xu <zefanxu2@illinois.edu>
Date: Wed, 11 May 2016 00:13:19 -0500
Subject: [PATCH] change mouse driver, add malloc file

---
 student-distrib/interrupt_wrapper.S |  12 ++-
 student-distrib/interrupt_wrapper.h |   1 +
 student-distrib/kernel.c            |  24 ++++--
 student-distrib/keyboard_handler.c  |   2 +-
 student-distrib/keyboard_handler.h  |   1 +
 student-distrib/malloc.c            |  48 ++++++++++++
 student-distrib/malloc.h            |   8 ++
 student-distrib/mousedriver.c       | 116 ++++++++++++++++++++++++++++
 student-distrib/mousedriver.h       |  53 +++++++++++++
 student-distrib/paging.c            |  34 ++++----
 student-distrib/systemcall.c        |  12 +--
 student-distrib/systemcall.h        |   2 +-
 12 files changed, 280 insertions(+), 33 deletions(-)
 create mode 100644 student-distrib/malloc.c
 create mode 100644 student-distrib/malloc.h
 create mode 100644 student-distrib/mousedriver.c
 create mode 100644 student-distrib/mousedriver.h

diff --git a/student-distrib/interrupt_wrapper.S b/student-distrib/interrupt_wrapper.S
index 5cf92db..acfcfb0 100644
--- a/student-distrib/interrupt_wrapper.S
+++ b/student-distrib/interrupt_wrapper.S
@@ -1,6 +1,6 @@
 .text # The text section is used for keeping the actual code
 
-.global rtc_wrapper, keyboard_wrapper, schedule_wrapper
+.global rtc_wrapper, keyboard_wrapper, schedule_wrapper, mouse_wrapper
 
 # saves all registers and flags before rtc_handler, restores all registers and flags after
 rtc_wrapper:
@@ -36,6 +36,16 @@ schedule_wrapper:
 
 	iret
 
+mouse_wrapper:
+	cli
+	pushal
+	pushfl
+	call mouse_handler
+	popfl
+	popal
+	sti
+
+	iret
 
 
 
diff --git a/student-distrib/interrupt_wrapper.h b/student-distrib/interrupt_wrapper.h
index 4ff6aae..1d59a3a 100644
--- a/student-distrib/interrupt_wrapper.h
+++ b/student-distrib/interrupt_wrapper.h
@@ -5,6 +5,7 @@
 extern void rtc_wrapper(void);
 extern void keyboard_wrapper(void);
 extern void schedule_wrapper(void);
+extern void mouse_wrapper(void);
 
 
 #endif
diff --git a/student-distrib/kernel.c b/student-distrib/kernel.c
index 92fa306..369004f 100644
--- a/student-distrib/kernel.c
+++ b/student-distrib/kernel.c
@@ -1,7 +1,3 @@
-/* kernel.c - the C part of the kernel
- * vim:ts=4 noexpandtab
- */
-
 #include "multiboot.h"
 #include "debug.h"
 #include "x86_desc.h"
@@ -19,6 +15,7 @@
 #include "filesystem.h"
 #include "schedule.h"
 #include "pit.h"
+#include "mousedriver.h"
 
 /* Macros. */
 /* Check if the bit BIT in FLAGS is set. */
@@ -27,8 +24,10 @@
 #define EXCEPTION_NUM 0x20
 #define RTC_ENTRY 0x28
 #define KEYBRD_ENTRY 0x21
+#define MOUSE_ENTRY 0x2c
 #define SYSCALL_ENTRY 0X80
 #define PIT_ENTRY 0x20
+#define MOUSE_IRQ 0xc
 
 extern void init_rtc();
 extern void init_exception(void);
@@ -205,6 +204,19 @@ entry (unsigned long magic, unsigned long addr)
 	//set offset_31_16 and offset_15_00 for the first 20 entries of the idt
 	SET_IDT_ENTRY(idt[KEYBRD_ENTRY], keyboard_wrapper);   // set idt entry for keyboard
 
+		// set idt entry for keyboard
+	idt[MOUSE_ENTRY].seg_selector = KERNEL_CS;   // set up elements in the keyboard entry
+	idt[MOUSE_ENTRY].reserved4 = 0;			
+	idt[MOUSE_ENTRY].reserved3 = 0;		
+	idt[MOUSE_ENTRY].reserved2 = 1;
+	idt[MOUSE_ENTRY].reserved1 = 1;
+	idt[MOUSE_ENTRY].size = 1;
+	idt[MOUSE_ENTRY].reserved0 = 0;
+	idt[MOUSE_ENTRY].dpl = 0;          
+	idt[MOUSE_ENTRY].present = 1;
+	//set offset_31_16 and offset_15_00 for the first 20 entries of the idt
+	SET_IDT_ENTRY(idt[MOUSE_ENTRY], mouse_wrapper);   // set idt entry for keyboard
+
 	//set offset_31_16 and offset_15_00 for the first 20 entries of the idt
 	idt[RTC_ENTRY].seg_selector = KERNEL_CS;   // set up elements in the RTC entry
 	idt[RTC_ENTRY].reserved4 = 0;			
@@ -251,6 +263,7 @@ entry (unsigned long magic, unsigned long addr)
 	paging_init();    // set up paging
 	rtc_initialization();     // init rtc  
 	keybrd_init();	// init keyboard
+	init_mouse();
 	pit_initialization();		// initialize pit
 	initialize_schedule();	// init schedule
 
@@ -258,7 +271,7 @@ entry (unsigned long magic, unsigned long addr)
 
 	// process initialization
 	for(i = 0; i < 6; i++){
-		running_proc_stat[i] = 0;
+		pid_status[i] = 0;
 	}
 	pid = -1;
 
@@ -267,6 +280,7 @@ entry (unsigned long magic, unsigned long addr)
 	enable_irq(8);   
 	enable_irq(1);  
 	enable_irq(0);
+	enable_irq(MOUSE_IRQ);
 	sti();
 
 	while(1){
diff --git a/student-distrib/keyboard_handler.c b/student-distrib/keyboard_handler.c
index cdd014a..eebe437 100644
--- a/student-distrib/keyboard_handler.c
+++ b/student-distrib/keyboard_handler.c
@@ -6,7 +6,7 @@
 #include "pit.h"
 #include "schedule.h"
 #include "systemcall.h"
-#include "lib.h"
+
 
 #define KEYBRD_DATA_PORT 0x60
 #define BUFF_END '\0'
diff --git a/student-distrib/keyboard_handler.h b/student-distrib/keyboard_handler.h
index fecff46..4cc3afe 100644
--- a/student-distrib/keyboard_handler.h
+++ b/student-distrib/keyboard_handler.h
@@ -10,6 +10,7 @@ extern uint32_t terminal_id;
 
 
 extern void keyboard_handler(void);
+void switch_terminal (uint32_t target_screen, uint32_t screen_size);
 
 		/* reset mouse device */
 #define VIDEO 0xB8000
diff --git a/student-distrib/malloc.c b/student-distrib/malloc.c
new file mode 100644
index 0000000..be75420
--- /dev/null
+++ b/student-distrib/malloc.c
@@ -0,0 +1,48 @@
+#include "lib.h"
+#include "types.h"
+
+#define DYNAMIC_ADDR_START 0x0800000
+#define KB_1 1024
+#define KB_4 0x1000
+
+uint8_t dynamic_memory_table[KB_4];
+
+void init_dynamic_memory() {
+	int i = 0;
+	for (i = 0; i < KB_4; i++) {
+		//set all dynamic space to be unallocated
+		dynamic_memory_table[i] = 0;
+	}
+}
+
+uint32_t * malloc(uint32_t size) {
+	uint8_t KB_size = (uint8_t)((size / KB_1) + 1);
+	int new_index = 0;
+	int check_space_index, check_space_flag;
+	while (new_index < KB_4) {
+		if (!dynamic_memory_table[new_index]) 
+			new_index += dynamic_memory_table[new_index];
+		else {
+			//check if we have enough consecutive availble space
+			check_space_flag = 0;
+			for (check_space_index = new_index; check_space_index < new_index + KB_size; check_space_index++) {
+				if (dynamic_memory_table[check_space_index]) check_space_flag = 1;
+			}
+			if (!check_space_flag)
+				break;
+		}
+	}
+	//all the space has been allocated
+	if (new_index >= KB_4) return NULL;
+
+	dynamic_memory_table[new_index] = KB_size;
+
+	return (uint32_t*)(DYNAMIC_ADDR_START + KB_size * KB_1);
+}
+
+uint32_t free(uint32_t * arg){
+	int index = (((uint32_t)arg) - DYNAMIC_ADDR_START) / KB_1;
+	dynamic_memory_table[index] = 0;
+	return 0;
+}
+
diff --git a/student-distrib/malloc.h b/student-distrib/malloc.h
new file mode 100644
index 0000000..c3e00a7
--- /dev/null
+++ b/student-distrib/malloc.h
@@ -0,0 +1,8 @@
+#ifndef _MALLOC_H
+#define _MALLOC_H
+
+void init_dynamic_memory();
+uint32_t * malloc(uint32_t size);
+uint32_t free(uint32_t * arg);
+
+#endif
diff --git a/student-distrib/mousedriver.c b/student-distrib/mousedriver.c
new file mode 100644
index 0000000..2be0796
--- /dev/null
+++ b/student-distrib/mousedriver.c
@@ -0,0 +1,116 @@
+#include "mousedriver.h"
+
+
+pos_t mouse;
+// statue register has to be set before read data
+uint8_t read_mouse() {
+	while((inb(STATUS_REGISTER)&0x1)==0)
+		;
+	return inb(MOUSE_PORT);
+}
+
+void move (int32_t dx, int32_t dy)
+{
+	mouse.x += dx/2;
+	if(mouse.x <= 0)
+		mouse.x = 0;
+	if(mouse.x >= 79)
+		mouse.x = 79;
+	mouse.y -= dy/2;
+	if(mouse.y <= 0)
+		mouse.y = 0;
+	if(mouse.y >= 24)
+		mouse.y = 24;
+	update_cursor(mouse.y,mouse.x);
+
+
+}
+
+//status register must be cleared before write data
+/*Sending a command or data byte to the mouse (to port 0x60) must be preceded by
+sending a 0xD4 byte to port 0x64 (with appropriate waits on port 0x64, bit 1, 
+before sending each output byte). Note: this 0xD4 byte does not generate any
+ACK, from either the keyboard or mouse.*/
+void write_mouse(uint8_t data, uint8_t port){
+	while((inb(STATUS_REGISTER)& 0x2) !=0)
+		;
+	//need to write D4 before command
+	outb(0xD4, STATUS_REGISTER);
+
+	while((inb(STATUS_REGISTER)& 0x2) !=0)
+		;
+	outb(data, port);
+	//printf("!!!!!!\n");
+}
+
+
+extern void mouse_handler()
+{
+	
+	//cli();
+	uint8_t package;
+	if ((inb(STATUS_REGISTER) & 0x1) ==0)
+		package = 0;
+	else
+		package = inb(MOUSE_PORT);
+
+	if(package != 0)
+	{	
+		if(package == 0xFA) //ack
+			;
+		else
+		{
+			 if ((package&MOVEMENT_ONE)!=0 && (package&X_OVERFLOW)==0 && (package&Y_OVERFLOW)==0)
+			{
+				int32_t dx = read_mouse();
+				if (package & X_SIGN)
+					dx |= 0xFFFFFF00;
+				int32_t dy = read_mouse();
+				if (package & Y_SIGN)
+					dy |= 0xFFFFFF00;  
+				move(dx, dy);
+			}
+		}
+
+	}
+	send_eoi(MOUSE_IRQ);
+	//sti();
+	return;
+}
+
+void init_mouse()
+{
+	write_mouse(0xFF, MOUSE_PORT);//reset the mouse
+	write_mouse(0x20, STATUS_REGISTER);//send "Get Compaq Status Byte" command
+
+	uint8_t compaq_status  = read_mouse();
+
+	compaq_status |= 0x2; //enable IRQ12
+	compaq_status &= 0xDF; //clear disable mouse click
+	
+
+	write_mouse(0x60, STATUS_REGISTER);//set compaq status
+	while ((inb(STATUS_REGISTER) & 0x2) !=0)
+		;
+
+	//write compaq status byte back
+	outb(compaq_status, MOUSE_PORT);
+
+	mouse.x = 0;
+	mouse.y = 0;
+	//enable package streaming
+
+	write_mouse(0xF4, MOUSE_PORT);
+	write_mouse(0xF3, MOUSE_PORT);
+	read_mouse(); //ack
+	write_mouse(200, MOUSE_PORT);
+
+	write_mouse(0xE8, MOUSE_PORT);
+	read_mouse();
+	//write_mouse(0x03, MOUSE_PORT);
+	//printf("stuck1\n");
+
+}
+
+
+
diff --git a/student-distrib/mousedriver.h b/student-distrib/mousedriver.h
new file mode 100644
index 0000000..77c700f
--- /dev/null
+++ b/student-distrib/mousedriver.h
@@ -0,0 +1,53 @@
+#ifndef _MOUSEDRIVER_H
+#define _MOUSEDRIVER_H
+
+#include "lib.h"
+#include "x86_desc.h"
+#include "types.h"
+#include "i8259.h"
+#include "keyboard_handler.h"
+#include "terminal.h"
+
+
+//init value of mouse package
+#define MOUSE_PORT 0x60
+#define STATUS_REGISTER 0x64
+#define MOUSE_IRQ 0xc
+//#define MOUSE_ID 1
+#define LEFT_BUTTON (1 << 0)
+#define RIGHT_BUTTON (1 << 1)
+#define MIDDLE_BUTTON (1 << 2)
+#define MOVEMENT_ONE (1 << 3)//always 1
+#define X_SIGN (1 << 4)
+#define Y_SIGN (1 << 5)
+#define X_OVERFLOW (1 << 6)
+#define Y_OVERFLOW (1 << 7)
+
+/*
+ * PS/2 Response Codes
+ */
+#define PS2_RESP_BAT_PASSED     0xAA    /* Returned after reset, when self test succeeds. */
+#define PS2_RESP_BAT_FAILED     0xFC    /* Returned after reset, when self test fails */
+#define PS2_RESP_ACK            0xFA    /* Acknowledge response. */
+
+
+
+typedef struct position {
+	int32_t x;
+	int32_t y;
+} pos_t;
+
+//static pos_t mouse;
+
+uint8_t read_mouse();
+void move (int32_t dx, int32_t dy);
+void write_mouse(uint8_t data, uint8_t port);
+void mouse_return();
+extern void mouse_handler();
+void init_mouse();
+
+
+#endif
+
+
+
diff --git a/student-distrib/paging.c b/student-distrib/paging.c
index d2d5bae..5f890a7 100644
--- a/student-distrib/paging.c
+++ b/student-distrib/paging.c
@@ -11,8 +11,8 @@
 #define VIDEO_DIR_OFFSET 37
 #define USER_not_present 0x07
 
-uint32_t page_directory[ONEKB] __attribute__((aligned(FOURKB)));
-uint32_t page_table[ONEKB] __attribute__((aligned(FOURKB)));
+uint32_t pd_array[ONEKB] __attribute__((aligned(FOURKB)));
+uint32_t kernel_page_table[ONEKB] __attribute__((aligned(FOURKB)));
 
 /*
 *   void switch_pd(uint32_t addr)
@@ -22,7 +22,7 @@ uint32_t page_table[ONEKB] __attribute__((aligned(FOURKB)));
 */
 void switch_pd(uint32_t addr){
 
-	page_directory[USER_PAGE] = addr | FOURMB_USER; 	//set to user level
+	pd_array[USER_PAGE] = addr | FOURMB_USER; 	//set to user level
 	int32_t cr3;
 	//TLB flusH
 	asm volatile (												
@@ -45,7 +45,7 @@ void switch_pd(uint32_t addr){
 */
 void switch_video_pd(uint32_t addr, int terminal_id){
 
-	page_table[video + terminal_id * 2] = addr | USER_not_present; 	//set to user level
+	kernel_page_table[video + terminal_id * 2] = addr | USER_not_present; 	//set to user level
 	int32_t cr3;
 	//TLB flusH
 	asm volatile (												
@@ -68,32 +68,28 @@ void switch_video_pd(uint32_t addr, int terminal_id){
 */
 void paging_init(){
 
- 	int i;	//for loop index
-
- 	//initialize the page directory with all not present
+ 	int i;	
  	for(i = 0; i < ONEKB; i++){
 
- 		page_directory[i] = not_present;
+ 		pd_array[i] = not_present;
  	}
 
- 	//initialize the page table with all not present except the video memory
  	for(i = 0; i < ONEKB; i++){
 
  		if(i == video)
- 			page_table[i] = (i*FOURKB) | 0x07;
+ 			kernel_page_table[i] = (i*FOURKB) | 0x07;
  		else
- 			page_table[i] = (i*FOURKB) | not_present;
+ 			kernel_page_table[i] = (i*FOURKB) | not_present;
  	}
 
- 	//let first page table to be present in the page directory
- 	page_directory[0] = ((unsigned int)page_table) | 0x07;
+ 	pd_array[0] = ((unsigned int)kernel_page_table) | 0x07;
+
+ 	pd_array[1] = ONEKB * FOURKB | FOURMB_PRESENT; 
+
+	pd_array[2] = 2 * ONEKB * FOURKB | FOURMB_PRESENT; 	
 
- 	//let second page directory to be present, which is kernel
- 	page_directory[1] = ONEKB * FOURKB | FOURMB_PRESENT; //starting from 4 Mb (0x400000) | (0x80 | 0x03)
- 	
- 	//using the asm volatile to output the paging
  	asm volatile (
- 		"movl $page_directory, %%eax 	\n 	\
+ 		"movl $pd_array, %%eax 	\n 	\
  		movl %%eax, %%cr3 				\n	\
  		movl %%cr4, %%eax				\n	\
  		orl $0x00000010, %%eax			\n	\
@@ -102,7 +98,7 @@ void paging_init(){
  		orl $0x80000000, %%eax			\n	\
  		movl %%eax, %%cr0"					\
  		: 									\
- 		: "g"(page_directory)				\
+ 		: "g"(pd_array)				\
  		: "memory", "cc", "eax");			
 
  
diff --git a/student-distrib/systemcall.c b/student-distrib/systemcall.c
index 7a73f01..83ce143 100644
--- a/student-distrib/systemcall.c
+++ b/student-distrib/systemcall.c
@@ -30,7 +30,7 @@ int32_t file_file_op[4] = {(int32_t) file_read, (int32_t) file_write, (int32_t)
 
 int pid = -1;		//indicate the current pid
 uint8_t global_return_status = -1; 	//to store the status
-int running_proc_stat[];
+int pid_status[];
 uint8_t status = 0;
 
 
@@ -53,7 +53,7 @@ int32_t halt (uint8_t status) {
 	pid = curr_process->PID;
 
 	clear_file_descriptors();
-	running_proc_stat[pid] = 0;
+	pid_status[pid] = 0;
 	pid = curr_process->parent;
 	terminal_process_info[current_terminal_id] = pid;
 
@@ -176,8 +176,8 @@ int32_t execute(const uint8_t * command) {
 		temp_pid = terminal_process_info[current_terminal_id];
 		int i;
 		for (i = 0; i < 7; i++) {
-			if (running_proc_stat[i] == 0) {
-				running_proc_stat[i] = 1;
+			if (pid_status[i] == 0) {
+				pid_status[i] = 1;
 				pid = i;
 				break;
 			}
@@ -188,8 +188,8 @@ int32_t execute(const uint8_t * command) {
 		temp_pid = terminal_process_info[terminal_id];
 		int i;
 		for (i = 0; i < 7; i++) {
-			if (running_proc_stat[i] == 0) {
-				running_proc_stat[i] = 1;
+			if (pid_status[i] == 0) {
+				pid_status[i] = 1;
 				pid = i;
 				break;
 			}
diff --git a/student-distrib/systemcall.h b/student-distrib/systemcall.h
index ffafb0f..928e6f7 100644
--- a/student-distrib/systemcall.h
+++ b/student-distrib/systemcall.h
@@ -43,7 +43,7 @@ typedef struct pcb{
 
 int pid;
 uint8_t global;
-int running_proc_stat[7];
+int pid_status[7];
 
 int32_t halt (uint8_t status);
 int32_t execute(const uint8_t * command);
-- 
GitLab