Files
DragonOS/kernel/src/driver/keyboard/ps2_keyboard.c
LoGin 1496ba7b24 进程管理模块重构完成 (#380)
* 添加新版pcb的数据结构 (#273)

* 将pcb中的内容分类,分别加锁 (#305)

* 进程管理重构:完成fork的主体逻辑 (#309)

1.完成fork的主体逻辑
2.将文件系统接到新的pcb上
3.经过思考,暂时弃用signal机制,待进程管理重构完成后,重写signal机制.原因是原本的signal机制太烂了

* chdir getcwd pid pgid ppid (#310)


---------

Co-authored-by: longjin <longjin@RinGoTek.cn>

* 删除旧的fork以及signal的代码,并调整fork/vfork/execve系统调用 (#325)

1.删除旧的fork
2.删除signal相关代码,等进程管理重构结束之后,再重新写.
3.调整了fork/vfork/execve系统调用

* 实现切换进程的代码 (#331)



* 实现切换进程的代码

* Patch modify preempt (#332)

* 修改设置preempt的代码

* 删除rust的list和refcount

* 为每个核心初始化idle进程 (#333)

* 为每个核心初始化idle进程

* 完成了新的内核线程机制 (#335)

* 调度器的pcb替换为新的Arc<ProcessControlBlock>,把调度器队列锁从 RwSpinLock 替换为了 SpinLock (#336)

* 把调度器的pcb替换为新的Arc<ProcessControlBlock>

* 把调度器队列锁从 RwSpinLock 替换为了 SpinLock ,修改了签名以通过编译

* 修正一些双重加锁、细节问题

---------

Co-authored-by: longjin <longjin@RinGoTek.cn>

* github workflow自动检查代码是否格式化

* cache toolchain yml

* 调整rust版本的waitqueue中的pcb为新版的pcb (#343)

* 解决设置rust workspace带来的“工具链不一致”的问题 (#344)


* 解决设置rust workspace带来的“工具链不一致”的问题

更改workflow

* 调整pcb的sched_info和rwlock,以避免调度器死锁问题 (#341)

* 调整pcb的sched_info和rwlock,以避免调度器死锁问题

* 修改为在 WriterGuard 中维护 Irq_guard

* 修正了 write_irqsave方法

* 优化了代码

* 把 set state 操作从 wakup 移动到 sched_enqueue 中

* 修正为在 wakeup 中设置 running ,以保留 set_state 的私有性

* 移除了 process_wakeup

* 实现进程退出的逻辑 (#340)

实现进程退出的逻辑

* 标志进程sleep

* 修复wakeup的问题

---------

Co-authored-by: longjin <longjin@RinGoTek.cn>

* rust 重构 completion (#350)

* 完成了completion的基本结构,待完善上级调用

* 用SpinLock保护结构体并发安全

* 修改原子变量为u32,修复符号错误

* irq guard

* 修改为具有内部可变性的结构体

* temp fix

* 修复了由于进程持有自旋锁导致的不被调度的问题

* 对 complete 系列方法上锁,保护 done 数据并发安全

* 移除了未使用的依赖

* 重写显示刷新驱动 (#363)

* 重构显示刷新驱动

* Patch refactor process management (#366)

* 维护进程树

* 维护进程树

* 更改代码结构

* 新建进程时,设置cwd

* 调整adopt childern函数,降低开销

---------

Co-authored-by: longjin <longjin@RinGoTek.cn>

* waitqueue兼容C部分 (#351)

* PATH

* safe init

* waitqueue兼容C部分

* waitqueue兼容C部分

* 删除semaphore.c,在ps2_keyboard中使用waitqueue

* 删除semaphore.c,在ps2_keyboard中使用waitqueue

* current_pcb的C兼容

* current_pcb的C兼容

* current_pcb的C兼容

* fmt

* current_pcb的兼容

* 针对修改

* 调整代码

* fmt

* 删除pcb的set flags

* 更改函数名

---------

Co-authored-by: longjin <longjin@RinGoTek.cn>

* merge master

* Patch debug process management refactor (#372)

* 能够调通,执行完textui_init

* 能跑到initial kernel thread

* fmt

* 能够正常初始化所有服务(尚未能切换到用户程序)

* 删除部分无用的extern

* 存在问题:ap处理器启动后,bsp的smp_init函数return之后就出错了,怀疑是栈损坏

* 解决smp启动由于未换栈导致的内存访问错误

* debug

* 1

* 1

* lock no preempt

* 调通

* 优化代码,删除一些调试日志

* fix

* 使用rust重写wait4 (#377)

* 维护进程树

* 维护进程树

* 更改代码结构

* 新建进程时,设置cwd

* 调整adopt childern函数,降低开销

* wait4

* 删除c_sys_wait4

* 使用userbuffer保护裸指针

---------

Co-authored-by: longjin <longjin@RinGoTek.cn>

* 消除warning

* 1. 修正未设置cpu executing的问题

* 修正kthread机制可能存在的内存泄露问题

* 删除pcb文档

* 删除C的tss struct

---------

Co-authored-by: Bullet <93781792+GP-Bullet@users.noreply.github.com>
Co-authored-by: Chiichen <39649411+Chiichen@users.noreply.github.com>
Co-authored-by: hanjiezhou <zhouhanjie@dragonos.org>
Co-authored-by: GnoCiYeH <118462160+GnoCiYeH@users.noreply.github.com>
Co-authored-by: houmkh <1119644616@qq.com>
2023-09-15 14:58:19 +08:00

210 lines
5.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ps2_keyboard.h"
#include <driver/interrupt/apic/apic.h>
#include <mm/mm.h>
#include <mm/slab.h>
#include <common/printk.h>
#include <filesystem/vfs/VFS.h>
#include <common/spinlock.h>
#include <common/kfifo.h>
// 键盘输入缓冲区
static struct kfifo_t kb_buf;
extern void ps2_keyboard_register(struct vfs_file_operations_t *);
extern void ps2_keyboard_parse_keycode(uint8_t input);
// 缓冲区读写锁
static spinlock_t ps2_kb_buf_rw_lock;
/**
* @brief 重置ps2键盘输入缓冲区
*
* @param kbp 缓冲区对象指针
*/
static void ps2_keyboard_reset_buffer(struct kfifo_t *kbp)
{
kfifo_reset(kbp);
}
struct apic_IO_APIC_RTE_entry entry;
hardware_intr_controller ps2_keyboard_intr_controller =
{
.enable = apic_ioapic_enable,
.disable = apic_ioapic_disable,
.install = apic_ioapic_install,
.uninstall = apic_ioapic_uninstall,
.ack = apic_ioapic_edge_ack,
};
/**
* @brief 打开键盘文件
*
* @param inode 所在的inode
* @param filp 文件指针
* @return long
*/
long ps2_keyboard_open(struct vfs_index_node_t *inode, struct vfs_file_t *filp)
{
ps2_keyboard_reset_buffer(&kb_buf);
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)
{
ps2_keyboard_reset_buffer(&kb_buf);
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);
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)
{
// 缓冲区为空则等待
while (kfifo_empty(&kb_buf))
;
count = (count > kb_buf.size) ? kb_buf.size : count;
return kfifo_out(&kb_buf, buf, count);
}
/**
* @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 键盘中断处理函数(中断上半部)
* 将数据存入缓冲区
* @param irq_num 中断向量号
* @param param 参数
* @param regs 寄存器信息
*/
void ps2_keyboard_handler(ul irq_num, ul buf_vaddr, struct pt_regs *regs)
{
unsigned char x = io_in8(PORT_PS2_KEYBOARD_DATA);
ps2_keyboard_parse_keycode((uint8_t)x);
}
/**
* @brief 初始化键盘驱动程序的函数
*
*/
void ps2_keyboard_init()
{
// ======= 初始化键盘循环队列缓冲区 ===========
// 初始化键盘循环队列缓冲区
kfifo_alloc(&kb_buf, ps2_keyboard_buffer_size, 0);
// ======== 初始化中断RTE entry ==========
entry.vector = PS2_KEYBOARD_INTR_VECTOR; // 设置中断向量号
entry.deliver_mode = IO_APIC_FIXED; // 投递模式:混合
entry.dest_mode = DEST_PHYSICAL; // 物理模式投递中断
entry.deliver_status = IDLE;
entry.trigger_mode = EDGE_TRIGGER; // 设置边沿触发
entry.polarity = POLARITY_HIGH; // 高电平触发
entry.remote_IRR = IRR_RESET;
entry.mask = MASKED;
entry.reserved = 0;
entry.destination.physical.reserved1 = 0;
entry.destination.physical.reserved2 = 0;
entry.destination.physical.phy_dest = 0; // 设置投递到BSP处理器
// ======== 初始化键盘控制器,写入配置值 =========
wait_ps2_keyboard_write();
io_out8(PORT_PS2_KEYBOARD_CONTROL, PS2_KEYBOARD_COMMAND_WRITE);
wait_ps2_keyboard_write();
io_out8(PORT_PS2_KEYBOARD_DATA, PS2_KEYBOARD_PARAM_INIT);
wait_ps2_keyboard_write();
// 执行一百万次nop等待键盘控制器把命令执行完毕
for (int i = 0; i < 1000; ++i)
for (int j = 0; j < 1000; ++j)
nop();
// 初始化键盘缓冲区的读写锁
spin_init(&ps2_kb_buf_rw_lock);
// 注册中断处理程序
irq_register(PS2_KEYBOARD_INTR_VECTOR, &entry, &ps2_keyboard_handler, (ul)&kb_buf, &ps2_keyboard_intr_controller, "ps/2 keyboard");
// 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。
io_in8(PORT_PS2_KEYBOARD_DATA);
// 将设备挂载到devfs
ps2_keyboard_register(&ps2_keyboard_fops);
kinfo("ps/2 keyboard registered.");
}
/**
* @brief 键盘驱动卸载函数
*
*/
void ps2_keyboard_exit()
{
irq_unregister(PS2_KEYBOARD_INTR_VECTOR);
kfifo_free_alloc(&kb_buf);
}