mouse.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #include "mouse.h"
  2. #include "../interrupt/apic/apic.h"
  3. #include "../../mm/mm.h"
  4. #include "../../mm/slab.h"
  5. #include "../../common/printk.h"
  6. #include "../../common/kprint.h"
  7. static struct mouse_input_buffer *mouse_buf_ptr = NULL;
  8. static int c = 0;
  9. struct apic_IO_APIC_RTE_entry mouse_entry;
  10. static unsigned char mouse_id = 0;
  11. /**
  12. * @brief 清空缓冲区
  13. *
  14. */
  15. static void mouse_clear_buf()
  16. {
  17. mouse_buf_ptr->ptr_head = mouse_buf_ptr->buffer;
  18. mouse_buf_ptr->ptr_tail = mouse_buf_ptr->buffer;
  19. mouse_buf_ptr->count = 0;
  20. memset(mouse_buf_ptr->buffer, 0, mouse_buffer_size);
  21. }
  22. /**
  23. * @brief 从缓冲队列中获取鼠标数据字节
  24. * @return 鼠标数据包的字节
  25. * 若缓冲队列为空则返回-1024
  26. */
  27. static int mouse_get_scancode()
  28. {
  29. // 缓冲队列为空
  30. if (mouse_buf_ptr->count == 0)
  31. while (!mouse_buf_ptr->count)
  32. nop();
  33. if (mouse_buf_ptr->ptr_tail == mouse_buf_ptr->buffer + mouse_buffer_size)
  34. mouse_buf_ptr->ptr_tail = mouse_buf_ptr->buffer;
  35. int ret = (int)((char)(*(mouse_buf_ptr->ptr_tail)));
  36. --(mouse_buf_ptr->count);
  37. ++(mouse_buf_ptr->ptr_tail);
  38. // printk("count=%d", mouse_buf_ptr->count);
  39. return ret;
  40. }
  41. /**
  42. * @brief 鼠标中断处理函数(中断上半部)
  43. * 将数据存入缓冲区
  44. * @param irq_num 中断向量号
  45. * @param param 参数
  46. * @param regs 寄存器信息
  47. */
  48. void mouse_handler(ul irq_num, ul param, struct pt_regs *regs)
  49. {
  50. // 读取鼠标输入的信息
  51. unsigned char x = io_in8(PORT_KEYBOARD_DATA);
  52. // 当头指针越过界时,恢复指向数组头部
  53. if (mouse_buf_ptr->ptr_head == mouse_buf_ptr->buffer + mouse_buffer_size)
  54. mouse_buf_ptr->ptr_head = mouse_buf_ptr->buffer;
  55. if (mouse_buf_ptr->count >= mouse_buffer_size)
  56. {
  57. // kwarn("mouse input buffer is full.");
  58. // return;
  59. }
  60. *mouse_buf_ptr->ptr_head = x;
  61. ++(mouse_buf_ptr->count);
  62. ++(mouse_buf_ptr->ptr_head);
  63. //printk("c=%d\tval = %d\n", ++c, x);
  64. }
  65. hardware_intr_controller mouse_intr_controller =
  66. {
  67. .enable = apic_ioapic_enable,
  68. .disable = apic_ioapic_disable,
  69. .install = apic_ioapic_install,
  70. .uninstall = apic_ioapic_uninstall,
  71. .ack = apic_ioapic_edge_ack,
  72. };
  73. /**
  74. * @brief 从键盘控制器读取mouse id
  75. *
  76. * @return unsigned char 鼠标id
  77. */
  78. static unsigned char mouse_get_mouse_ID()
  79. {
  80. // 读取鼠标的ID
  81. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  82. wait_keyboard_write();
  83. io_out8(PORT_KEYBOARD_DATA, MOUSE_GET_ID);
  84. wait_keyboard_write();
  85. mouse_id = io_in8(PORT_KEYBOARD_DATA);
  86. for (int i = 0; i < 1000; i++)
  87. for (int j = 0; j < 1000; j++)
  88. nop();
  89. return mouse_id;
  90. }
  91. /**
  92. * @brief 设置鼠标采样率
  93. *
  94. * @param hz 采样率
  95. */
  96. int mouse_set_sample_rate(unsigned int hz)
  97. {
  98. switch (hz)
  99. {
  100. case 10:
  101. case 20:
  102. case 40:
  103. case 60:
  104. case 80:
  105. case 100:
  106. case 200:
  107. wait_keyboard_write();
  108. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  109. wait_keyboard_write();
  110. io_out8(PORT_KEYBOARD_DATA, MOUSE_SET_SAMPLING_RATE);
  111. wait_keyboard_write();
  112. for (int i = 0; i < 1000; i++)
  113. for (int j = 0; j < 1000; j++)
  114. nop();
  115. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  116. wait_keyboard_write();
  117. io_out8(PORT_KEYBOARD_DATA, hz);
  118. for (int i = 0; i < 1000; i++)
  119. for (int j = 0; j < 1000; j++)
  120. nop();
  121. wait_keyboard_write();
  122. break;
  123. default:
  124. return EINVALID_ARGUMENT;
  125. break;
  126. }
  127. return SUCCESS;
  128. }
  129. /**
  130. * @brief 使鼠标支持滚轮
  131. * 该模式下,鼠标ID=3
  132. */
  133. static int mouse_enable_scroll_wheel()
  134. {
  135. if (mouse_id == 3)
  136. return SUCCESS;
  137. mouse_set_sample_rate(200);
  138. mouse_set_sample_rate(100);
  139. mouse_set_sample_rate(80);
  140. if (mouse_get_mouse_ID() != 3)
  141. {
  142. kerror("Cannot set mouse ID to 3");
  143. return EFAIL;
  144. }
  145. // 清空缓冲区,防止解析时产生错误
  146. mouse_clear_buf();
  147. return SUCCESS;
  148. }
  149. /**
  150. * @brief 使鼠标支持5键
  151. * 该模式下ID=4
  152. */
  153. static int mouse_enable_5keys()
  154. {
  155. if (mouse_id == 4)
  156. return SUCCESS;
  157. // 根据规范,应当先启用ID=3
  158. mouse_enable_scroll_wheel();
  159. mouse_set_sample_rate(200);
  160. mouse_set_sample_rate(200);
  161. mouse_set_sample_rate(80);
  162. if (mouse_get_mouse_ID() != 4)
  163. {
  164. kerror("Cannot set mouse ID to 4");
  165. return EFAIL;
  166. }
  167. // 清空缓冲区,防止解析时产生错误
  168. mouse_clear_buf();
  169. return SUCCESS;
  170. }
  171. /**
  172. * @brief 初始化鼠标驱动程序
  173. *
  174. */
  175. void mouse_init()
  176. {
  177. // 初始化鼠标读入队列缓冲区
  178. mouse_buf_ptr = (struct mouse_input_buffer *)kmalloc(sizeof(struct mouse_input_buffer), 0);
  179. mouse_buf_ptr->ptr_head = mouse_buf_ptr->buffer;
  180. mouse_buf_ptr->ptr_tail = mouse_buf_ptr->buffer;
  181. mouse_buf_ptr->count = 0;
  182. memset(mouse_buf_ptr->buffer, 0, mouse_buffer_size);
  183. // ======== 初始化中断RTE entry ==========
  184. mouse_entry.vector = MOUSE_INTR_VECTOR; // 设置中断向量号
  185. mouse_entry.deliver_mode = IO_APIC_FIXED; // 投递模式:混合
  186. mouse_entry.dest_mode = DEST_PHYSICAL; // 物理模式投递中断
  187. mouse_entry.deliver_status = IDLE;
  188. mouse_entry.trigger_mode = EDGE_TRIGGER; // 设置边沿触发
  189. mouse_entry.polarity = POLARITY_HIGH; // 高电平触发
  190. mouse_entry.remote_IRR = IRR_RESET;
  191. mouse_entry.mask = MASKED;
  192. mouse_entry.reserved = 0;
  193. mouse_entry.destination.physical.reserved1 = 0;
  194. mouse_entry.destination.physical.reserved2 = 0;
  195. mouse_entry.destination.physical.phy_dest = 0; // 设置投递到BSP处理器
  196. // 注册中断处理程序
  197. irq_register(MOUSE_INTR_VECTOR, &mouse_entry, &mouse_handler, (ul)mouse_buf_ptr, &mouse_intr_controller, "ps/2 mouse");
  198. wait_keyboard_write();
  199. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_ENABLE_MOUSE_PORT); // 开启鼠标端口
  200. for (int i = 0; i < 1000; i++)
  201. for (int j = 0; j < 1000; j++)
  202. nop();
  203. wait_keyboard_write();
  204. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  205. wait_keyboard_write();
  206. io_out8(PORT_KEYBOARD_DATA, MOUSE_ENABLE); // 允许鼠标设备发送数据包
  207. for (int i = 0; i < 1000; i++)
  208. for (int j = 0; j < 1000; j++)
  209. nop();
  210. wait_keyboard_write();
  211. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_WRITE);
  212. wait_keyboard_write();
  213. io_out8(PORT_KEYBOARD_DATA, KEYBOARD_PARAM_INIT); // 设置键盘控制器
  214. for (int i = 0; i < 1000; i++)
  215. for (int j = 0; j < 1000; j++)
  216. nop();
  217. wait_keyboard_write();
  218. mouse_enable_5keys();
  219. mouse_get_mouse_ID();
  220. kdebug("mouse ID:%d", mouse_id);
  221. c = 0;
  222. }
  223. /**
  224. * @brief 卸载鼠标驱动程序
  225. *
  226. */
  227. void mouse_exit()
  228. {
  229. irq_unregister(MOUSE_INTR_VECTOR);
  230. kfree((ul *)mouse_buf_ptr);
  231. }
  232. /**
  233. * @brief 获取鼠标数据包
  234. *
  235. * @param packet 数据包的返回值
  236. * @return int 错误码
  237. */
  238. int mouse_get_packet(void *packet)
  239. {
  240. if (mouse_buf_ptr->count != 0)
  241. kdebug("at get packet: count=%d", mouse_buf_ptr->count);
  242. int code = 0;
  243. switch (mouse_id)
  244. {
  245. case 0: // 3bytes 数据包
  246. if (mouse_buf_ptr->count < 3)
  247. return EFAIL;
  248. do
  249. {
  250. code = mouse_get_scancode();
  251. ((struct mouse_packet_3bytes *)packet)->byte0 = (unsigned char)code;
  252. } while (code == -1024);
  253. do
  254. {
  255. code = mouse_get_scancode();
  256. ((struct mouse_packet_3bytes *)packet)->movement_x = (char)code;
  257. } while (code == -1024);
  258. do
  259. {
  260. code = mouse_get_scancode();
  261. ((struct mouse_packet_3bytes *)packet)->movement_y = (char)code;
  262. } while (code == -1024);
  263. return SUCCESS;
  264. break;
  265. case 3: // 4bytes数据包
  266. case 4:
  267. if (mouse_buf_ptr->count < 4)
  268. return EFAIL;
  269. do
  270. {
  271. code = mouse_get_scancode();
  272. ((struct mouse_packet_4bytes *)packet)->byte0 = (unsigned char)code;
  273. } while (code == -1024);
  274. do
  275. {
  276. code = mouse_get_scancode();
  277. ((struct mouse_packet_4bytes *)packet)->movement_x = (char)code;
  278. } while (code == -1024);
  279. do
  280. {
  281. code = mouse_get_scancode();
  282. ((struct mouse_packet_4bytes *)packet)->movement_y = (char)code;
  283. } while (code == -1024);
  284. do
  285. {
  286. code = mouse_get_scancode();
  287. ((struct mouse_packet_4bytes *)packet)->byte3 = (char)code;
  288. } while (code == -1024);
  289. return SUCCESS;
  290. break;
  291. default: // Should not reach here
  292. kBUG("mouse_get_packet(): Invalid mouse_id!");
  293. return EFAIL;
  294. break;
  295. }
  296. return SUCCESS;
  297. }