|
@@ -3,14 +3,32 @@
|
|
|
#include "../../mm/mm.h"
|
|
|
#include "../../mm/slab.h"
|
|
|
#include "../../common/printk.h"
|
|
|
+#include <filesystem/VFS/VFS.h>
|
|
|
+#include <process/wait_queue.h>
|
|
|
|
|
|
+// 键盘输入缓冲区
|
|
|
static struct ps2_keyboard_input_buffer *kb_buf_ptr = NULL;
|
|
|
+// 缓冲区等待队列
|
|
|
+static wait_queue_node_t ps2_keyboard_wait_queue;
|
|
|
|
|
|
// 功能键标志变量
|
|
|
static bool shift_l, shift_r, ctrl_l, ctrl_r, alt_l, alt_r;
|
|
|
static bool gui_l, gui_r, apps, insert, home, pgup, del, end, pgdn, arrow_u, arrow_l, arrow_d, arrow_r;
|
|
|
static bool kp_forward_slash, kp_en;
|
|
|
|
|
|
+/**
|
|
|
+ * @brief 重置ps2键盘输入缓冲区
|
|
|
+ *
|
|
|
+ * @param kbp 缓冲区对象指针
|
|
|
+ */
|
|
|
+static void ps2_keyboard_reset_buffer(struct ps2_keyboard_input_buffer *kbp)
|
|
|
+{
|
|
|
+ kbp->ptr_head = kb_buf_ptr->buffer;
|
|
|
+ kbp->ptr_tail = kb_buf_ptr->buffer;
|
|
|
+ kbp->count = 0;
|
|
|
+ // 清空输入缓冲区
|
|
|
+ memset(kbp->buffer, 0, ps2_keyboard_buffer_size);
|
|
|
+}
|
|
|
struct apic_IO_APIC_RTE_entry entry;
|
|
|
|
|
|
hardware_intr_controller ps2_keyboard_intr_controller =
|
|
@@ -23,6 +41,120 @@ hardware_intr_controller ps2_keyboard_intr_controller =
|
|
|
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * @brief 打开键盘文件
|
|
|
+ *
|
|
|
+ * @param inode 所在的inode
|
|
|
+ * @param filp 文件指针
|
|
|
+ * @return long
|
|
|
+ */
|
|
|
+long ps2_keyboard_open(struct vfs_index_node_t *inode, struct vfs_file_t *filp)
|
|
|
+{
|
|
|
+ filp->private_data = (void *)kb_buf_ptr;
|
|
|
+ ps2_keyboard_reset_buffer(kb_buf_ptr);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief 关闭键盘文件
|
|
|
+ *
|
|
|
+ * @param inode 所在的inode
|
|
|
+ * @param filp 文件指针
|
|
|
+ * @return long
|
|
|
+ */
|
|
|
+long ps2_keyboard_close(struct vfs_index_node_t *inode, struct vfs_file_t *filp)
|
|
|
+{
|
|
|
+ filp->private_data = NULL;
|
|
|
+ ps2_keyboard_reset_buffer(kb_buf_ptr);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief 键盘io控制接口
|
|
|
+ *
|
|
|
+ * @param inode 所在的inode
|
|
|
+ * @param filp 键盘文件指针
|
|
|
+ * @param cmd 命令
|
|
|
+ * @param arg 参数
|
|
|
+ * @return long
|
|
|
+ */
|
|
|
+long ps2_keyboard_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *filp, uint64_t cmd, uint64_t arg)
|
|
|
+{
|
|
|
+ switch (cmd)
|
|
|
+ {
|
|
|
+ case KEYBOARD_CMD_RESET_BUFFER:
|
|
|
+ ps2_keyboard_reset_buffer(kb_buf_ptr);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief 读取键盘文件的操作接口
|
|
|
+ *
|
|
|
+ * @param filp 文件指针
|
|
|
+ * @param buf 输出缓冲区
|
|
|
+ * @param count 要读取的字节数
|
|
|
+ * @param position 读取的位置
|
|
|
+ * @return long 读取的字节数
|
|
|
+ */
|
|
|
+long ps2_keyboard_read(struct vfs_file_t *filp, char *buf, int64_t count, long *position)
|
|
|
+{
|
|
|
+ // 缓冲区为空则等待
|
|
|
+ if (kb_buf_ptr->count == 0)
|
|
|
+ wait_queue_sleep_on(&ps2_keyboard_wait_queue);
|
|
|
+
|
|
|
+ long counter = kb_buf_ptr->count >= count ? count : kb_buf_ptr->count;
|
|
|
+
|
|
|
+ uint8_t *tail = kb_buf_ptr->ptr_tail;
|
|
|
+
|
|
|
+ // 要读取的部分没有越过缓冲区末尾
|
|
|
+ if (counter <= (kb_buf_ptr->buffer + ps2_keyboard_buffer_size - tail))
|
|
|
+ {
|
|
|
+ copy_to_user(buf, tail, counter);
|
|
|
+ kb_buf_ptr->ptr_tail += counter;
|
|
|
+ }
|
|
|
+ else // 要读取的部分越过了缓冲区的末尾,进行循环
|
|
|
+ {
|
|
|
+ uint64_t tmp = (kb_buf_ptr->buffer + ps2_keyboard_buffer_size - tail);
|
|
|
+ copy_to_user(buf, tail, tmp);
|
|
|
+ copy_to_user(buf, kb_buf_ptr->ptr_head, counter - tmp);
|
|
|
+ kb_buf_ptr->ptr_tail = kb_buf_ptr->ptr_head + (counter - tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+ kb_buf_ptr->count -= counter;
|
|
|
+ return counter;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief 键盘文件写入接口(无作用,空)
|
|
|
+ *
|
|
|
+ * @param filp
|
|
|
+ * @param buf
|
|
|
+ * @param count
|
|
|
+ * @param position
|
|
|
+ * @return long
|
|
|
+ */
|
|
|
+long ps2_keyboard_write(struct vfs_file_t *filp, char *buf, int64_t count, long *position)
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+/**
|
|
|
+ * @brief ps2键盘驱动的虚拟文件接口
|
|
|
+ *
|
|
|
+ */
|
|
|
+struct vfs_file_operations_t ps2_keyboard_fops =
|
|
|
+ {
|
|
|
+ .open = ps2_keyboard_open,
|
|
|
+ .close = ps2_keyboard_close,
|
|
|
+ .ioctl = ps2_keyboard_ioctl,
|
|
|
+ .read = ps2_keyboard_read,
|
|
|
+ .write = ps2_keyboard_write,
|
|
|
+};
|
|
|
+
|
|
|
/**
|
|
|
* @brief 键盘中断处理函数(中断上半部)
|
|
|
* 将数据存入缓冲区
|
|
@@ -49,6 +181,8 @@ void ps2_keyboard_handler(ul irq_num, ul param, struct pt_regs *regs)
|
|
|
*kb_buf_ptr->ptr_head = x;
|
|
|
++(kb_buf_ptr->count);
|
|
|
++(kb_buf_ptr->ptr_head);
|
|
|
+
|
|
|
+ wait_queue_wakeup(&ps2_keyboard_wait_queue, PROC_UNINTERRUPTIBLE);
|
|
|
}
|
|
|
/**
|
|
|
* @brief 初始化键盘驱动程序的函数
|
|
@@ -56,7 +190,7 @@ void ps2_keyboard_handler(ul irq_num, ul param, struct pt_regs *regs)
|
|
|
*/
|
|
|
void ps2_keyboard_init()
|
|
|
{
|
|
|
-
|
|
|
+
|
|
|
// ======= 初始化键盘循环队列缓冲区 ===========
|
|
|
|
|
|
// 申请键盘循环队列缓冲区的内存
|
|
@@ -102,6 +236,8 @@ void ps2_keyboard_init()
|
|
|
alt_l = false;
|
|
|
alt_r = false;
|
|
|
|
|
|
+ wait_queue_init(&ps2_keyboard_wait_queue, NULL);
|
|
|
+
|
|
|
// 注册中断处理程序
|
|
|
irq_register(PS2_KEYBOARD_INTR_VECTOR, &entry, &ps2_keyboard_handler, (ul)kb_buf_ptr, &ps2_keyboard_intr_controller, "ps/2 keyboard");
|
|
|
kdebug("kb registered.");
|