ps2_mouse.c 10 KB

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