From 80edc58cf0f997ba4e9bbab2015a644d7cedaf91 Mon Sep 17 00:00:00 2001 From: longjin Date: Fri, 14 Oct 2022 18:01:26 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E5=B0=86idr=E4=B8=AD=EF=BC=8C=E5=85=B3?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E5=8A=A0=E8=87=AA=E6=97=8B=E9=94=81=E7=9A=84?= =?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=8C=E6=9B=BF=E6=8D=A2=E4=B8=BA=E4=B8=8D?= =?UTF-8?q?=E5=85=B3=E4=B8=AD=E6=96=AD=EF=BC=8C=E5=8A=A0=E8=87=AA=E6=97=8B?= =?UTF-8?q?=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/lib/idr.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/kernel/lib/idr.c b/kernel/lib/idr.c index b0a9539c..79a6adb4 100644 --- a/kernel/lib/idr.c +++ b/kernel/lib/idr.c @@ -32,15 +32,14 @@ void idr_init(struct idr *idp) */ static void __move_to_free_list(struct idr *idp, struct idr_layer *p) { - unsigned long flags; - spin_lock_irqsave(&idp->lock, flags); + spin_lock(&idp->lock); // 插入free_list p->ary[0] = idp->free_list; idp->free_list = p; ++(idp->id_free_cnt); - spin_unlock_irqrestore(&idp->lock, flags); + spin_unlock(&idp->lock); } /** @@ -60,8 +59,7 @@ static void *__get_from_free_list(struct idr *idp) } } - unsigned long flags; - spin_lock_irqsave(&idp->lock, flags); + spin_lock(&idp->lock); // free_list还有节点 struct idr_layer *item = idp->free_list; @@ -69,7 +67,7 @@ static void *__get_from_free_list(struct idr *idp) item->ary[0] = NULL; // 记得清空原来的数据 --(idp->id_free_cnt); - spin_unlock_irqrestore(&idp->lock, flags); + spin_unlock(&idp->lock); return item; } @@ -316,9 +314,8 @@ static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr // 特判根节点是否只剩0号儿子节点 (注意还要layer > 0) // (注意,有可能出现idp->top=NULL) // bitmap: 1000...000/00.....000 - while (idp->top != NULL && - ((idp->top->bitmap <= 1 && idp->top->layer > 0) || // 一条链的情况 - (idp->top->layer == 0 && idp->top->bitmap == 0))) // 最后一个点的情况 + while (idp->top != NULL && ((idp->top->bitmap <= 1 && idp->top->layer > 0) || // 一条链的情况 + (idp->top->layer == 0 && idp->top->bitmap == 0))) // 最后一个点的情况 { struct idr_layer *t = idp->top->layer ? idp->top->ary[0] : NULL; __idr_layer_free(idp->top); @@ -505,7 +502,8 @@ void *idr_find(struct idr *idp, int id) } /** - * @brief 返回id大于 start_id 的数据指针(即非空闲id对应的指针), 如果没有则返回NULL; 可以传入nextid指针,获取下一个id; 时间复杂度O(log_64(n)), 空间复杂度O(log_64(n)) 约为 6; + * @brief 返回id大于 start_id 的数据指针(即非空闲id对应的指针), 如果没有则返回NULL; 可以传入nextid指针,获取下一个id; + * 时间复杂度O(log_64(n)), 空间复杂度O(log_64(n)) 约为 6; * * @param idp * @param start_id @@ -699,8 +697,7 @@ int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask) if (idr_pre_get(&ida_p->idr, gfp_mask) != 0) return -ENOMEM; - unsigned long flags; - spin_lock_irqsave(&ida_p->idr.lock, flags); + spin_lock(&ida_p->idr.lock); if (NULL == ida_p->free_list) { @@ -708,13 +705,13 @@ int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask) bitmap = kzalloc(sizeof(struct ida_bitmap), gfp_mask); if (NULL == bitmap) { - spin_unlock_irqrestore(&ida_p->idr.lock, flags); + spin_unlock(&ida_p->idr.lock); return -ENOMEM; } ida_p->free_list = bitmap; } - spin_unlock_irqrestore(&ida_p->idr.lock, flags); + spin_unlock(&ida_p->idr.lock); return 0; } From 39f11c5b4b5f9249123d564e2347a6b7815b05cd Mon Sep 17 00:00:00 2001 From: login Date: Fri, 14 Oct 2022 18:45:10 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Eusb=20hid=20report?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * new: usb hid parser --- .vscode/settings.json | 3 +- kernel/common/compiler_attributes.h | 1 + kernel/common/hid.h | 97 ++ kernel/driver/Makefile | 2 +- kernel/driver/hid/Makefile | 19 + kernel/driver/hid/hidparse.c | 526 +++++++++ kernel/driver/hid/hidstrings.c | 1580 +++++++++++++++++++++++++++ kernel/driver/hid/internal.h | 37 + kernel/driver/hid/usbhid/Makefile | 15 + kernel/driver/usb/usb.h | 32 +- kernel/driver/usb/xhci/xhci.c | 357 ++++-- 11 files changed, 2567 insertions(+), 102 deletions(-) create mode 100644 kernel/common/hid.h create mode 100644 kernel/driver/hid/Makefile create mode 100644 kernel/driver/hid/hidparse.c create mode 100644 kernel/driver/hid/hidstrings.c create mode 100644 kernel/driver/hid/internal.h create mode 100644 kernel/driver/hid/usbhid/Makefile diff --git a/.vscode/settings.json b/.vscode/settings.json index c4e42aef..f840a4b2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -145,7 +145,8 @@ "kthread.h": "c", "lockref.h": "c", "compiler_attributes.h": "c", - "timer.h": "c" + "timer.h": "c", + "hid.h": "c" }, "C_Cpp.errorSquiggles": "Enabled", "esbonio.sphinx.confDir": "" diff --git a/kernel/common/compiler_attributes.h b/kernel/common/compiler_attributes.h index b77cae26..12278be6 100644 --- a/kernel/common/compiler_attributes.h +++ b/kernel/common/compiler_attributes.h @@ -1,4 +1,5 @@ #pragma once +#include // 当函数的返回值未被使用时,编译器抛出警告信息 #define __must_check __attribute__((__warn_unused_result__)) diff --git a/kernel/common/hid.h b/kernel/common/hid.h new file mode 100644 index 00000000..a215de3a --- /dev/null +++ b/kernel/common/hid.h @@ -0,0 +1,97 @@ +#pragma once +#include + +#define __HID_USAGE_TABLE_SIZE 64 // usage stack的大小 +#define HID_MAX_REPORT 300 // 最大允许的hid report数目(包括feature、input、output) +#define HID_MAX_PATH_SIZE 16 // maximum depth for path + +/** + * @brief 描述hid path中的一个节点 + * + */ +struct hid_node_t +{ + int u_page; + int usage; +}; + +/** + * @brief 描述一条hid path + * + */ +struct hid_path_t +{ + int size; // 路径中的节点数目 + struct hid_node_t node[HID_MAX_PATH_SIZE]; +}; + +/** + * @brief Describe a HID Data with its location in report + * + */ +struct hid_data_t +{ + int value; // hid对象的值 + struct hid_path_t path; // hid path + + int report_count; // count of reports for this usage type + int offset; // offset of data in report + int size; // size of data in bits + + uint8_t report_id; // report id(from incoming report) + uint8_t type; // 数据类型:FEATURE / INPUT / OUTPUT + uint8_t attribute; // report field attribute. (2 = (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)) + // (6 = (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)) + int8_t unit_exp; // unit exponent; + + uint32_t unit; // HID unit + + int logical_min; // Logical min + int logical_max; // Logical max + int phys_min; // Physical min + int phys_max; // Physical max +}; + +/** + * @brief hid解析器 + * + */ +struct hid_parser +{ + const uint8_t *report_desc; // 指向report descriptor的指针 + int report_desc_size; // report descriptor的大小(字节) + int pos; // report_desc中,当前正在处理的位置 + uint8_t item; // 暂存当前的item + uint32_t value; // 暂存当前的值 + + struct hid_data_t data; // 存储当前的环境 + + int offset_table[HID_MAX_REPORT][3]; // 存储 hid report的ID、type、offset + int report_count; // hid report的数量 + int count; // local items的计数 + + uint32_t u_page; + struct hid_node_t usage_table[__HID_USAGE_TABLE_SIZE]; // Usage stack + int usage_size; // usage的数量 + int usage_min; + int usage_max; + + int cnt_objects; // report descriptor中的对象数目 + int cnt_report // report desc中的report数目 +}; + + +struct hid_usage_types_string +{ + int value; + const char *string; +}; + +struct hid_usage_pages_string +{ + int value; + struct hid_usage_types_string * types; + const char * string; +}; + +int hid_parse_report(const void *report_data, const int len); diff --git a/kernel/driver/Makefile b/kernel/driver/Makefile index bbd51c12..3b84c7ef 100644 --- a/kernel/driver/Makefile +++ b/kernel/driver/Makefile @@ -1,7 +1,7 @@ CFLAGS += -I . -kernel_driver_subdirs:=video interrupt usb pci uart acpi disk keyboard mouse multiboot2 timers tty +kernel_driver_subdirs:=video interrupt usb pci uart acpi disk keyboard mouse multiboot2 timers tty hid ECHO: @echo "$@" diff --git a/kernel/driver/hid/Makefile b/kernel/driver/hid/Makefile new file mode 100644 index 00000000..63f6e33f --- /dev/null +++ b/kernel/driver/hid/Makefile @@ -0,0 +1,19 @@ + +CFLAGS += -I . + +kernel_driver_hid_subdirs:= usbhid + +kernel_driver_hid_objs:= $(shell find ./*.c) + +ECHO: + @echo "$@" + +$(kernel_driver_hid_subdirs): ECHO + $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" + +$(kernel_driver_hid_objs): ECHO + gcc $(CFLAGS) -c $@ -o $@.o + +all: $(kernel_driver_hid_objs) $(kernel_driver_hid_subdirs) + @echo $(kernel_driver_hid_objs) + diff --git a/kernel/driver/hid/hidparse.c b/kernel/driver/hid/hidparse.c new file mode 100644 index 00000000..c882f47a --- /dev/null +++ b/kernel/driver/hid/hidparse.c @@ -0,0 +1,526 @@ +#include "internal.h" +#include +#include +#include +#include +#include +#include + +/* + 参考文档:https://www.usb.org/document-library/device-class-definition-hid-111 + 本文件参考了FYSOS: https://github.com/fysnet/FYSOS.git + */ + +static bool HID_PARSE_OUTPUT = true; // 是否输出解析信息 +static char __tmp_usage_page_str[128] = {0}; + +static void hid_reset_parser(struct hid_parser *parser); + +static const char *hid_get_usage_page_str(const int u_page); +static const char *hid_get_usage_type_str(const int page, const int type); +static const char *hid_get_collection_str(const int value); +static int *__get_report_offset(struct hid_parser *parser, const uint8_t report_id, const uint8_t report_type); +static __always_inline const struct hid_usage_pages_string *hid_get_usage_page(const int u_page); + +static __always_inline const struct hid_usage_types_string *hid_get_usage_type( + const struct hid_usage_pages_string *upage, const int type); + +// hid item的低2位为size +#define HID_SIZE_MASK 0x3 +// 高6bit为item内容 +#define HID_ITEM_MASK 0xFC +#define HID_ITEM_UPAGE 0x04 // usage page +#define HID_ITEM_USAGE 0x08 // local item +#define HID_ITEM_LOG_MIN 0x14 +#define HID_ITEM_USAGE_MIN 0x18 // local item +#define HID_ITEM_LOG_MAX 0x24 +#define HID_ITEM_USAGE_MAX 0x28 // local item +#define HID_ITEM_PHY_MIN 0x34 +#define HID_ITEM_PHY_MAX 0x44 +#define HID_ITEM_UNIT_EXP 0x54 +#define HID_ITEM_UNIT 0x64 +#define HID_ITEM_REP_SIZE 0x74 +#define HID_ITEM_STRING 0x78 // local item? +#define HID_ITEM_REP_ID 0x84 +#define HID_ITEM_REP_COUNT 0x94 + +// 这部分请参考hid_1_11.pdf Section 6.2.2.4 + +#define HID_ITEM_COLLECTION 0xA0 +#define HID_ITEM_END_COLLECTION 0xC0 +#define HID_ITEM_FEATURE 0xB0 +#define HID_ITEM_INPUT 0x80 +#define HID_ITEM_OUTPUT 0x90 + +static char __spaces_buf[33]; +char *__spaces(uint8_t cnt) +{ + static char __space_overflow_str[] = "**"; + if (cnt > 32) + { + return &__space_overflow_str; + } + + memset(__spaces_buf, ' ', 32); + __spaces_buf[cnt] = '\0'; + return __spaces_buf; +} + +static __always_inline uint32_t __format_value(uint32_t value, uint8_t size) +{ + switch (size) + { + case 1: + value = (uint32_t)(uint8_t)value; + break; + case 2: + value = (uint32_t)(uint16_t)value; + break; + } + return value; +} + +/** + * @brief 重置parser + * + * @param parser 解析器 + * @return int 状态码 + */ +static void hid_reset_parser(struct hid_parser *parser) +{ + memset(parser, 0, sizeof(struct hid_parser)); + parser->data.report_id = 1; // we must give it a non-zero value or the parser doesn't work +} + +/** + * @brief 从usage_stack中弹出第一个元素 + * + * @param parser 解析器 + * @return __always_inline + */ +static __always_inline void __pop_usage_stack(struct hid_parser *parser) +{ + if (parser->usage_size > 0) + { + for (int js = 0; js < parser->usage_size - 1; ++js) + memmove(&parser->usage_table[js], &parser->usage_table[js + 1], sizeof(struct hid_node_t)); + + --parser->usage_size; + } +} + +/** + * @brief 解析hid report,并获取下一个数据到data字段中 + * + * @param parser 解析器 + * @param data 返回的数据 + * @return true 解析成功 + * @return false 解析失败 + */ +static bool hid_parse(struct hid_parser *parser, struct hid_data_t *data) +{ + bool found = false; + static uint8_t space_cnt = 0; + static bool did_collection = false; + static int item_size[4] = {0, 1, 2, 4}; + + // 循环解析 + while (!found && (parser->pos < parser->report_desc_size)) + { + // 当前parse过程还没有解析到report + if (parser->count == 0) + { + // 打印当前 report_data 的值 + if (HID_PARSE_OUTPUT) + printk("\n %02X ", parser->report_desc[parser->pos]); + // 获取到report size + parser->item = parser->report_desc[parser->pos++]; + parser->value = 0; + // 拷贝report的数据 + memcpy(&parser->value, &parser->report_desc[parser->pos], item_size[parser->item & HID_SIZE_MASK]); + + if (HID_PARSE_OUTPUT) + { + for (int i = 0; i < 4; ++i) + { + if (i < item_size[parser->item & HID_SIZE_MASK]) + printk("%02X ", parser->report_desc[parser->pos + i]); + else + printk(" "); + } + } + // 将指针指向下一个item + parser->pos += item_size[parser->item & HID_SIZE_MASK]; + } + + switch (parser->item & HID_ITEM_MASK) + { + case HID_ITEM_UPAGE: + // 拷贝upage + parser->u_page = (int)parser->value; + if (HID_PARSE_OUTPUT) + printk("%sUsage Page (%s)", __spaces(space_cnt), hid_get_usage_page_str(parser->u_page)); + // 拷贝到 usage table。由于这是一个USAGE entry,因此不增加usage_size(以便后面覆盖它) + parser->usage_table[parser->usage_size].u_page = parser->u_page; + parser->usage_table[parser->usage_size].usage = 0xff; + break; + case HID_ITEM_USAGE: + // 拷贝upage到usage table中 + if ((parser->item & HID_SIZE_MASK) > 2) // item大小为32字节 + parser->usage_table[parser->usage_size].u_page = (int)(parser->value >> 16); + else + parser->usage_table[parser->usage_size].u_page = parser->u_page; + + if (HID_PARSE_OUTPUT) + printk("%sUsage (%s)", __spaces(space_cnt), + hid_get_usage_type_str(parser->u_page, parser->value & 0xffff)); + ++parser->usage_size; + break; + case HID_ITEM_USAGE_MIN: + // todo: 设置usage min + if (HID_PARSE_OUTPUT) + printk("%sUsage min (%i=%s)", __spaces(space_cnt), parser->value, + hid_get_usage_type_str(parser->u_page, parser->value)); + break; + case HID_ITEM_USAGE_MAX: + // todo: 设置usage max + if (HID_PARSE_OUTPUT) + printk("%sUsage max (%i=%s)", __spaces(space_cnt), parser->value, + hid_get_usage_type_str(parser->u_page, parser->value)); + break; + case HID_ITEM_COLLECTION: + // 从usage table中取出第一个u_page和usage,并且将他们存储在parser->data.path + parser->data.path.node[parser->data.path.size].u_page = parser->usage_table[0].u_page; + parser->data.path.node[parser->data.path.size].usage = parser->usage_table[0].usage; + ++parser->data.path.size; + + // 由于上面取出了元素,因此将队列往前移动1个位置 + __pop_usage_stack(parser); + + // 获取index(如果有的话)??? + if (parser->value >= 0x80) + { + kdebug("parser->value > 0x80"); + parser->data.path.node[parser->data.path.size].u_page = 0xff; + parser->data.path.node[parser->data.path.size].usage = parser->value & 0x7f; + ++parser->data.path.size; + } + if (HID_PARSE_OUTPUT) + { + printk("%sCollection (%s)", __spaces(space_cnt), hid_get_collection_str(parser->value)); + space_cnt += 2; + } + break; + case HID_ITEM_END_COLLECTION: + --parser->data.path.size; // 为什么要--????? + // 删除多余的(未识别的)node + if (parser->data.path.node[parser->data.path.size].u_page == 0xff) + --parser->data.path.size; + if (HID_PARSE_OUTPUT) + { + if (space_cnt >= 2) + space_cnt -= 2; + printk("%sEnd Collection", __spaces(space_cnt)); + } + break; + case HID_ITEM_FEATURE: + case HID_ITEM_INPUT: + case HID_ITEM_OUTPUT: + // 找到了一个对象 + found = true; + + // 增加对象计数器 + ++parser->cnt_objects; + + // 更新local items的计数 + if (parser->count == 0) + parser->count = parser->report_count; + + // 从usage_table获取u_page和usage,将他们存储到parser.data.path + parser->data.path.node[parser->data.path.size].u_page = parser->usage_table[0].u_page; + parser->data.path.node[parser->data.path.size].usage = parser->usage_table[0].usage; + ++parser->data.path.size; + + // 从usage table中弹出刚刚那个node + __pop_usage_stack(parser); + + // 拷贝数据到data + parser->data.type = (uint8_t)(parser->item & HID_ITEM_MASK); + parser->data.attribute = (uint8_t)parser->value; + int *offset_ptr = + __get_report_offset(parser, parser->data.report_id, (uint8_t)(parser->item & HID_ITEM_MASK)); + + if (unlikely(offset_ptr == NULL)) + { + BUG_ON(1); + return false; + } + parser->data.offset = *offset_ptr; + + // 获取pData中的对象 + memcpy(data, &parser->data, sizeof(struct hid_data_t)); + + // 增加report offset + *offset_ptr = (*offset_ptr) + parser->data.size; + + // 从path中删除最后一个节点(刚刚弹出的这个节点) + --parser->data.path.size; + + // 减少local items计数 + if (parser->count > 0) + --parser->count; + + if (!did_collection) + { + if (HID_PARSE_OUTPUT) + { + if ((parser->item & HID_ITEM_MASK) == HID_ITEM_FEATURE) + printk("%sFeature ", __spaces(space_cnt)); + else if ((parser->item & HID_ITEM_MASK) == HID_ITEM_INPUT) + printk("%sInput ", __spaces(space_cnt)); + else if ((parser->item & HID_ITEM_MASK) == HID_ITEM_OUTPUT) + printk("%sOutut ", __spaces(space_cnt)); + + printk("(%s,%s,%s" /* ",%s,%s,%s,%s" */ ")", !(parser->value & (1 << 0)) ? "Data" : "Constant", + !(parser->value & (1 << 1)) ? "Array" : "Variable", + !(parser->value & (1 << 2)) ? "Absolute" : "Relative" /*, + !(parser->value & (1<<3)) ? "No Wrap" : "Wrap", + !(parser->value & (1<<4)) ? "Linear" : "Non Linear", + !(parser->value & (1<<5)) ? "Preferred State" : "No Preferred", + !(parser->value & (1<<6)) ? "No Null" : "Null State", + //!(parser->value & (1<<8)) ? "Bit Fueld" : "Buffered Bytes" + */ + ); + } + + did_collection = true; + } + break; + case HID_ITEM_REP_ID: // 当前item表示report id + parser->data.report_id = (uint8_t)parser->value; + if (HID_PARSE_OUTPUT) + printk("%sReport ID: %i", __spaces(space_cnt), parser->data.report_id); + break; + case HID_ITEM_REP_SIZE: // 当前item表示report size + parser->data.size = parser->value; + if (HID_PARSE_OUTPUT) + printk("%sReport size (%i)", __spaces(space_cnt), parser->data.size); + break; + case HID_ITEM_REP_COUNT: + parser->report_count = parser->value; + if (HID_PARSE_OUTPUT) + printk("%sReport count (%i)", __spaces(space_cnt), parser->report_count); + break; + case HID_ITEM_UNIT_EXP: + parser->data.unit_exp = (int8_t)parser->value; + if (parser->data.unit_exp > 7) + parser->data.unit_exp |= 0xf0; + if (HID_PARSE_OUTPUT) + printk("%sUnit Exp (%i)", __spaces(space_cnt), parser->data.unit_exp); + break; + case HID_ITEM_UNIT: + parser->data.unit = parser->value; + if (HID_PARSE_OUTPUT) + printk("%sUnit (%i)", __spaces(space_cnt), parser->data.unit); + break; + case HID_ITEM_LOG_MIN: // logical min + parser->data.logical_min = __format_value(parser->value, item_size[parser->item & HID_SIZE_MASK]); + if (HID_PARSE_OUTPUT) + printk("%sLogical Min (%i)", __spaces(space_cnt), parser->data.logical_min); + break; + case HID_ITEM_LOG_MAX: + parser->data.logical_max = __format_value(parser->value, item_size[parser->item & HID_SIZE_MASK]); + if (HID_PARSE_OUTPUT) + printk("%sLogical Max (%i)", __spaces(space_cnt), parser->data.logical_max); + break; + case HID_ITEM_PHY_MIN: + parser->data.phys_min = __format_value(parser->value, item_size[parser->item & HID_SIZE_MASK]); + if (HID_PARSE_OUTPUT) + printk("%Physical Min (%i)", __spaces(space_cnt), parser->data.phys_min); + break; + case HID_ITEM_PHY_MAX: + parser->data.phys_max = __format_value(parser->value, item_size[parser->item & HID_SIZE_MASK]); + if (HID_PARSE_OUTPUT) + printk("%Physical Max (%i)", __spaces(space_cnt), parser->data.phys_max); + break; + default: + printk("\n Found unknown item %#02X\n", parser->item & HID_ITEM_MASK); + return false; + } + } + return found; +} + +/** + * @brief 解析hid report的数据 + * + * @param report_data 从usb hid设备获取到hid report + * @param len report_data的大小(字节) + * @return int错误码 + */ +int hid_parse_report(const void *report_data, const int len) +{ + struct hid_parser parser = {0}; + struct hid_data_t data; + + hid_reset_parser(&parser); + parser.report_desc = (const uint8_t *)report_data; + parser.report_desc_size = len; + + while (hid_parse(&parser, &data)) + ; + return 0; +} + +/** + * @brief 根据usage page的id获取usage page string结构体.当u_page不属于任何已知的id时,返回NULL + * + * @param u_page usage page id + * @return const struct hid_usage_pages_string * usage page string结构体 + */ +static __always_inline const struct hid_usage_pages_string *hid_get_usage_page(const int u_page) +{ + int i = 0; + while ((hid_usage_page_strings[i].value < u_page) && (hid_usage_page_strings[i].value < 0xffff)) + ++i; + if ((hid_usage_page_strings[i].value != u_page) || (hid_usage_page_strings[i].value == 0xffff)) + return NULL; + else + return &hid_usage_page_strings[i]; +} + +/** + * @brief 从指定的upage获取指定类型的usage type结构体。当不存在时,返回NULL + * + * @param upage 指定的upage + * @param type usage的类型 + * @return const struct hid_usage_types_string * 目标usage type结构体。 + */ +static __always_inline const struct hid_usage_types_string *hid_get_usage_type( + const struct hid_usage_pages_string *upage, const int type) +{ + if (unlikely(upage == NULL || upage->types == NULL)) + { + BUG_ON(1); + return NULL; + } + struct hid_usage_types_string *types = upage->types; + int i = 0; + while ((types[i].value < type) && (types[i].value != 0xffff)) + ++i; + + if ((types[i].value != type) || (types[i].value == 0xffff)) + return NULL; + + return &types[i]; +} + +/** + * @brief 获取usage page的名称 + * + * @param u_page usage page的id + * @return const char* usage page的字符串 + */ +static const char *hid_get_usage_page_str(const int u_page) +{ + + const struct hid_usage_pages_string *upage = hid_get_usage_page(u_page); + if (unlikely(upage == NULL)) + { + sprintk(__tmp_usage_page_str, "Unknown Usage Page: %#04x", u_page); + return __tmp_usage_page_str; + } + return upage->string; +} + +/** + * @brief 打印usage page的指定类型的usage + * + * @param page usage page id + * @param type usage的类型 + * @return const char* + */ +static const char *hid_get_usage_type_str(const int page, const int type) +{ + const struct hid_usage_pages_string *upage = hid_get_usage_page(page); + if (unlikely(upage == NULL)) + { + sprintk(__tmp_usage_page_str, "Unknown Usage Page: %#04x", page); + return __tmp_usage_page_str; + } + + // button press, ordinal, or UTC + if (page == 0x0009) + { + sprintk(__tmp_usage_page_str, "Button number %i", type); + return __tmp_usage_page_str; + } + else if (page == 0x000a) + { + sprintk(__tmp_usage_page_str, "Ordinal %i", type); + return __tmp_usage_page_str; + } + else if (page == 0x0010) + { + sprintk(__tmp_usage_page_str, "UTC %#04X", type); + return __tmp_usage_page_str; + } + + const struct hid_usage_types_string *usage_type = hid_get_usage_type(upage, type); + if (unlikely(usage_type == NULL)) + { + sprintk(__tmp_usage_page_str, "Usage Page %s, with Unknown Type: %#04X", upage->string, type); + return __tmp_usage_page_str; + } + + return usage_type->string; +} + +/** + * @brief 输出colection字符串 + * + * @param value collection的值 + * @return const char* + */ +static const char *hid_get_collection_str(const int value) +{ + if (value <= 0x06) + return hid_collection_str[value]; + else if (value <= 0x7f) + return "Reserved"; + else if (value <= 0xff) + return "Vendor-defined"; + else + return "Error in get_collection_str(): value > 0xff"; +} + +/** + * @brief 从parser的offset table中,根据report_id和report_type,获取表中指向offset字段的指针 + * + * @param parser 解析器 + * @param report_id report_id + * @param report_type report类型 + * @return int* 指向offset字段的指针 + */ +static int *__get_report_offset(struct hid_parser *parser, const uint8_t report_id, const uint8_t report_type) +{ + int pos = 0; + // 尝试从已有的report中获取 + while ((pos < HID_MAX_REPORT) && (parser->offset_table[pos][0] != 0)) // 当offset的id不为0时 + { + if ((parser->offset_table[pos][0] == report_id) && (parser->offset_table[pos][1] == report_type)) + return &parser->offset_table[2]; + ++pos; + } + // 在offset table中占用一个新的表项来存储这个report的offset + if (pos < HID_MAX_REPORT) + { + ++parser->cnt_report; + parser->offset_table[pos][0] = report_id; + parser->offset_table[pos][1] = report_type; + parser->offset_table[pos][2] = 0; + return &parser->offset_table[pos][2]; + } + // 当offset table满了,且未找到结果的时候,返回NULL + return NULL; +} \ No newline at end of file diff --git a/kernel/driver/hid/hidstrings.c b/kernel/driver/hid/hidstrings.c new file mode 100644 index 00000000..eb938b8a --- /dev/null +++ b/kernel/driver/hid/hidstrings.c @@ -0,0 +1,1580 @@ +#include + +// Generic Desktop Devices +struct hid_usage_types_string hid_usage_type001[] = { + {0x0000, "Undefined"}, + {0x0001, "Pointer"}, + {0x0002, "Mouse"}, + {0x0003, "Reserved"}, + {0x0004, "Joystick"}, + {0x0005, "Game Pad"}, + {0x0006, "Keyboard"}, + {0x0007, "Keypad"}, + {0x0008, "Multi-axis Controller"}, + {0x0009, "Tablet PC System Controls"}, + {0x0030, "X"}, + {0x0031, "Y"}, + {0x0032, "Z"}, + {0x0033, "Rx"}, + {0x0034, "Ry"}, + {0x0035, "Rz"}, + {0x0036, "Slider"}, + {0x0037, "Dial"}, + {0x0038, "Wheel"}, + {0x0039, "Hat Switch"}, + {0x003A, "Counted Buffer"}, + {0x003B, "Byte Count"}, + {0x003C, "Motion Wake-up"}, + {0x003D, "Start"}, + {0x003E, "Select"}, + {0x003F, "Reserved"}, + {0x0040, "Vx"}, + {0x0041, "Vy"}, + {0x0042, "Vz"}, + {0x0043, "Vbrx"}, + {0x0044, "Vbry"}, + {0x0045, "Vbrz"}, + {0x0046, "Vno"}, + {0x0047, "Feature Notification"}, + {0x0048, "Resolution Mutliplier"}, + {0x0080, "System Control"}, + {0x0081, "System Power Down"}, + {0x0082, "System Sleep"}, + {0x0083, "System Wake-up"}, + {0x0084, "System Context Menu"}, + {0x0085, "System Main Menu"}, + {0x0086, "System App Menu"}, + {0x0087, "System Menu Help"}, + {0x0088, "System Menu Exit"}, + {0x0089, "System Menu Select"}, + {0x008A, "System Menu Right"}, + {0x008B, "System Menu Left"}, + {0x008C, "System Menu Up"}, + {0x008D, "System Menu Down"}, + {0x008E, "System Cold Restart "}, + {0x008F, "System Warm Restart"}, + {0x0090, "D-Pan Up"}, + {0x0091, "D-Pan Down"}, + {0x0092, "D-Pan Right"}, + {0x0093, "D-Pan Left"}, + {0x00A0, "System Dock"}, + {0x00A1, "System unDock"}, + {0x00A2, "System Setup"}, + {0x00A3, "System Break"}, + {0x00A4, "System Debugger Break"}, + {0x00A5, "Application Break"}, + {0x00A6, "Application Debugger Break"}, + {0x00A7, "System Speaker Mute"}, + {0x00A8, "System Hibernate"}, + {0x00B0, "System Display Invert"}, + {0x00B1, "System Display Internal"}, + {0x00B2, "System Display External"}, + {0x00B3, "System Display Both"}, + {0x00B4, "System Display Dual"}, + {0x00B5, "System Display Toggle Int/Ext"}, + {0x00B6, "System Display Swap Prim/Sec"}, + {0x00B7, "System Display Display Auto Scale"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type002[] = { + {0x0000, "Undefined"}, + {0x0001, "Flight Simulation Device"}, + {0x0002, "Automobile Simulation Device"}, + {0x0003, "Tank Simulation Device"}, + {0x0004, "Spaceship Simulation Device"}, + {0x0005, "Submarine Simulation Device"}, + {0x0006, "Sailing Simulation Device"}, + {0x0007, "Motorcycle Simulation Device"}, + {0x0008, "Sports Simulation Device"}, + {0x0009, "Airplane Simulation Device"}, + {0x000A, "Helicopter Simulation Device"}, + {0x000B, "Magic Carpet Simulation Device"}, + {0x000C, "Bicycle"}, + {0x0020, "Flight Control Stick"}, + {0x0021, "Flight Stick"}, + {0x0022, "Cyclic Control"}, + {0x0023, "Cyclic Trim"}, + {0x0024, "Flight Yoke"}, + {0x0025, "Track Control"}, + {0x0026, "Driving Control"}, + {0x00B0, "Aileron"}, + {0x00B1, "Aileron Trim"}, + {0x00B2, "Anti-Torque Control"}, + {0x00B3, "Auto-pilot Enable"}, + {0x00B4, "Chaff Release"}, + {0x00B5, "Collective Control"}, + {0x00B6, "Dive Brake"}, + {0x00B7, "Electronic Counter Measures"}, + {0x00B8, "Elevator"}, + {0x00B9, "Elevator Trim"}, + {0x00BA, "Rudder"}, + {0x00BB, "Throttle"}, + {0x00BC, "Flight Communication"}, + {0x00BD, "Flare Release"}, + {0x00BE, "Landing Gear"}, + {0x00BF, "Toe Brake"}, + {0x00C0, "Trigger"}, + {0x00C1, "Weapons Arm"}, + {0x00C2, "Weapons Select"}, + {0x00C3, "Wing Flaps"}, + {0x00C4, "Accelerator"}, + {0x00C5, "Brake"}, + {0x00C6, "Clutch"}, + {0x00C7, "Shifter"}, + {0x00C8, "Steering"}, + {0x00C9, "Turret Direction"}, + {0x00CA, "Barrel Elevation"}, + {0x00CB, "Dive Plane"}, + {0x00CC, "Ballast"}, + {0x00CD, "Bicycle Crank"}, + {0x00CE, "Handle Bars"}, + {0x00CF, "Front Brake"}, + {0x00D0, "Rear Brake"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type003[] = { + {0x0000, "Unidentified"}, + {0x0001, "Belt"}, + {0x0002, "Body Suit"}, + {0x0003, "Flexor"}, + {0x0004, "Glove"}, + {0x0005, "Head Tracker"}, + {0x0006, "Head Mounted Display"}, + {0x0007, "Hand Tracker"}, + {0x0008, "Oculometer"}, + {0x0009, "Vest"}, + {0x000A, "Animatronic Device"}, + {0x0020, "Stereo Enable"}, + {0x0021, "Display Enable"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type004[] = { + {0x0000, "Unidentified"}, + {0x0001, "Baseball Bat"}, + {0x0002, "Golf Club"}, + {0x0003, "Rowing Machine"}, + {0x0004, "Treadmill"}, + {0x0030, "Oar"}, + {0x0031, "Slope"}, + {0x0032, "Rate"}, + {0x0033, "Stick Speed"}, + {0x0034, "Stick Face Angle"}, + {0x0035, "Stick Heel/Toe"}, + {0x0036, "Stick Follow Through"}, + {0x0037, "Stick Tempo"}, + {0x0038, "Stick Type"}, + {0x0039, "Stick Height"}, + {0x0050, "Putter"}, + {0x0051, "1 Iron"}, + {0x0052, "2 Iron"}, + {0x0053, "3 Iron"}, + {0x0054, "4 Iron"}, + {0x0055, "5 Iron"}, + {0x0056, "6 Iron"}, + {0x0057, "7 Iron"}, + {0x0058, "8 Iron"}, + {0x0059, "9 Iron"}, + {0x005A, "10 Iron"}, + {0x005B, "11 Iron"}, + {0x005C, "Sand Wedge"}, + {0x005D, "Loft Wedge"}, + {0x005E, "Power Wedge"}, + {0x005F, "1 Wood"}, + {0x0060, "3 Wood"}, + {0x0061, "5 Wood"}, + {0x0062, "7 Wood"}, + {0x0063, "9 Wood"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type005[] = { + {0x0000, "Undefined"}, + {0x0001, "3D Game Controller"}, + {0x0002, "Pinball Device"}, + {0x0003, "Gun Device"}, + {0x0020, "Point of View"}, + {0x0021, "Turn Right/Left"}, + {0x0022, "Pitch Right/Left"}, + {0x0023, "Roll Forward/Backward"}, + {0x0024, "Move Right/Left"}, + {0x0025, "Move Forward/Backward"}, + {0x0026, "Move Up/Down"}, + {0x0027, "Lean Right/Left"}, + {0x0028, "Lean Forward/Backward"}, + {0x0029, "Height of POV"}, + {0x002A, "Flipper"}, + {0x002B, "Secondary Flipper"}, + {0x002C, "Bump"}, + {0x002D, "New Game"}, + {0x002E, "Shoot Ball"}, + {0x002F, "Player"}, + {0x0030, "Gun Bolt"}, + {0x0031, "Gun Clip"}, + {0x0032, "Gun Selector"}, + {0x0033, "Gun Single Shot"}, + {0x0034, "Gun Burst"}, + {0x0035, "Gun Automatic"}, + {0x0036, "Gun Safety"}, + {0x0037, "Gamepad Fire/Jump"}, + {0x0039, "Gamepad Trigger"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type006[] = { + {0x0000, "Unidentified"}, + {0x0020, " Battery Strength"}, + {0x0021, " Wireless Channel"}, + {0x0022, " Wireless ID"}, + {0x0023, " Discover Wireless Control"}, + {0x0024, " Security Code Character Entered"}, + {0x0025, " Security Code Character Erased"}, + {0x0026, " Security Code Cleared"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type007[] = { + {0x0000, "Reserved (no event indicated)"}, + {0x0001, "Keyboard ErrorRollOver"}, + {0x0002, "Keyboard POSTFail"}, + {0x0003, "Keyboard ErrorUndefined"}, + {0x0004, "Keyboard a and A"}, + {0x0005, "Keyboard b and B"}, + {0x0006, "Keyboard c and C"}, + {0x0007, "Keyboard d and D"}, + {0x0008, "Keyboard e and E"}, + {0x0009, "Keyboard f and F"}, + {0x000A, "Keyboard g and G"}, + {0x000B, "Keyboard h and H"}, + {0x000C, "Keyboard i and I"}, + {0x000D, "Keyboard j and J"}, + {0x000E, "Keyboard k and K"}, + {0x000F, "Keyboard l and L"}, + {0x0010, "Keyboard m and M"}, + {0x0011, "Keyboard n and N"}, + {0x0012, "Keyboard o and O"}, + {0x0013, "Keyboard p and P"}, + {0x0014, "Keyboard q and Q"}, + {0x0015, "Keyboard r and R"}, + {0x0016, "Keyboard s and S"}, + {0x0017, "Keyboard t and T"}, + {0x0018, "Keyboard u and U"}, + {0x0019, "Keyboard v and V"}, + {0x001A, "Keyboard w and W"}, + {0x001B, "Keyboard x and X"}, + {0x001C, "Keyboard y and Y"}, + {0x001D, "Keyboard z and Z"}, + {0x001E, "Keyboard 1 and !"}, + {0x001F, "Keyboard 2 and @"}, + {0x0020, "Keyboard 3 and #"}, + {0x0021, "Keyboard 4 and $"}, + {0x0022, "Keyboard 5 and %"}, + {0x0023, "Keyboard 6 and ^"}, + {0x0024, "Keyboard 7 and &"}, + {0x0025, "Keyboard 8 and *"}, + {0x0026, "Keyboard 9 and ("}, + {0x0027, "Keyboard 0 and )"}, + {0x0028, "Keyboard Return (ENTER)"}, + {0x0029, "Keyboard ESCAPE"}, + {0x002A, "Keyboard DELETE (Backspace)"}, + {0x002B, "Keyboard Tab"}, + {0x002C, "Keyboard Spacebar"}, + {0x002D, "Keyboard - and (underscore)"}, + {0x002E, "Keyboard = and +"}, + {0x002F, "Keyboard [ and {"}, + {0x0030, "Keyboard ] and }"}, + {0x0031, "Keyboard \\ and |"}, + {0x0032, "Keyboard Non-US # and ~"}, + {0x0033, "Keyboard ; and :"}, + {0x0034, "Keyboard ' and \""}, + {0x0035, "Keyboard Grave Accent and Tilde"}, + {0x0036, "Keyboard, and <"}, + {0x0037, "Keyboard . and >"}, + {0x0038, "Keyboard / and ?"}, + {0x0039, "Keyboard Caps Lock"}, + {0x003A, "Keyboard F1"}, + {0x003B, "Keyboard F2"}, + {0x003C, "Keyboard F3"}, + {0x003D, "Keyboard F4"}, + {0x003E, "Keyboard F5"}, + {0x003F, "Keyboard F6"}, + {0x0040, "Keyboard F7"}, + {0x0041, "Keyboard F8"}, + {0x0042, "Keyboard F9"}, + {0x0043, "Keyboard F10"}, + {0x0044, "Keyboard F11"}, + {0x0045, "Keyboard F12"}, + {0x0046, "Keyboard PrintScreen"}, + {0x0047, "Keyboard Scroll Lock"}, + {0x0048, "Keyboard Pause"}, + {0x0049, "Keyboard Insert"}, + {0x004A, "Keyboard Home"}, + {0x004B, "Keyboard PageUp"}, + {0x004C, "Keyboard Delete Forward"}, + {0x004D, "Keyboard End"}, + {0x004E, "Keyboard PageDown"}, + {0x004F, "Keyboard RightArrow"}, + {0x0050, "Keyboard LeftArrow"}, + {0x0051, "Keyboard DownArrow"}, + {0x0052, "Keyboard UpArrow"}, + {0x0053, "Keypad Num Lock and Clear"}, + {0x0054, "Keypad /"}, + {0x0055, "Keypad *"}, + {0x0056, "Keypad -"}, + {0x0057, "Keypad +"}, + {0x0058, "Keypad ENTER"}, + {0x0059, "Keypad 1 and End"}, + {0x005A, "Keypad 2 and Down Arrow"}, + {0x005B, "Keypad 3 and PageDn"}, + {0x005C, "Keypad 4 and Left Arrow"}, + {0x005D, "Keypad 5"}, + {0x005E, "Keypad 6 and Right Arrow"}, + {0x005F, "Keypad 7 and Home"}, + {0x0060, "Keypad 8 and Up Arrow"}, + {0x0061, "Keypad 9 and PageUp"}, + {0x0062, "Keypad 0 and Insert"}, + {0x0063, "Keypad . and Delete"}, + {0x0064, "Keyboard Non-US \\ and |"}, + {0x0065, "Keyboard Application"}, + {0x0066, "Keyboard Power"}, + {0x0067, "Keypad ="}, + {0x0068, "Keyboard F13"}, + {0x0069, "Keyboard F14"}, + {0x006A, "Keyboard F15"}, + {0x006B, "Keyboard F16"}, + {0x006C, "Keyboard F17"}, + {0x006D, "Keyboard F18"}, + {0x006E, "Keyboard F19"}, + {0x006F, "Keyboard F20"}, + {0x0070, "Keyboard F21"}, + {0x0071, "Keyboard F22"}, + {0x0072, "Keyboard F23"}, + {0x0073, "Keyboard F24"}, + {0x0074, "Keyboard Execute"}, + {0x0075, "Keyboard Help"}, + {0x0076, "Keyboard Menu"}, + {0x0077, "Keyboard Select"}, + {0x0078, "Keyboard Stop"}, + {0x0079, "Keyboard Again"}, + {0x007A, "Keyboard Undo"}, + {0x007B, "Keyboard Cut"}, + {0x007C, "Keyboard Copy"}, + {0x007D, "Keyboard Paste"}, + {0x007E, "Keyboard Find"}, + {0x007F, "Keyboard Mute"}, + {0x0080, "Keyboard Volume Up"}, + {0x0081, "Keyboard Volume Down"}, + {0x0082, "Keyboard Locking Caps Lock"}, + {0x0083, "Keyboard Locking Num Lock"}, + {0x0084, "Keyboard Locking Scroll Lock"}, + {0x0085, "Keypad Comma"}, + {0x0086, "Keypad Equal Sign"}, + {0x0087, "Keyboard International1"}, + {0x0088, "Keyboard International2"}, + {0x0089, "Keyboard International3"}, + {0x008A, "Keyboard International4"}, + {0x008B, "Keyboard International5"}, + {0x008C, "Keyboard International6"}, + {0x008D, "Keyboard International7"}, + {0x008E, "Keyboard International8"}, + {0x008F, "Keyboard International9"}, + {0x0090, "Keyboard LANG1"}, + {0x0091, "Keyboard LANG2"}, + {0x0092, "Keyboard LANG3"}, + {0x0093, "Keyboard LANG4"}, + {0x0094, "Keyboard LANG5"}, + {0x0095, "Keyboard LANG6"}, + {0x0096, "Keyboard LANG7"}, + {0x0097, "Keyboard LANG8"}, + {0x0098, "Keyboard LANG9"}, + {0x0099, "Keyboard Alternate Erase"}, + {0x009A, "Keyboard SysReq/Attention"}, + {0x009B, "Keyboard Cancel"}, + {0x009C, "Keyboard Clear"}, + {0x009D, "Keyboard Prior"}, + {0x009E, "Keyboard Return"}, + {0x009F, "Keyboard Separator"}, + {0x00A0, "Keyboard Out"}, + {0x00A1, "Keyboard Oper"}, + {0x00A2, "Keyboard Clear/Again"}, + {0x00A3, "Keyboard CrSel/Props"}, + {0x00A4, "Keyboard ExSel"}, + {0x00E0, "Keyboard LeftControl"}, + {0x00E1, "Keyboard LeftShift"}, + {0x00E2, "Keyboard LeftAlt"}, + {0x00E3, "Keyboard Left GUI"}, + {0x00E4, "Keyboard RightControl"}, + {0x00E5, "Keyboard RightShift"}, + {0x00E6, "Keyboard RightAlt"}, + {0x00E7, "Keyboard Right GUI"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type008[] = { + {0x0000, "Undefined"}, + {0x0001, "Num Lock"}, + {0x0002, "Caps Lock"}, + {0x0003, "Scroll Lock"}, + {0x0004, "Compose"}, + {0x0005, "Kana"}, + {0x0006, "Power"}, + {0x0007, "Shift"}, + {0x0008, "Do Not Disturb"}, + {0x0009, "Mute"}, + {0x000A, "Tone Enable"}, + {0x000B, "High Cut Filter"}, + {0x000C, "Low Cut Filter"}, + {0x000D, "Equalizer Enable"}, + {0x000E, "Sound Field On"}, + {0x000F, "Surround Field On"}, + {0x0010, "Repeat"}, + {0x0011, "Stereo"}, + {0x0012, "Sampling Rate Detect"}, + {0x0013, "Spinning"}, + {0x0014, "CAV"}, + {0x0015, "CLV"}, + {0x0016, "Recording Format Detect"}, + {0x0017, "Off-Hook"}, + {0x0018, "Ring"}, + {0x0019, "Message Waiting"}, + {0x001A, "Data Mode"}, + {0x001B, "Battery Operation"}, + {0x001C, "Battery OK"}, + {0x001D, "Battery Low"}, + {0x001E, "Speaker"}, + {0x001F, "Head Set"}, + {0x0020, "Hold"}, + {0x0021, "Microphone"}, + {0x0022, "Coverage"}, + {0x0023, "Night Mode"}, + {0x0024, "Send Calls"}, + {0x0025, "Call Pickup"}, + {0x0026, "Conference"}, + {0x0027, "Stand-by"}, + {0x0028, "Camera On"}, + {0x0029, "Camera Off"}, + {0x002A, "On-Line"}, + {0x002B, "Off-Line"}, + {0x002C, "Busy"}, + {0x002D, "Ready"}, + {0x002E, "Paper-Out"}, + {0x002F, "Paper-Jam"}, + {0x0030, "Remote"}, + {0x0031, "Forward"}, + {0x0032, "Reverse"}, + {0x0033, "Stop"}, + {0x0034, "Rewind"}, + {0x0035, "Fast Forward"}, + {0x0036, "Play"}, + {0x0037, "Pause"}, + {0x0038, "Record"}, + {0x0039, "Error"}, + {0x003A, "Usage Selected Indicator"}, + {0x003B, "Usage In Use Indicator"}, + {0x003C, "Usage Multi Mode Indicator"}, + {0x003D, "Indicator On"}, + {0x003E, "Indicator Flash"}, + {0x003F, "Indicator Slow Blink"}, + {0x0040, "Indicator Fast Blink"}, + {0x0041, "Indicator Off"}, + {0x0042, "Flash On Time"}, + {0x0043, "Slow Blink On Time"}, + {0x0044, "Slow Blink Off Time"}, + {0x0045, "Fast Blink On Time"}, + {0x0046, "Fast Blink Off Time"}, + {0x0047, "Usage Indicator Color"}, + {0x0048, "Red"}, + {0x0049, "Green"}, + {0x004A, "Amber"}, + {0x004B, "Generic Indicator"}, + {0x004C, "System Suspend"}, + {0x004D, "External Power Connected"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type00B[] = { + {0x0000, "Unassigned"}, + {0x0001, "Phone"}, + {0x0002, "Answering Machine"}, + {0x0003, "Message Controls"}, + {0x0004, "Handset"}, + {0x0005, "Headset"}, + {0x0006, "Telephony Key Pad"}, + {0x0007, "Programmable Button"}, + {0x0020, "Hook Switch"}, + {0x0021, "Flash"}, + {0x0022, "Feature"}, + {0x0023, "Hold"}, + {0x0024, "Redial"}, + {0x0025, "Transfer"}, + {0x0026, "Drop"}, + {0x0027, "Park"}, + {0x0028, "Forward Calls"}, + {0x0029, "Alternate Function"}, + {0x002A, "Line"}, + {0x002B, "Speaker Phone"}, + {0x002C, "Conference"}, + {0x002D, "Ring Enable"}, + {0x002E, "Ring Select"}, + {0x002F, "Phone Mute"}, + {0x0030, "Caller ID"}, + {0x0050, "Speed Dial"}, + {0x0051, "Store Number"}, + {0x0052, "Recall Number"}, + {0x0053, "Phone Directory"}, + {0x0070, "Voice Mail"}, + {0x0071, "Screen Calls"}, + {0x0072, "Do Not Disturb"}, + {0x0073, "Message"}, + {0x0074, "Answer On/Off"}, + {0x0090, "Inside Dial Tone"}, + {0x0091, "Outside Dial Tone"}, + {0x0092, "Inside Ring Tone"}, + {0x0093, "Outside Ring Tone"}, + {0x0094, "Priority Ring Tone"}, + {0x0095, "Inside Ringback"}, + {0x0096, "Priority Ringback"}, + {0x0097, "Line Busy Tone"}, + {0x0098, "Reorder Tone"}, + {0x0099, "Call Waiting Tone"}, + {0x009A, "Confirmation Tone 1"}, + {0x009B, "Confirmation Tone 2"}, + {0x009C, "Tones Off"}, + {0x00B0, "Phone Key 0"}, + {0x00B1, "Phone Key 1"}, + {0x00B2, "Phone Key 2"}, + {0x00B3, "Phone Key 3"}, + {0x00B4, "Phone Key 4"}, + {0x00B5, "Phone Key 5"}, + {0x00B6, "Phone Key 6"}, + {0x00B7, "Phone Key 7"}, + {0x00B8, "Phone Key 8"}, + {0x00B9, "Phone Key 9"}, + {0x00BA, "Phone Key Star"}, + {0x00BB, "Phone Key Pound"}, + {0x00BC, "Phone Key A"}, + {0x00BD, "Phone Key B"}, + {0x00BE, "Phone Key C"}, + {0x00BF, "Phone Key D"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type00C[] = { + {0x0000, "Undefined"}, + {0x0001, "Consumer Control"}, + {0x0002, "Numeric Key Pad"}, + {0x0003, "Programmable Buttons"}, + {0x0004, "Microphone"}, + {0x0005, "Headphone"}, + {0x0006, "Graphic Equalizer"}, + {0x0020, "+10"}, + {0x0021, "+100"}, + {0x0022, "AM/PM"}, + {0x0030, "Power"}, + {0x0031, "Reset"}, + {0x0032, "Sleep"}, + {0x0033, "Sleep After"}, + {0x0034, "Sleep Mode"}, + {0x0035, "Illumination"}, + {0x0036, "Function Buttons"}, + {0x0040, "Menu"}, + {0x0041, "Menu Pick"}, + {0x0042, "Menu Up"}, + {0x0043, "Menu Down"}, + {0x0044, "Menu Left"}, + {0x0045, "Menu Right"}, + {0x0046, "Menu Esc"}, + {0x0047, "Menu Value Increase"}, + {0x0048, "Menu Value Decrease"}, + {0x0060, "Data On Screen"}, + {0x0061, "Closed Caption"}, + {0x0062, "Closed Caption Select"}, + {0x0063, "VCR/TV"}, + {0x0064, "Broadcast Mode"}, + {0x0065, "Snap shot"}, + {0x0066, "Still"}, + {0x0080, "Selection"}, + {0x0081, "Assign Selection"}, + {0x0082, "Mode Setup"}, + {0x0083, "Recal Last"}, + {0x0084, "Enter Channel"}, + {0x0085, "Order Movie"}, + {0x0086, "Channel"}, + {0x0087, "Media Selection"}, + {0x0088, "Media Select Computer"}, + {0x0089, "Media Select TV"}, + {0x008A, "Media Select WWW"}, + {0x008B, "Media Select DVD"}, + {0x008C, "Media Select Telephone"}, + {0x008D, "Media Select Program Guide"}, + {0x008E, "Media Select Video Phone"}, + {0x008F, "Media Select Games"}, + {0x0090, "Media Select Messages"}, + {0x0091, "Media Select CD"}, + {0x0092, "Media Select VCR"}, + {0x0093, "Media Select Tuner"}, + {0x0094, "Quit"}, + {0x0095, "Help"}, + {0x0096, "Media Select Tape"}, + {0x0097, "Media Select Cable"}, + {0x0098, "Media Select Satelite"}, + {0x0099, "Media Select Security"}, + {0x009A, "Media Select Home"}, + {0x009B, "Media Select Call"}, + {0x009C, "Channel Increment"}, + {0x009E, "Channel Decrement"}, + {0x009D, "Media Select SAP"}, + {0x009F, "Reserved"}, + {0x00A0, "VCR Plus"}, + {0x00A1, "Once"}, + {0x00A2, "Daily"}, + {0x00A3, "Weekly"}, + {0x00A4, "Monthly"}, + {0x00B0, "Play"}, + {0x00B1, "Pause"}, + {0x00B2, "Record"}, + {0x00B3, "Fast Foward"}, + {0x00B4, "Rewind"}, + {0x00B5, "Scan Next Track"}, + {0x00B6, "Scan Previous Track"}, + {0x00B7, "Stop"}, + {0x00B8, "Eject"}, + {0x00B9, "Random Play"}, + {0x00BA, "Select Disc"}, + {0x00BB, "Enter Disk"}, + {0x00BC, "Repeat"}, + {0x00BD, "Tracking"}, + {0x00BE, "Track Normal"}, + {0x00BF, "Slow Tracking"}, + {0x00C0, "Frame Forward"}, + {0x00C1, "Frame Back"}, + {0x00C2, "Mark"}, + {0x00C3, "Clear Mark"}, + {0x00C4, "Repeat from Mark"}, + {0x00C5, "Return to Mark"}, + {0x00C6, "Search Mark Forward"}, + {0x00C7, "Search Mark Backwards"}, + {0x00C8, "Counter Reset"}, + {0x00C9, "Show Counter"}, + {0x00CA, "Tracking Increment"}, + {0x00CB, "Tracking Decrement"}, + {0x00CC, "Stop/Eject"}, + {0x00CD, "Play/Pause"}, + {0x00CE, "Play/Skip"}, + {0x00E0, "Volume"}, + {0x00E1, "Balance"}, + {0x00E2, "Mute"}, + {0x00E3, "Bass"}, + {0x00E4, "Treble"}, + {0x00E5, "Bass Boost"}, + {0x00E6, "Surround Mode"}, + {0x00E7, "Loudness"}, + {0x00E8, "MPX"}, + {0x00E9, "Volume Increment"}, + {0x00EA, "Volume Decrement"}, + {0x00F0, "Speed Select"}, + {0x00F1, "Playback Speed"}, + {0x00F2, "Standard Play"}, + {0x00F3, "Long Play"}, + {0x00F4, "Extended Play"}, + {0x00F5, "Slow"}, + {0x0100, "Fan Enable"}, + {0x0101, "Fan Speed"}, + {0x0102, "Light Enable"}, + {0x0103, "Light Illumination Level"}, + {0x0104, "Climate Control Enable"}, + {0x0105, "Room Temperature"}, + {0x0106, "Security Enable"}, + {0x0107, "Fire Alarm"}, + {0x0108, "Police Alarm"}, + {0x0109, "Proximity"}, + {0x010A, "Motion"}, + {0x010B, "Duress Alarm"}, + {0x010C, "Holdup Alarm"}, + {0x010D, "Medical Alarm"}, + {0x0150, "Balance Right"}, + {0x0151, "Balance Left"}, + {0x0152, "Bass Increment"}, + {0x0153, "Bass Decrement"}, + {0x0154, "Treble Increment"}, + {0x0155, "Trebel Decrement"}, + {0x0160, "Speaker System"}, + {0x0161, "Channel Left"}, + {0x0162, "Channel Right"}, + {0x0163, "Channel Center"}, + {0x0164, "Channel Front"}, + {0x0165, "Channel Center Front"}, + {0x0166, "Channel Side"}, + {0x0167, "Channel Surround"}, + {0x0168, "Channel Low Freq Enhancement"}, + {0x0169, "Channel Top"}, + {0x016A, "Channel Unknown"}, + {0x0170, "Sub-channel"}, + {0x0171, "Sub-channel Increment"}, + {0x0172, "Sub-channel Decrement"}, + {0x0173, "Alternate Audio Increment"}, + {0x0174, "Alternate Audio Decrement"}, + {0x0180, "Application Launch"}, + {0x0180, "App Launch: Config Tool"}, + {0x0181, "App Launch: Launch Button Config"}, + {0x0182, "App Launch: Programmable Button"}, + {0x0183, "App Launch: Consumer Control"}, + {0x0184, "App Launch: Word Processor"}, + {0x0185, "App Launch: Text Editor"}, + {0x0186, "App Launch: Spread Sheet"}, + {0x0187, "App Launch: Graphics Editor"}, + {0x0188, "App Launch: Presentation App"}, + {0x0189, "App Launch: Database App"}, + {0x018A, "App Launch: Email Reader"}, + {0x018B, "App Launch: News Reader"}, + {0x018C, "App Launch: Voice Mail"}, + {0x018D, "App Launch: Contacts/Address Book"}, + {0x018E, "App Launch: Calendar/Schedule Book"}, + {0x018F, "App Launch: Task/Project Manager"}, + {0x0190, "App Launch: Log/Journal/Time card"}, + {0x0191, "App Launch: Checkbook/Finance"}, + {0x0192, "App Launch: Calculator"}, + {0x0193, "App Launch: A/V Capture/Playback"}, + {0x0194, "App Launch: Local Machine Browser"}, + {0x0195, "App Launch: LAN/WAN Browser"}, + {0x0196, "App Launch: Internet Browser"}, + {0x0197, "App Launch: Remote Networking"}, + {0x0198, "App Launch: Network Conference"}, + {0x0199, "App Launch: Network Chat"}, + {0x019A, "App Launch: Telephone Dialer"}, + {0x019B, "App Launch: Logon"}, + {0x019C, "App Launch: Logoff"}, + {0x019D, "App Launch: Logon/Logoff"}, + {0x019E, "App Launch: Term Lock/Screensaver"}, + {0x019F, "App Launch: Control Panel"}, + {0x01A0, "App Launch: Command Line"}, + {0x01A1, "App Launch: Process Task Manager"}, + {0x01A2, "App Launch: Select Task/App"}, + {0x01A3, "App Launch: Next Task/App"}, + {0x01A4, "App Launch: Prev Task/App"}, + {0x01A5, "App Launch: Premptive Halt"}, + {0x01A6, "App Launch: Integrated Help Center"}, + {0x01A7, "App Launch: Documents"}, + {0x01A8, "App Launch: Thesarus"}, + {0x01A9, "App Launch: Dictionary"}, + {0x01AA, "App Launch: Desktop"}, + {0x01AB, "App Launch: Spell Check"}, + {0x01AC, "App Launch: Grammer Check"}, + {0x01AD, "App Launch: Wireless Status"}, + {0x01AE, "App Launch: Keyboard Layout"}, + {0x01AF, "App Launch: Virus Protect"}, + {0x01B0, "App Launch: Encryption"}, + {0x01B1, "App Launch: Screen Saver"}, + {0x01B2, "App Launch: Alarms"}, + {0x01B3, "App Launch: Clock"}, + {0x01B4, "App Launch: File Browser"}, + {0x01B5, "App Launch: Power Status"}, + {0x01B6, "App Launch: Image Browser"}, + {0x01B7, "App Launch: Audio Browser"}, + {0x01B8, "App Launch: Movie Browser"}, + {0x01B9, "App Launch: Digital Rights Manager"}, + {0x01BA, "App Launch: Digital Wallet"}, + {0x01BB, "App Launch: Reserved"}, + {0x01BC, "App Launch: Instant Messaging"}, + {0x01BD, "App Launch: OEM Tools"}, + {0x01BE, "App Launch: OEM Help"}, + {0x01BF, "App Launch: Online Community"}, + {0x01C0, "App Launch: Entertainment Content Browser"}, + {0x01C1, "App Launch: Online Shopping Browser"}, + {0x01C2, "App Launch: SmartCard Info"}, + {0x01C3, "App Launch: Market Monitor"}, + {0x01C4, "App Launch: Customized News"}, + {0x01C5, "App Launch: Online Activity Browser"}, + {0x01C6, "App Launch: Research/Search Browser"}, + {0x01C7, "App Launch: Audio Player"}, + {0x0200, "GUI Controls"}, + {0x0201, "GUI: New"}, + {0x0202, "GUI: Open"}, + {0x0203, "GUI: Close"}, + {0x0204, "GUI: Exit"}, + {0x0205, "GUI: Maximize"}, + {0x0206, "GUI: Minimize"}, + {0x0207, "GUI: Save"}, + {0x0208, "GUI: Print"}, + {0x0209, "GUI: Properties"}, + {0x021A, "GUI: Undo"}, + {0x021B, "GUI: Copy"}, + {0x021C, "GUI: Cut"}, + {0x021D, "GUI: Paste"}, + {0x021E, "GUI: Select All"}, + {0x021F, "GUI: Find"}, + {0x0220, "GUI: Find/Replace"}, + {0x0221, "GUI: Search"}, + {0x0222, "GUI: Goto"}, + {0x0223, "GUI: Home"}, + {0x0224, "GUI: Back"}, + {0x0225, "GUI: Foward"}, + {0x0226, "GUI: Stop"}, + {0x0227, "GUI: Refresh"}, + {0x0228, "GUI: Prev Link"}, + {0x0229, "GUI: Next Link"}, + {0x022A, "GUI: Bookmarks"}, + {0x022B, "GUI: History"}, + {0x022C, "GUI: Subscriptions"}, + {0x022D, "GUI: Zoom In"}, + {0x022E, "GUI: Zoom Out"}, + {0x022F, "GUI: Zoom"}, + {0x0230, "GUI: Full Screen"}, + {0x0231, "GUI: Normal View"}, + {0x0232, "GUI: View Toggle"}, + {0x0233, "GUI: Scroll Up"}, + {0x0234, "GUI: Scroll Down"}, + {0x0235, "GUI: Scroll"}, + {0x0236, "GUI: Pan Left"}, + {0x0237, "GUI: Pan Right"}, + {0x0238, "GUI: Pan"}, + {0x0239, "GUI: New Window"}, + {0x023A, "GUI: Tile Horz"}, + {0x023B, "GUI: Tile Vert"}, + {0x023C, "GUI: Format"}, + {0x023D, "GUI: Edit"}, + {0x023E, "GUI: Bold"}, + {0x023F, "GUI: Italics"}, + {0x0240, "GUI: Underline"}, + {0x0241, "GUI: StrikeThrough"}, + {0x0242, "GUI: SubScript"}, + {0x0243, "GUI: SuperScript"}, + {0x0244, "GUI: All Caps"}, + {0x0245, "GUI: Rotate"}, + {0x0246, "GUI: Resize"}, + {0x0247, "GUI: Flip Horz"}, + {0x0248, "GUI: Flip Vert"}, + {0x0249, "GUI: Mirror Horz"}, + {0x024A, "GUI: Mirror Vert"}, + {0x024B, "GUI: Font Select"}, + {0x024C, "GUI: Font Color"}, + {0x024D, "GUI: Font Size"}, + {0x024E, "GUI: Justify Left"}, + {0x024F, "GUI: Justify Center H"}, + {0x0250, "GUI: Justify Right"}, + {0x0251, "GUI: Justify Block H"}, + {0x0252, "GUI: Justify Top"}, + {0x0253, "GUI: Justify Center V"}, + {0x0254, "GUI: Justify Bottom"}, + {0x0255, "GUI: Justify Block V"}, + {0x0256, "GUI: Indent Decrease"}, + {0x0257, "GUI: Indent Increase"}, + {0x0258, "GUI: Numbered List"}, + {0x0259, "GUI: Restart Numbering"}, + {0x025A, "GUI: Bulleted List"}, + {0x025B, "GUI: Promote"}, + {0x025C, "GUI: Demote"}, + {0x025D, "GUI: Yes"}, + {0x025E, "GUI: No"}, + {0x025F, "GUI: Cancel"}, + {0x0260, "GUI: Catalog"}, + {0x0261, "GUI: Buy/Checkout"}, + {0x0262, "GUI: Add to Cart"}, + {0x0263, "GUI: Expand"}, + {0x0264, "GUI: Expand All"}, + {0x0265, "GUI: Collapse"}, + {0x0266, "GUI: Collapse All"}, + {0x0267, "GUI: Print Preview"}, + {0x0268, "GUI: Paste Special"}, + {0x0269, "GUI: Insert Mode"}, + {0x026A, "GUI: Delete"}, + {0x026B, "GUI: Lock"}, + {0x026C, "GUI: Unlock"}, + {0x026D, "GUI: Protect"}, + {0x026E, "GUI: Unprotect"}, + {0x026F, "GUI: Attache Comment"}, + {0x0270, "GUI: Delete Comment"}, + {0x0271, "GUI: View Comment"}, + {0x0272, "GUI: Select Word"}, + {0x0273, "GUI: Select Sentence"}, + {0x0274, "GUI: Select Paragraph"}, + {0x0275, "GUI: Select Column"}, + {0x0276, "GUI: Select Row"}, + {0x0277, "GUI: Select Table"}, + {0x0278, "GUI: Select Object"}, + {0x0279, "GUI: Redo/Repeat"}, + {0x027A, "GUI: Sort"}, + {0x027B, "GUI: Sort Ascending"}, + {0x027C, "GUI: Sort Descending"}, + {0x027D, "GUI: Filter"}, + {0x027E, "GUI: Set Clock"}, + {0x027F, "GUI: View Clock"}, + {0x0280, "GUI: Select Time Zone"}, + {0x0281, "GUI: Edit Time Zone"}, + {0x0282, "GUI: Set Alarm"}, + {0x0283, "GUI: Clear Alarm"}, + {0x0284, "GUI: Snooze Alarm"}, + {0x0285, "GUI: Reset Alarm"}, + {0x0286, "GUI: Synchronize"}, + {0x0287, "GUI: Send/Receive"}, + {0x0288, "GUI: Send To"}, + {0x0289, "GUI: Reply"}, + {0x028A, "GUI: Reply All"}, + {0x028B, "GUI: Forward Message"}, + {0x028C, "GUI: Send"}, + {0x028D, "GUI: Attach File"}, + {0x028E, "GUI: Upload"}, + {0x028F, "GUI: Download"}, + {0x0290, "GUI: Set Boards"}, + {0x0291, "GUI: Insert Row"}, + {0x0292, "GUI: Insert Column"}, + {0x0293, "GUI: insert File"}, + {0x0294, "GUI: Insert Picture"}, + {0x0295, "GUI: Insert Object"}, + {0x0296, "GUI: Insert Symbol"}, + {0x0297, "GUI: Save and Close"}, + {0x0298, "GUI: Rename"}, + {0x0299, "GUI: Merge"}, + {0x029A, "GUI: Split"}, + {0x029B, "GUI: Distribute Horz"}, + {0x029C, "GUI: Distribute Vert"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type00D[] = { + {0x0000, "Undefined"}, + {0x0001, "Digitizer"}, + {0x0002, "Pen"}, + {0x0003, "Light Pen"}, + {0x0004, "Touch Screen"}, + {0x0005, "Touch Pad"}, + {0x0006, "White Board"}, + {0x0007, "Coordinate Measuring Machine"}, + {0x0008, "3-D Digitizer"}, + {0x0009, "Stereo Plotter"}, + {0x000A, "Articulated Arm"}, + {0x000B, "Armature"}, + {0x000C, "Multiple Point Digitizer"}, + {0x000D, "Free Space Wand"}, + {0x0020, "Stylus"}, + {0x0021, "Puck"}, + {0x0022, "Finger"}, + {0x0030, "Tip Pressure"}, + {0x0031, "Barrel Pressure"}, + {0x0032, "In Range"}, + {0x0033, "Touch"}, + {0x0034, "Untouch"}, + {0x0035, "Tap"}, + {0x0036, "Quality"}, + {0x0037, "Data Valid"}, + {0x0038, "Transducer Index"}, + {0x0039, "Tablet Function Keys"}, + {0x003A, "Program Change Keys"}, + {0x003B, "Battery Strength"}, + {0x003C, "Invert"}, + {0x003D, "X Tilt"}, + {0x003E, "Y Tilt"}, + {0x003F, "Azimuth"}, + {0x0040, "Altitude"}, + {0x0041, "Twist"}, + {0x0042, "Tip Switch"}, + {0x0043, "Secondary Tip Switch"}, + {0x0044, "Barrel Switch"}, + {0x0045, "Eraser"}, + {0x0046, "Tablet Pick"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type00F[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type014[] = { + {0x0000, "Undefined"}, + {0x0001, "Alphanumeric Display"}, + {0x0020, "Display Attributes Report"}, + {0x0021, "ASCII Character Set"}, + {0x0022, "Data Read Back"}, + {0x0023, "Font Read Back"}, + {0x0024, "Display Control Report"}, + {0x0025, "Clear Display"}, + {0x0026, "Display Enable"}, + {0x0027, "Screen Saver Delay"}, + {0x0028, "Screen Saver Enable"}, + {0x0029, "Vertical Scroll"}, + {0x002A, "Horizontal Scroll"}, + {0x002B, "Character Report"}, + {0x002C, "Display Data"}, + {0x002D, "Display Status"}, + {0x002E, "Stat Not Ready"}, + {0x002F, "Stat Ready"}, + {0x0030, "Err Not a loadable character"}, + {0x0031, "Err Font data cannot be read"}, + {0x0032, "Cursor Position Report"}, + {0x0033, "Row"}, + {0x0034, "Column"}, + {0x0035, "Rows"}, + {0x0036, "Columns"}, + {0x0037, "Cursor Pixel Positioning"}, + {0x0038, "Cursor Mode"}, + {0x0039, "Cursor Enable"}, + {0x003A, "Cursor Blink"}, + {0x003B, "Font Report"}, + {0x003C, "Font Data"}, + {0x003D, "Character Width"}, + {0x003E, "Character Height"}, + {0x003F, "Character Spacing Horizontal"}, + {0x0040, "Character Spacing Vertical"}, + {0x0041, "Unicode Character Set"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type040[] = { + {0x0000, "Undefined"}, + {0x0001, "Medical Ultrasound"}, + {0x0020, "VCR/Acquisition"}, + {0x0021, "Freeze/Thaw"}, + {0x0022, "Clip Store"}, + {0x0023, "Update"}, + {0x0024, "Next"}, + {0x0025, "Save"}, + {0x0026, "Print"}, + {0x0027, "Microphone Enable"}, + {0x0040, "Cine"}, + {0x0041, "Transmit Power"}, + {0x0042, "Volume"}, + {0x0043, "Focus"}, + {0x0044, "Depth"}, + {0x0060, "Soft Step - Primary"}, + {0x0061, "Soft Step - Secondary"}, + {0x0070, "Depth Gain Compensation"}, + {0x0080, "Zoom Select"}, + {0x0081, "Zoom Adjust"}, + {0x0082, "Spectral Doppler Mode Select"}, + {0x0083, "Spectral Doppler Adjust"}, + {0x0084, "Color Doppler Mode Select"}, + {0x0085, "Color Doppler Adjust"}, + {0x0086, "Motion Mode Select"}, + {0x0087, "Motion Mode Adjust"}, + {0x0088, "2-D Mode Select"}, + {0x0089, "2-D Mode Adjust"}, + {0x00A0, "Soft Control Select"}, + {0x00A1, "Soft Control Adjust"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type080[] = { + {0x0000, "Undefined"}, + {0x0001, "Monitor Control"}, + {0x0002, "EDID Information"}, + {0x0003, "VDIF Information"}, + {0x0004, "VESA Version"}, + {0x0005, "On Screen Display"}, + {0x0006, "Auto Size Center"}, + {0x0007, "Polarity Horz Synch"}, + {0x0008, "Polarity Vert Synch"}, + {0x0009, "Sync Type"}, + {0x000A, "Screen Position"}, + {0x000B, "Horizontal Frequency"}, + {0x000C, "Vertical Frequency"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type082[] = { + {0x0010, "Brightness"}, + {0x0012, "Contrast"}, + {0x0016, "Video Gain Red"}, + {0x0018, "Video Gain Green"}, + {0x001A, "Video Gain Blue"}, + {0x001C, "Focus"}, + {0x0020, "Horizontal Position"}, + {0x0022, "Horizontal Size"}, + {0x0024, "Horizontal Pincushion"}, + {0x0026, "Horizontal Pincushion Balance"}, + {0x0028, "Horizontal Misconvergence"}, + {0x002A, "Horizontal Linearity"}, + {0x002C, "Horizontal Linearity Balance"}, + {0x0030, "Vertical Position"}, + {0x0032, "Vertical Size"}, + {0x0034, "Vertical Pincushion"}, + {0x0036, "Vertical Pincushion Balance"}, + {0x0038, "Vertical Misconvergence"}, + {0x003A, "Vertical Linearity"}, + {0x003C, "Vertical Linearity Balance"}, + {0x0040, "Parallelogram Distortion"}, + {0x0042, "Trapezoidal Distortion"}, + {0x0044, "Tilt"}, + {0x0046, "Top Corner Distortion Control"}, + {0x0048, "Top Corner Distortion Balance"}, + {0x004A, "Bottom Corner Distortion Control"}, + {0x004C, "Bottom Corner Distortion Balance"}, + {0x0056, "Moir Horizontal"}, + {0x0058, "Moir Vertical"}, + {0x005E, "Input Level Select"}, + {0x0060, "Input Source Select"}, + {0x0062, "Stereo Mode"}, + {0x006C, "Video Black Level Red"}, + {0x006E, "Video Black Level Green"}, + {0x0070, "Video Black Level Blue"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type083[] = { + {0x0000, "Undefined"}, + {0x0001, "Settings"}, + {0x0002, "Degauss"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type084[] = { + {0x0000, "Undefined"}, + {0x0001, "iName"}, + {0x0002, "PresentStatus"}, + {0x0003, "ChangedStatus"}, + {0x0004, "UPS"}, + {0x0005, "PowerSupply"}, + {0x0010, "BatterySystem"}, + {0x0011, "BatterySystemID"}, + {0x0012, "Battery"}, + {0x0013, "BatteryID"}, + {0x0014, "Charger"}, + {0x0015, "ChargerID"}, + {0x0016, "PowerConverter"}, + {0x0017, "PowerConverterID"}, + {0x0018, "OutletSystem"}, + {0x0019, "OutletSystemID"}, + {0x001A, "Input"}, + {0x001B, "InputID"}, + {0x001C, "Output"}, + {0x001D, "OutputID"}, + {0x001E, "Flow"}, + {0x001F, "FlowID"}, + {0x0020, "Outlet"}, + {0x0021, "OutletID"}, + {0x0022, "Gang"}, + {0x0023, "GangID"}, + {0x0024, "Sink"}, + {0x0025, "SinkID"}, + {0x0030, "Voltage"}, + {0x0031, "Current"}, + {0x0032, "Frequency"}, + {0x0033, "ApparentPower"}, + {0x0034, "ActivePower"}, + {0x0035, "PercentLoad"}, + {0x0036, "Temperature"}, + {0x0037, "Humidity"}, + {0x0040, "ConfigVoltage"}, + {0x0041, "ConfigCurrent"}, + {0x0042, "ConfigFrequency"}, + {0x0043, "ConfigApparentPower"}, + {0x0044, "ConfigActivePower"}, + {0x0045, "ConfigPercentLoad"}, + {0x0046, "ConfigTemperature"}, + {0x0047, "ConfigHumidity"}, + {0x0050, "SwitchOnControl"}, + {0x0051, "SwitchOffControl"}, + {0x0052, "ToggleControl"}, + {0x0053, "LowVoltageTransfer"}, + {0x0054, "HighVoltageTransfer"}, + {0x0055, "DelayBeforeReboot"}, + {0x0056, "DelayBeforeStartup"}, + {0x0057, "DelayBeforeShutdown"}, + {0x0058, "Test"}, + {0x0059, "Vendorspecificcommand"}, + {0x0060, "Present"}, + {0x0061, "Good"}, + {0x0062, "InternalFailure"}, + {0x0063, "VoltageOutOfRange"}, + {0x0064, "FrequencyOutOfRange"}, + {0x0065, "Overload"}, + {0x0066, "OverCharged"}, + {0x0067, "OverTemperature"}, + {0x0068, "ShutdownRequested"}, + {0x0069, "ShutdownImminent"}, + {0x006A, "VendorSpecificAnswerValid"}, + {0x006B, "SwitchOn/Off"}, + {0x006C, "Switcheble"}, + {0x006D, "Used"}, + {0x006E, "Boost"}, + {0x006F, "Buck"}, + {0x0070, "Initialized"}, + {0x0071, "Tested"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type085[] = { + {0x0000, "Undefined"}, + {0x0001, "SMBBatteryMode"}, + {0x0002, "SMBBatteryStatus"}, + {0x0003, "SMBAlarmWarning"}, + {0x0004, "SMBChargerMode"}, + {0x0005, "SMBChargerStatus"}, + {0x0006, "SMBChargerSpecInfo"}, + {0x0007, "SMBSelectorState"}, + {0x0008, "SMBSelectorPreset"}, + {0x0009, "SMBSelectorInfo"}, + {0x0010, "OptionalMfgFunction1"}, + {0x0011, "OptionalMfgFunction2"}, + {0x0012, "OptionalMfgFunction3"}, + {0x0013, "OptionalMfgFunction4"}, + {0x0014, "OptionalMfgFunction5"}, + {0x0015, "ConnectionToSMBus"}, + {0x0016, "OutputConnection"}, + {0x0017, "ChargerConnection"}, + {0x0018, "BatteryInsertion"}, + {0x0019, "Usenext"}, + {0x001A, "OKToUse"}, + {0x0028, "ManufacturerAccess"}, + {0x0029, "RemainingCapacityLimit"}, + {0x002A, "RemainingTimeLimit"}, + {0x002B, "AtRate"}, + {0x002C, "CapacityMode"}, + {0x002D, "BroadcastToCharger"}, + {0x002E, "PrimaryBattery"}, + {0x002F, "ChargeController"}, + {0x0040, "TerminateCharge"}, + {0x0041, "TermminateDischarge"}, + {0x0042, "BelowRemainingCapacityLimit"}, + {0x0043, "RemainingTimeLimitExpired"}, + {0x0044, "Charging"}, + {0x0045, "Discharging"}, + {0x0046, "FullyCharged"}, + {0x0047, "FullyDischarged"}, + {0x0048, "ConditionningFlag"}, + {0x0049, "AtRateOK"}, + {0x004A, "SMBErrorCode"}, + {0x004B, "NeedReplacement"}, + {0x0060, "AtRateTimeToFull"}, + {0x0061, "AtRateTimeToEmpty"}, + {0x0062, "AverageCurrent"}, + {0x0063, "Maxerror"}, + {0x0064, "RelativeStateOfCharge"}, + {0x0065, "AbsoluteStateOfCharge"}, + {0x0066, "RemainingCapacity"}, + {0x0067, "FullChargeCapacity"}, + {0x0068, "RunTimeToEmpty"}, + {0x0069, "AverageTimeToEmpty"}, + {0x006A, "AverageTimeToFull"}, + {0x006B, "CycleCount"}, + {0x0080, "BattPackModelLevel"}, + {0x0081, "InternalChargeController"}, + {0x0082, "PrimaryBatterySupport"}, + {0x0083, "DesignCapacity"}, + {0x0084, "SpecificationInfo"}, + {0x0085, "ManufacturerDate"}, + {0x0086, "SerialNumber"}, + {0x0087, "iManufacturerName"}, + {0x0088, "iDevicename"}, + {0x0089, "iDeviceChemistery"}, + {0x008A, "iManufacturerData"}, + {0x008B, "Rechargeable"}, + {0x008C, "WarningCapacityLimit"}, + {0x008D, "CapacityGranularity1"}, + {0x008E, "CapacityGranularity2"}, + {0x00C0, "InhibitCharge"}, + {0x00C1, "EnablePolling"}, + {0x00C2, "ResetToZero"}, + {0x00D0, "ACPresent"}, + {0x00D1, "BatteryPresent"}, + {0x00D2, "PowerFail"}, + {0x00D3, "AlarmInhibited"}, + {0x00D4, "ThermistorUnderRange"}, + {0x00D5, "ThermistorHot"}, + {0x00D6, "ThermistorCold"}, + {0x00D7, "ThermistorOverRange"}, + {0x00D8, "VoltageOutOfRange"}, + {0x00D9, "CurrentOutOfRange"}, + {0x00DA, "CurrentNotRegulated"}, + {0x00DB, "VoltageNotRegulated"}, + {0x00DC, "MasterMode"}, + {0x00DD, "ChargerBattery/HostControlled"}, + {0x00F0, "ChargerSpecInfo"}, + {0x00F1, "ChargerSpecRef"}, + {0x00F2, "Level2"}, + {0x00F3, "Level3"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type086[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type087[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type08C[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type08D[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type08E[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type08F[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type090[] = { + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_type091[] = { + + {0xFFFF, ""}, +}; + +/* +struct S_USAGE_TYPES_STR usage_typeF1F2[] = { + { 0x0000, "?????0000" }, + { 0x0001, "?????1111" }, + + { 0xFFFF, "" } +}; +*/ + +struct hid_usage_types_string hid_usage_typeFF00[] = { + {0x00E9, "Base Up"}, + {0x00EA, "Base Down"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_typeFF84[] = { + {0x0000, "Undefined"}, + {0x0001, "iName"}, + {0x0002, "PresentStatus"}, + {0x0003, "ChangedStatus"}, + {0x0004, "UPS"}, + {0x0005, "PowerSupply"}, + {0x0010, "BatterySystem"}, + {0x0011, "BatterySystemID"}, + {0x0012, "Battery"}, + {0x0013, "BatteryID"}, + {0x0014, "Charger"}, + {0x0015, "ChargerID"}, + {0x0016, "PowerConverter"}, + {0x0017, "PowerConverterID"}, + {0x0018, "OutletSystem"}, + {0x0019, "OutletSystemID"}, + {0x001A, "Input"}, + {0x001B, "InputID"}, + {0x001C, "Output"}, + {0x001D, "OutputID"}, + {0x001E, "Flow"}, + {0x001F, "FlowID"}, + {0x0020, "Outlet"}, + {0x0021, "OutletID"}, + {0x0022, "Gang"}, + {0x0023, "GangID"}, + {0x0024, "Sink"}, + {0x0025, "SinkID"}, + {0x0030, "Voltage"}, + {0x0031, "Current"}, + {0x0032, "Frequency"}, + {0x0033, "ApparentPower"}, + {0x0034, "ActivePower"}, + {0x0035, "PercentLoad"}, + {0x0036, "Temperature"}, + {0x0037, "Humidity"}, + {0x0040, "ConfigVoltage"}, + {0x0041, "ConfigCurrent"}, + {0x0042, "ConfigFrequency"}, + {0x0043, "ConfigApparentPower"}, + {0x0044, "ConfigActivePower"}, + {0x0045, "ConfigPercentLoad"}, + {0x0046, "ConfigTemperature"}, + {0x0047, "ConfigHumidity"}, + {0x0050, "SwitchOnControl"}, + {0x0051, "SwitchOffControl"}, + {0x0052, "ToggleControl"}, + {0x0053, "LowVoltageTransfer"}, + {0x0054, "HighVoltageTransfer"}, + {0x0055, "DelayBeforeReboot"}, + {0x0056, "DelayBeforeStartup"}, + {0x0057, "DelayBeforeShutdown"}, + {0x0058, "Test"}, + {0x0059, "Vendorspecificcommand"}, + {0x0060, "Present"}, + {0x0061, "Good"}, + {0x0062, "InternalFailure"}, + {0x0063, "VoltageOutOfRange"}, + {0x0064, "FrequencyOutOfRange"}, + {0x0065, "Overload"}, + {0x0066, "OverCharged"}, + {0x0067, "OverTemperature"}, + {0x0068, "ShutdownRequested"}, + {0x0069, "ShutdownImminent"}, + {0x006A, "VendorSpecificAnswerValid"}, + {0x006B, "SwitchOn/Off"}, + {0x006C, "Switcheble"}, + {0x006D, "Used"}, + {0x006E, "Boost"}, + {0x006F, "Buck"}, + {0x0070, "Initialized"}, + {0x0071, "Tested"}, + + {0xFFFF, ""}, +}; + +struct hid_usage_types_string hid_usage_typeFF85[] = { + {0x0000, "Undefined"}, + {0x0001, "SMBBatteryMode"}, + {0x0002, "SMBBatteryStatus"}, + {0x0003, "SMBAlarmWarning"}, + {0x0004, "SMBChargerMode"}, + {0x0005, "SMBChargerStatus"}, + {0x0006, "SMBChargerSpecInfo"}, + {0x0007, "SMBSelectorState"}, + {0x0008, "SMBSelectorPreset"}, + {0x0009, "SMBSelectorInfo"}, + {0x0010, "OptionalMfgFunction1"}, + {0x0011, "OptionalMfgFunction2"}, + {0x0012, "OptionalMfgFunction3"}, + {0x0013, "OptionalMfgFunction4"}, + {0x0014, "OptionalMfgFunction5"}, + {0x0015, "ConnectionToSMBus"}, + {0x0016, "OutputConnection"}, + {0x0017, "ChargerConnection"}, + {0x0018, "BatteryInsertion"}, + {0x0019, "Usenext"}, + {0x001A, "OKToUse"}, + {0x0028, "ManufacturerAccess"}, + {0x0029, "RemainingCapacityLimit"}, + {0x002A, "RemainingTimeLimit"}, + {0x002B, "AtRate"}, + {0x002C, "CapacityMode"}, + {0x002D, "BroadcastToCharger"}, + {0x002E, "PrimaryBattery"}, + {0x002F, "ChargeController"}, + {0x0040, "TerminateCharge"}, + {0x0041, "TermminateDischarge"}, + {0x0042, "BelowRemainingCapacityLimit"}, + {0x0043, "RemainingTimeLimitExpired"}, + {0x0044, "Charging"}, + {0x0045, "Discharging"}, + {0x0046, "FullyCharged"}, + {0x0047, "FullyDischarged"}, + {0x0048, "ConditionningFlag"}, + {0x0049, "AtRateOK"}, + {0x004A, "SMBErrorCode"}, + {0x004B, "NeedReplacement"}, + {0x0060, "AtRateTimeToFull"}, + {0x0061, "AtRateTimeToEmpty"}, + {0x0062, "AverageCurrent"}, + {0x0063, "Maxerror"}, + {0x0064, "RelativeStateOfCharge"}, + {0x0065, "AbsoluteStateOfCharge"}, + {0x0066, "RemainingCapacity"}, + {0x0067, "FullChargeCapacity"}, + {0x0068, "RunTimeToEmpty"}, + {0x0069, "AverageTimeToEmpty"}, + {0x006A, "AverageTimeToFull"}, + {0x006B, "CycleCount"}, + {0x0080, "BattPackModelLevel"}, + {0x0081, "InternalChargeController"}, + {0x0082, "PrimaryBatterySupport"}, + {0x0083, "DesignCapacity"}, + {0x0084, "SpecificationInfo"}, + {0x0085, "ManufacturerDate"}, + {0x0086, "SerialNumber"}, + {0x0087, "iManufacturerName"}, + {0x0088, "iDevicename"}, + {0x0089, "iDeviceChemistery"}, + {0x008A, "iManufacturerData"}, + {0x008B, "Rechargeable"}, + {0x008C, "WarningCapacityLimit"}, + {0x008D, "CapacityGranularity1"}, + {0x008E, "CapacityGranularity2"}, + {0x00C0, "InhibitCharge"}, + {0x00C1, "EnablePolling"}, + {0x00C2, "ResetToZero"}, + {0x00D0, "ACPresent"}, + {0x00D1, "BatteryPresent"}, + {0x00D2, "PowerFail"}, + {0x00D3, "AlarmInhibited"}, + {0x00D4, "ThermistorUnderRange"}, + {0x00D5, "ThermistorHot"}, + {0x00D6, "ThermistorCold"}, + {0x00D7, "ThermistorOverRange"}, + {0x00D8, "VoltageOutOfRange"}, + {0x00D9, "CurrentOutOfRange"}, + {0x00DA, "CurrentNotRegulated"}, + {0x00DB, "VoltageNotRegulated"}, + {0x00DC, "MasterMode"}, + {0x00DD, "ChargerBattery/HostControlled"}, + {0x00F0, "ChargerSpecInfo"}, + {0x00F1, "ChargerSpecRef"}, + {0x00F2, "Level2"}, + {0x00F3, "Level3"}, + + {0xFFFF, ""}, +}; + +// Usage Pages +struct hid_usage_pages_string hid_usage_page_strings[] = { + {0x0000, NULL, "Undefined"}, + {0x0001, hid_usage_type001, "Generic Desktop"}, + {0x0002, hid_usage_type002, "Simulation"}, + {0x0003, hid_usage_type003, "Virtual Reality"}, + {0x0004, hid_usage_type004, "Sport"}, + {0x0005, hid_usage_type005, "Game"}, + {0x0006, hid_usage_type006, "Generic Device"}, + {0x0007, hid_usage_type007, "Keyboard/Keypad"}, + {0x0008, hid_usage_type008, "LEDs"}, + {0x0009, NULL, "Button"}, + {0x000A, NULL, "Ordinal"}, + {0x000B, hid_usage_type00B, "Telephony"}, + {0x000C, hid_usage_type00C, "Consumer"}, + {0x000D, hid_usage_type00D, "Digitizer"}, + {0x000F, hid_usage_type00F, "PID Page"}, + {0x0010, NULL, "Unicode"}, + {0x0014, hid_usage_type014, "Alphanumeric Display"}, + {0x0040, hid_usage_type040, "Meidcal Insturments"}, + {0x0080, hid_usage_type080, "Monitor Pages"}, + {0x0081, NULL, "Monitor Pages"}, + {0x0082, hid_usage_type082, "Monitor Pages"}, + {0x0083, hid_usage_type083, "Monitor Pages"}, + {0x0084, hid_usage_type084, "Power Pages"}, + {0x0085, hid_usage_type085, "Power Pages"}, + {0x0086, hid_usage_type086, "Power Pages"}, + {0x0087, hid_usage_type087, "Power Pages"}, + {0x008C, hid_usage_type08C, "Barcode Scanner"}, + {0x008D, hid_usage_type08D, "Scale"}, + {0x008E, hid_usage_type08E, "Magnetic Stripe Reading (MSR) Devices"}, + {0x008F, hid_usage_type08F, "Reserved Point of Sale"}, + {0x0090, hid_usage_type090, "Camera Control"}, + {0x0091, hid_usage_type091, "Arcade"}, + //{ 0xF1F2, hid_usage_typeF1F2, "??????" }, // unknown: I have a MOSART Semi Wireless Mouse that uses this Upage + {0xFF00, hid_usage_typeFF00, "MS Non-Standard"}, + {0xFF84, hid_usage_typeFF84, "APC Non-Standard"}, + {0xFF85, hid_usage_typeFF85, "APC Non-Standard"}, + + {0xFFFF, NULL, ""}, +}; + +char hid_collection_str[][64] = { + "Physical", "Application", "Logical", "Report", "Named Array", "Usage Switch", "Usage Modifier", +}; \ No newline at end of file diff --git a/kernel/driver/hid/internal.h b/kernel/driver/hid/internal.h new file mode 100644 index 00000000..3da9db43 --- /dev/null +++ b/kernel/driver/hid/internal.h @@ -0,0 +1,37 @@ +#pragma once +#include + +extern struct hid_usage_types_string hid_usage_type001[]; +extern struct hid_usage_types_string hid_usage_type002[]; +extern struct hid_usage_types_string hid_usage_type003[]; +extern struct hid_usage_types_string hid_usage_type004[]; +extern struct hid_usage_types_string hid_usage_type005[]; +extern struct hid_usage_types_string hid_usage_type006[]; +extern struct hid_usage_types_string hid_usage_type007[]; +extern struct hid_usage_types_string hid_usage_type008[]; +extern struct hid_usage_types_string hid_usage_type00B[]; +extern struct hid_usage_types_string hid_usage_type00C[]; +extern struct hid_usage_types_string hid_usage_type00D[]; +extern struct hid_usage_types_string hid_usage_type00F[]; +extern struct hid_usage_types_string hid_usage_type014[]; +extern struct hid_usage_types_string hid_usage_type040[]; +extern struct hid_usage_types_string hid_usage_type080[]; +extern struct hid_usage_types_string hid_usage_type082[]; +extern struct hid_usage_types_string hid_usage_type083[]; +extern struct hid_usage_types_string hid_usage_type084[]; +extern struct hid_usage_types_string hid_usage_type085[]; +extern struct hid_usage_types_string hid_usage_type086[]; +extern struct hid_usage_types_string hid_usage_type087[]; +extern struct hid_usage_types_string hid_usage_type08C[]; +extern struct hid_usage_types_string hid_usage_type08D[]; +extern struct hid_usage_types_string hid_usage_type08E[]; +extern struct hid_usage_types_string hid_usage_type08F[]; +extern struct hid_usage_types_string hid_usage_type090[]; +extern struct hid_usage_types_string hid_usage_type091[]; +extern struct hid_usage_types_string hid_usage_typeFF00[]; +extern struct hid_usage_types_string hid_usage_typeFF84[]; +extern struct hid_usage_types_string hid_usage_typeFF85[]; + +extern struct hid_usage_pages_string hid_usage_page_strings[]; + +extern char hid_collection_str[][64]; \ No newline at end of file diff --git a/kernel/driver/hid/usbhid/Makefile b/kernel/driver/hid/usbhid/Makefile new file mode 100644 index 00000000..39103944 --- /dev/null +++ b/kernel/driver/hid/usbhid/Makefile @@ -0,0 +1,15 @@ + +CFLAGS += -I . + + +kernel_driver_usbhid_objs:= $(shell find ./*.c) + +ECHO: + @echo "$@" + +$(kernel_driver_usbhid_objs): ECHO + gcc $(CFLAGS) -c $@ -o $@.o + +all: $(kernel_driver_hid_objs) $(kernel_driver_hid_subdirs) + @echo $(kernel_driver_hid_objs) + diff --git a/kernel/driver/usb/usb.h b/kernel/driver/usb/usb.h index fa521902..c2298342 100644 --- a/kernel/driver/usb/usb.h +++ b/kernel/driver/usb/usb.h @@ -105,7 +105,8 @@ struct usb_interface_desc uint8_t num_endpoints; // 当前interface的端点数量 uint8_t interface_class; // Class code uint8_t interface_sub_class; // Sub class code - uint8_t interface_protocol; // 协议 These codes are qualified by the value of thebInterfaceClass and the bInterfaceSubClass fields. + uint8_t interface_protocol; // 协议 These codes are qualified by the value of thebInterfaceClass and the + // bInterfaceSubClass fields. uint8_t index; // index of String Descriptor describing this interface } __attribute__((packed)); @@ -162,6 +163,7 @@ struct usb_request_packet_t #define USB_REQ_TYPE_GET_REQUEST (__USB_REQ_TYPE_D2H | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_DEVICE) #define USB_REQ_TYPE_SET_REQUEST (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_DEVICE) +#define USB_REQ_TYPE_GET_INTERFACE_REQUEST (__USB_REQ_TYPE_D2H | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_INTERFACE) #define USB_REQ_TYPE_SET_INTERFACE (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_INTERFACE) #define USB_REQ_TYPE_SET_CLASS_INTERFACE (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_CLASS | __USB_REQ_TYPE_INTERFACE) @@ -244,12 +246,12 @@ enum * @brief 该宏定义用于声明usb请求包,并初始化其中的各个字段 * */ -#define DECLARE_USB_PACKET(pak_name, _trans_req_type, _trans_request, _trans_value, _trans_index, _transfer_length) \ - struct usb_request_packet_t pak_name = {0}; \ - pak_name.request_type = (_trans_req_type); \ - pak_name.request = (_trans_request); \ - pak_name.value = (_trans_value); \ - pak_name.index = (_trans_index); \ +#define DECLARE_USB_PACKET(pak_name, _trans_req_type, _trans_request, _trans_value, _trans_index, _transfer_length) \ + struct usb_request_packet_t pak_name = {0}; \ + pak_name.request_type = (_trans_req_type); \ + pak_name.request = (_trans_request); \ + pak_name.value = (_trans_value); \ + pak_name.index = (_trans_index); \ pak_name.length = (_transfer_length); /* @@ -283,6 +285,22 @@ enum USB_CLASS_VENDOR_SPEC = 0XFF, }; +/** + * @brief usb hid descriptor的结构体 + * + */ +struct usb_hid_desc +{ + uint8_t len; + uint8_t type; // USB_DT_HID + uint16_t bcdHID; // 标识HIDClass规范版本的数字表达式。 + + uint8_t country_code; + uint8_t descriptors_num; // the number of class descriptors + uint8_t desc_type; // Constant name identifying type of class descriptor + uint16_t report_desc_len; // Report descriptor的大小 +}; + /** * @brief 初始化usb驱动程序 * diff --git a/kernel/driver/usb/xhci/xhci.c b/kernel/driver/usb/xhci/xhci.c index f9f0c929..308d1bff 100644 --- a/kernel/driver/usb/xhci/xhci.c +++ b/kernel/driver/usb/xhci/xhci.c @@ -1,14 +1,15 @@ #include "xhci.h" #include "internal.h" +#include #include -#include #include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include // 由于xhci寄存器读取需要对齐,因此禁用GCC优化选项 #pragma GCC optimize("O0") @@ -30,7 +31,8 @@ static int xhci_hc_reset(int id); static int xhci_hc_stop_legacy(int id); static int xhci_hc_start_sched(int id); static int xhci_hc_stop_sched(int id); -static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset, uint32_t *count, uint16_t *protocol_flag); +static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset, + uint32_t *count, uint16_t *protocol_flag); static int xhci_hc_pair_ports(int id); static uint64_t xhci_create_ring(int trbs); static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr); @@ -40,30 +42,43 @@ static int xhci_hc_start_ports(int id); static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring); static uint64_t xhci_initialize_slot(const int id, const int port, const int speed, const int max_packet); -static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const int port_id, const int ep_num, const int max_packet, const int max_burst, const int type, const int direction, const int speed, const int ep_interval); +static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const int port_id, const int ep_num, + const int max_packet, const int max_burst, const int type, const int direction, + const int speed, const int ep_interval); static int xhci_set_address(const int id, const uint64_t slot_vaddr, const int slot_id, const bool block); -static int xhci_control_in(const int id, struct usb_request_packet_t *packet, void *target, const int port_id, const int max_packet); -static int xhci_control_out(const int id, struct usb_request_packet_t *packet, void *target, const int slot_id, const int max_packet); -static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_packet_t *packet, const uint8_t direction); -static int xhci_data_stage(struct xhci_ep_info_t *ep, uint64_t buf_vaddr, uint8_t trb_type, const uint32_t size, uint8_t direction, const int max_packet, const uint64_t status_vaddr); +static int xhci_control_in(const int id, struct usb_request_packet_t *packet, void *target, const int port_id, + const int max_packet); +static int xhci_control_out(const int id, struct usb_request_packet_t *packet, void *target, const int slot_id, + const int max_packet); +static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_packet_t *packet, + const uint8_t direction); +static int xhci_data_stage(struct xhci_ep_info_t *ep, uint64_t buf_vaddr, uint8_t trb_type, const uint32_t size, + uint8_t direction, const int max_packet, const uint64_t status_vaddr); static int xhci_status_stage(struct xhci_ep_info_t *ep, uint8_t direction, uint64_t status_buf_vaddr); static int xhci_wait_for_interrupt(const int id, uint64_t status_vaddr); -static inline int xhci_get_desc(const int id, const int port_id, void *target, const uint16_t desc_type, const uint8_t desc_index, const uint16_t lang_id, const uint16_t length); +static inline int xhci_get_desc(const int id, const int port_id, void *target, const uint16_t desc_type, + const uint8_t desc_index, const uint16_t lang_id, const uint16_t length); static int xhci_get_config_desc(const int id, const int port_id, struct usb_config_desc *conf_desc); -static inline int xhci_get_config_desc_full(const int id, const int port_id, const struct usb_config_desc *conf_desc, void *target); +static inline int xhci_get_config_desc_full(const int id, const int port_id, const struct usb_config_desc *conf_desc, + void *target); static int xhci_get_interface_desc(const void *in_buf, const uint8_t if_num, struct usb_interface_desc **if_desc); -static inline int xhci_get_endpoint_desc(const struct usb_interface_desc *if_desc, const uint8_t ep_num, struct usb_endpoint_desc **ep_desc); +static inline int xhci_get_endpoint_desc(const struct usb_interface_desc *if_desc, const uint8_t ep_num, + struct usb_endpoint_desc **ep_desc); static int xhci_get_descriptor(const int id, const int port_id, struct usb_device_desc *dev_desc); static int xhci_configure_port(const int id, const int port_id); -static int xhci_configure_endpoint(const int id, const int port_id, const uint8_t ep_num, const uint8_t ep_type, struct usb_endpoint_desc *ep_desc); +static int xhci_configure_endpoint(const int id, const int port_id, const uint8_t ep_num, const uint8_t ep_type, + struct usb_endpoint_desc *ep_desc); +static int xhci_get_hid_report(int id, int port_id, int interface_number, void *ret_hid_report, + uint32_t hid_report_len); +static int xhci_get_hid_descriptor(int id, int port_id, const void *full_conf, int interface_number, + struct usb_hid_desc **ret_hid_desc); -hardware_intr_controller xhci_hc_intr_controller = - { - .enable = xhci_hc_irq_enable, - .disable = xhci_hc_irq_disable, - .install = xhci_hc_irq_install, - .uninstall = xhci_hc_irq_uninstall, - .ack = apic_local_apic_edge_ack, +hardware_intr_controller xhci_hc_intr_controller = { + .enable = xhci_hc_irq_enable, + .disable = xhci_hc_irq_disable, + .install = xhci_hc_irq_install, + .uninstall = xhci_hc_irq_uninstall, + .ack = apic_local_apic_edge_ack, }; /** @@ -207,7 +222,8 @@ static __always_inline void __xhci_write_trb(struct xhci_ep_info_t *ep_info, str */ static __always_inline uint64_t xhci_get_device_context_vaddr(const int id, const int port_id) { - return (uint64_t)phys_2_virt(__read8b(xhci_hc[id].dcbaap_vaddr + (xhci_hc[id].ports[port_id].slot_id * sizeof(uint64_t)))); + return (uint64_t)phys_2_virt( + __read8b(xhci_hc[id].dcbaap_vaddr + (xhci_hc[id].ports[port_id].slot_id * sizeof(uint64_t)))); } /** @@ -294,11 +310,13 @@ static int xhci_hc_stop_legacy(int id) { io_mfence(); // 接管控制权 - xhci_write_cap_reg32(id, current_offset, xhci_read_cap_reg32(id, current_offset) | XHCI_XECP_LEGACY_OS_OWNED); + xhci_write_cap_reg32(id, current_offset, + xhci_read_cap_reg32(id, current_offset) | XHCI_XECP_LEGACY_OS_OWNED); io_mfence(); // 等待响应完成 int timeout = XHCI_XECP_LEGACY_TIMEOUT; - while ((xhci_read_cap_reg32(id, current_offset) & XHCI_XECP_LEGACY_OWNING_MASK) != XHCI_XECP_LEGACY_OS_OWNED) + while ((xhci_read_cap_reg32(id, current_offset) & XHCI_XECP_LEGACY_OWNING_MASK) != + XHCI_XECP_LEGACY_OS_OWNED) { io_mfence(); usleep(1000); @@ -361,7 +379,8 @@ static int xhci_hc_stop_sched(int id) * @param protocol_flag 返回的与协议相关的flag * @return uint32_t 下一个列表项的偏移量 */ -static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset, uint32_t *count, uint16_t *protocol_flag) +static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset, + uint32_t *count, uint16_t *protocol_flag) { if (count) *count = 0; @@ -467,7 +486,8 @@ static int xhci_hc_pair_ports(int id) continue; io_mfence(); if ((xhci_hc[id].ports[i].offset == xhci_hc[id].ports[j].offset) && - ((xhci_hc[id].ports[i].flags & XHCI_PROTOCOL_INFO) != (xhci_hc[id].ports[j].flags & XHCI_PROTOCOL_INFO))) + ((xhci_hc[id].ports[i].flags & XHCI_PROTOCOL_INFO) != + (xhci_hc[id].ports[j].flags & XHCI_PROTOCOL_INFO))) { xhci_hc[id].ports[i].paired_port_num = j; xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_HAS_PAIR; @@ -482,11 +502,11 @@ static int xhci_hc_pair_ports(int id) for (int i = 0; i < xhci_hc[id].port_num; ++i) { io_mfence(); - if (XHCI_PORT_IS_USB3(id, i) || - (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i)))) + if (XHCI_PORT_IS_USB3(id, i) || (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i)))) xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_ACTIVE; } - kinfo("Found %d ports on root hub, usb2 ports:%d, usb3 ports:%d", xhci_hc[id].port_num, xhci_hc[id].port_num_u2, xhci_hc[id].port_num_u3); + kinfo("Found %d ports on root hub, usb2 ports:%d, usb3 ports:%d", xhci_hc[id].port_num, xhci_hc[id].port_num_u2, + xhci_hc[id].port_num_u3); /* // 打印配对结果 @@ -494,8 +514,9 @@ static int xhci_hc_pair_ports(int id) { if (XHCI_PORT_IS_USB3(id, i)) { - kdebug("USB3 port %d, offset=%d, pair with usb2 port %d, current port is %s", i, xhci_hc[id].ports[i].offset, - xhci_hc[id].ports[i].paired_port_num, XHCI_PORT_IS_ACTIVE(id, i) ? "active" : "inactive"); + kdebug("USB3 port %d, offset=%d, pair with usb2 port %d, current port is %s", i, + xhci_hc[id].ports[i].offset, xhci_hc[id].ports[i].paired_port_num, XHCI_PORT_IS_ACTIVE(id, i) ? "active" : + "inactive"); } else if (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))) // 单独的2.0接口 { @@ -721,8 +742,10 @@ void xhci_hc_irq_handler(uint64_t irq_num, uint64_t cid, struct pt_regs *regs) switch (event_trb_ptr->TRB_type) { case TRB_TYPE_TRANS_EVENT: // 当前 event trb是 transfer event TRB - // If SPD was encountered in this TD, comp_code will be SPD, else it should be SUCCESS (specs 4.10.1.1) - __write4b((uint64_t)phys_2_virt(event_trb.param), (event_trb.status | XHCI_IRQ_DONE)); // return code + bytes *not* transferred + // If SPD was encountered in this TD, comp_code will be SPD, else it should be SUCCESS + // (specs 4.10.1.1) + __write4b((uint64_t)phys_2_virt(event_trb.param), + (event_trb.status | XHCI_IRQ_DONE)); // return code + bytes *not* transferred break; default: @@ -871,14 +894,15 @@ static uint64_t xhci_initialize_slot(const int id, const int port, const int spe uint64_t device_context_vaddr = (uint64_t)kzalloc(xhci_hc[id].context_size * 32, 0); // kdebug("slot id=%d, device_context_vaddr=%#018lx, port=%d", slot_id, device_context_vaddr, port); // 写到数组中 - __write8b(xhci_hc[id].dcbaap_vaddr + (xhci_hc[id].ports[port].slot_id * sizeof(uint64_t)), virt_2_phys(device_context_vaddr)); + __write8b(xhci_hc[id].dcbaap_vaddr + (xhci_hc[id].ports[port].slot_id * sizeof(uint64_t)), + virt_2_phys(device_context_vaddr)); struct xhci_slot_context_t slot_ctx = {0}; slot_ctx.entries = 1; slot_ctx.speed = speed; slot_ctx.route_string = 0; slot_ctx.rh_port_num = port + 1; // 由于xhci控制器是1-base的,因此把驱动程序中存储的端口号加1,才是真实的端口号 - slot_ctx.max_exit_latency = 0; // 稍后会计算这个值 - slot_ctx.int_target = 0; // 当前全部使用第0个interrupter + slot_ctx.max_exit_latency = 0; // 稍后会计算这个值 + slot_ctx.int_target = 0; // 当前全部使用第0个interrupter slot_ctx.slot_state = XHCI_SLOT_STATE_DISABLED_OR_ENABLED; slot_ctx.device_address = 0; @@ -904,7 +928,9 @@ static uint64_t xhci_initialize_slot(const int id, const int port, const int spe * @param speed 传输速度 * @param ep_interval 端点的连续请求间隔 */ -static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const int port_id, const int ep_num, const int max_packet, const int max_burst, const int type, const int direction, const int speed, const int ep_interval) +static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const int port_id, const int ep_num, + const int max_packet, const int max_burst, const int type, const int direction, + const int speed, const int ep_interval) { // 由于目前只实现获取设备的描述符,因此暂时只支持control ep if (type != USB_EP_CONTROL && type != USB_EP_INTERRUPT) @@ -917,10 +943,12 @@ static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const in ep_ctx.tr_dequeue_ptr = virt_2_phys(xhci_hc[id].ports[port_id].ep_info[ep_num].ep_ring_vbase); xhci_ep_set_dequeue_cycle_state(&ep_ctx, XHCI_TRB_CYCLE_ON); - xhci_hc[id].ports[port_id].ep_info[ep_num].current_ep_ring_vaddr = xhci_hc[id].ports[port_id].ep_info[ep_num].ep_ring_vbase; + xhci_hc[id].ports[port_id].ep_info[ep_num].current_ep_ring_vaddr = + xhci_hc[id].ports[port_id].ep_info[ep_num].ep_ring_vbase; xhci_hc[id].ports[port_id].ep_info[ep_num].current_ep_ring_cycle = xhci_ep_get_dequeue_cycle_state(&ep_ctx); // kdebug("ep_ctx.tr_dequeue_ptr = %#018lx", ep_ctx.tr_dequeue_ptr); - // kdebug("xhci_hc[id].control_ep_info.current_ep_ring_cycle = %d", xhci_hc[id].control_ep_info.current_ep_ring_cycle); + // kdebug("xhci_hc[id].control_ep_info.current_ep_ring_cycle = %d", + // xhci_hc[id].control_ep_info.current_ep_ring_cycle); kdebug("max_packet=%d, max_burst=%d", max_packet, max_burst); switch (type) { @@ -1032,7 +1060,8 @@ failed:; * @param direction 传输的方向 * @return int 产生的TRB数量 */ -static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_packet_t *packet, const uint8_t direction) +static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_packet_t *packet, + const uint8_t direction) { // kdebug("ep->current_ep_ring_cycle=%d", ep->current_ep_ring_cycle); struct xhci_TRB_setup_stage_t trb = {0}; @@ -1066,7 +1095,8 @@ static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_ * @param status_vaddr event data TRB的缓冲区(4字节,且地址按照16字节对齐) * @return int 产生的TRB数量 */ -static int xhci_data_stage(struct xhci_ep_info_t *ep, uint64_t buf_vaddr, uint8_t trb_type, const uint32_t size, uint8_t direction, const int max_packet, const uint64_t status_vaddr) +static int xhci_data_stage(struct xhci_ep_info_t *ep, uint64_t buf_vaddr, uint8_t trb_type, const uint32_t size, + uint8_t direction, const int max_packet, const uint64_t status_vaddr) { if (size == 0) return 0; @@ -1204,10 +1234,12 @@ static int xhci_wait_for_interrupt(const int id, uint64_t status_vaddr) * @param max_packet 最大数据包大小 * @return int 读取到的数据的大小 */ -static int xhci_control_in(const int id, struct usb_request_packet_t *packet, void *target, const int port_id, const int max_packet) +static int xhci_control_in(const int id, struct usb_request_packet_t *packet, void *target, const int port_id, + const int max_packet) { - uint64_t status_buf_vaddr = (uint64_t)kzalloc(16, 0); // 本来是要申请4bytes的buffer的,但是因为xhci控制器需要16bytes对齐,因此申请16bytes + uint64_t status_buf_vaddr = + (uint64_t)kzalloc(16, 0); // 本来是要申请4bytes的buffer的,但是因为xhci控制器需要16bytes对齐,因此申请16bytes uint64_t data_buf_vaddr = 0; int retval = 0; @@ -1216,7 +1248,8 @@ static int xhci_control_in(const int id, struct usb_request_packet_t *packet, vo if (packet->length) { data_buf_vaddr = (uint64_t)kzalloc(packet->length, 0); - xhci_data_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], data_buf_vaddr, TRB_TYPE_DATA_STAGE, packet->length, XHCI_DIR_IN_BIT, max_packet, status_buf_vaddr); + xhci_data_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], data_buf_vaddr, TRB_TYPE_DATA_STAGE, + packet->length, XHCI_DIR_IN_BIT, max_packet, status_buf_vaddr); } /* @@ -1275,7 +1308,8 @@ done:; * @param max_packet 最大数据包大小 * @return int 读取到的数据的大小 */ -static int xhci_control_out(const int id, struct usb_request_packet_t *packet, void *target, const int port_id, const int max_packet) +static int xhci_control_out(const int id, struct usb_request_packet_t *packet, void *target, const int port_id, + const int max_packet) { uint64_t status_buf_vaddr = (uint64_t)kzalloc(16, 0); uint64_t data_buf_vaddr = 0; @@ -1287,7 +1321,8 @@ static int xhci_control_out(const int id, struct usb_request_packet_t *packet, v if (packet->length) { data_buf_vaddr = (uint64_t)kzalloc(packet->length, 0); - xhci_data_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], data_buf_vaddr, TRB_TYPE_DATA_STAGE, packet->length, XHCI_DIR_OUT_BIT, max_packet, status_buf_vaddr); + xhci_data_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], data_buf_vaddr, TRB_TYPE_DATA_STAGE, + packet->length, XHCI_DIR_OUT_BIT, max_packet, status_buf_vaddr); } #ifndef __QEMU_EMULATION__ @@ -1338,7 +1373,8 @@ done:; * @param length 要传输的数据长度 * @return int 错误码 */ -static inline int xhci_get_desc(const int id, const int port_id, void *target, const uint16_t desc_type, const uint8_t desc_index, const uint16_t lang_id, const uint16_t length) +static inline int xhci_get_desc(const int id, const int port_id, void *target, const uint16_t desc_type, + const uint8_t desc_index, const uint16_t lang_id, const uint16_t length) { struct usb_device_desc *dev_desc = xhci_hc[id].ports[port_id].dev_desc; int count; @@ -1347,7 +1383,13 @@ static inline int xhci_get_desc(const int id, const int port_id, void *target, c // 设备端口没有对应的描述符 if (unlikely(dev_desc == NULL)) return -EINVAL; - DECLARE_USB_PACKET(ctrl_in_packet, USB_REQ_TYPE_GET_REQUEST, USB_REQ_GET_DESCRIPTOR, (desc_type << 8) | desc_index, lang_id, length); + + uint8_t req_type = USB_REQ_TYPE_GET_REQUEST; + if (desc_type == USB_DT_HID_REPORT) + req_type = USB_REQ_TYPE_GET_INTERFACE_REQUEST; + + DECLARE_USB_PACKET(ctrl_in_packet, req_type, USB_REQ_GET_DESCRIPTOR, (desc_type << 8) | desc_index, lang_id, + length); count = xhci_control_in(id, &ctrl_in_packet, target, port_id, dev_desc->max_packet_size); if (unlikely(count == 0)) return -EAGAIN; @@ -1364,9 +1406,9 @@ static inline int xhci_set_configuration(const int id, const int port_id, const if (unlikely(dev_desc == NULL)) return -EINVAL; DECLARE_USB_PACKET(ctrl_out_packet, USB_REQ_TYPE_SET_REQUEST, USB_REQ_SET_CONFIGURATION, conf_value & 0xff, 0, 0); - kdebug("set conf: to control out"); + // kdebug("set conf: to control out"); count = xhci_control_out(id, &ctrl_out_packet, NULL, port_id, dev_desc->max_packet_size); - kdebug("set conf: count=%d", count); + // kdebug("set conf: count=%d", count); return 0; } @@ -1387,7 +1429,10 @@ static int xhci_get_config_desc(const int id, const int port_id, struct usb_conf int retval = xhci_get_desc(id, port_id, conf_desc, USB_DT_CONFIG, 0, 0, 9); if (unlikely(retval != 0)) return retval; - kdebug("port %d got conf ok. type=%d, len=%d, total_len=%d, num_interfaces=%d, max_power=%dmA", port_id, conf_desc->type, conf_desc->len, conf_desc->total_len, conf_desc->num_interfaces, (xhci_get_port_speed(id, port_id) == XHCI_PORT_SPEED_SUPER) ? (conf_desc->max_power * 8) : (conf_desc->max_power * 2)); + kdebug("port %d got conf ok. type=%d, len=%d, total_len=%d, num_interfaces=%d, max_power=%dmA", port_id, + conf_desc->type, conf_desc->len, conf_desc->total_len, conf_desc->num_interfaces, + (xhci_get_port_speed(id, port_id) == XHCI_PORT_SPEED_SUPER) ? (conf_desc->max_power * 8) + : (conf_desc->max_power * 2)); return 0; } @@ -1400,7 +1445,8 @@ static int xhci_get_config_desc(const int id, const int port_id, struct usb_conf * @param target 最终结果要拷贝到的地址 * @return int 错误码 */ -static inline int xhci_get_config_desc_full(const int id, const int port_id, const struct usb_config_desc *conf_desc, void *target) +static inline int xhci_get_config_desc_full(const int id, const int port_id, const struct usb_config_desc *conf_desc, + void *target) { if (unlikely(conf_desc == NULL || target == NULL)) return -EINVAL; @@ -1420,20 +1466,31 @@ static int xhci_get_interface_desc(const void *in_buf, const uint8_t if_num, str { if (unlikely(if_desc == NULL || in_buf == NULL)) return -EINVAL; - kdebug("to get interface."); // 判断接口index是否合理 if (if_num >= ((struct usb_config_desc *)in_buf)->num_interfaces) return -EINVAL; - struct usb_interface_desc *ptr = (struct usb_interface_desc *)(in_buf + sizeof(struct usb_config_desc)); - for (int i = 0; i < if_num; ++i) + uint32_t total_len = ((struct usb_config_desc *)in_buf)->total_len; + uint32_t pos = 0; + while (pos < total_len) { - ptr = (struct usb_interface_desc *)(((uint64_t)ptr) + sizeof(struct usb_interface_desc) + sizeof(struct usb_endpoint_desc) * ptr->num_endpoints); - } - // 返回结果 - *if_desc = ptr; + struct usb_interface_desc *ptr = (struct usb_interface_desc *)(in_buf + pos); + if (ptr->type != USB_DT_INTERFACE) + { + pos += ptr->len; + continue; + } - kdebug("get interface desc ok. interface_number=%d, num_endpoints=%d, class=%d, subclass=%d", ptr->interface_number, ptr->num_endpoints, ptr->interface_class, ptr->interface_sub_class); - return 0; + if (ptr->interface_number == if_num) // 找到目标interface desc + { + kdebug("get interface desc ok. interface_number=%d, num_endpoints=%d, class=%d, subclass=%d", + ptr->interface_number, ptr->num_endpoints, ptr->interface_class, ptr->interface_sub_class); + *if_desc = ptr; + return 0; + } + pos += ptr->len; + } + + return -EINVAL; } /** @@ -1444,14 +1501,16 @@ static int xhci_get_interface_desc(const void *in_buf, const uint8_t if_num, str * @param ep_desc 返回的指向端点描述符的指针 * @return int 错误码 */ -static inline int xhci_get_endpoint_desc(const struct usb_interface_desc *if_desc, const uint8_t ep_num, struct usb_endpoint_desc **ep_desc) +static inline int xhci_get_endpoint_desc(const struct usb_interface_desc *if_desc, const uint8_t ep_num, + struct usb_endpoint_desc **ep_desc) { if (unlikely(if_desc == NULL || ep_desc == NULL)) return -EINVAL; BUG_ON(ep_num >= if_desc->num_endpoints); *ep_desc = (struct usb_endpoint_desc *)((uint64_t)(if_desc + 1) + ep_num * sizeof(struct usb_endpoint_desc)); - kdebug("get endpoint desc: ep_addr=%d, max_packet=%d, attr=%#06x, interval=%d", (*ep_desc)->endpoint_addr, (*ep_desc)->max_packet, (*ep_desc)->attributes, (*ep_desc)->interval); + kdebug("get endpoint desc: ep_addr=%d, max_packet=%d, attr=%#06x, interval=%d", (*ep_desc)->endpoint_addr, + (*ep_desc)->max_packet, (*ep_desc)->attributes, (*ep_desc)->interval); return 0; } @@ -1552,11 +1611,11 @@ static int xhci_get_descriptor(const int id, const int port_id, struct usb_devic " product index: %i\n" " serial index: %i\n" " number of configs: %i\n", - port_id, dev_desc->len, dev_desc->type, dev_desc->usb_version >> 8, dev_desc->usb_version & 0xFF, dev_desc->_class, dev_desc->subclass, - dev_desc->protocol, dev_desc->max_packet_size, dev_desc->vendor_id, dev_desc->product_id, - (dev_desc->device_rel & 0xF000) >> 12, (dev_desc->device_rel & 0x0F00) >> 8, - (dev_desc->device_rel & 0x00F0) >> 4, (dev_desc->device_rel & 0x000F) >> 0, - dev_desc->manufacturer_index, dev_desc->procuct_index, dev_desc->serial_index, dev_desc->config); + port_id, dev_desc->len, dev_desc->type, dev_desc->usb_version >> 8, dev_desc->usb_version & 0xFF, + dev_desc->_class, dev_desc->subclass, dev_desc->protocol, dev_desc->max_packet_size, dev_desc->vendor_id, + dev_desc->product_id, (dev_desc->device_rel & 0xF000) >> 12, (dev_desc->device_rel & 0x0F00) >> 8, + (dev_desc->device_rel & 0x00F0) >> 4, (dev_desc->device_rel & 0x000F) >> 0, dev_desc->manufacturer_index, + dev_desc->procuct_index, dev_desc->serial_index, dev_desc->config); return 0; } @@ -1605,8 +1664,9 @@ static int xhci_hc_start_ports(int id) // kdebug("initializing usb2: %d", i); // reset该端口 // kdebug("to reset port %d, rflags=%#018lx", i, get_rflags()); - if (likely(xhci_reset_port(id, i) == 0)) // 如果端口reset成功,就获取它的描述符 - // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的 + if (likely(xhci_reset_port(id, i) == + 0)) // 如果端口reset成功,就获取它的描述符 + // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的 { // kdebug("reset port %d ok", id); @@ -1657,7 +1717,8 @@ static int xhci_hid_set_idle(const int id, const int port_id, struct usb_interfa * @param ep_desc 端点描述符 * @return int 错误码 */ -static int xhci_configure_endpoint(const int id, const int port_id, const uint8_t ep_num, const uint8_t ep_type, struct usb_endpoint_desc *ep_desc) +static int xhci_configure_endpoint(const int id, const int port_id, const uint8_t ep_num, const uint8_t ep_type, + struct usb_endpoint_desc *ep_desc) { int retval = 0; @@ -1672,7 +1733,7 @@ static int xhci_configure_endpoint(const int id, const int port_id, const uint8_ // 创建输入上下文缓冲区 uint64_t input_ctx_buffer = (uint64_t)kzalloc(xhci_hc[id].context_size * 33, 0); // 置位对应的add bit - __write4b(input_ctx_buffer + 4, (1 << ep_num)|1); + __write4b(input_ctx_buffer + 4, (1 << ep_num) | 1); __write4b(input_ctx_buffer + 0x1c, 1); // 拷贝slot上下文 @@ -1736,38 +1797,83 @@ static int xhci_configure_port(const int id, const int port_id) void *full_conf = NULL; struct usb_interface_desc *if_desc = NULL; struct usb_endpoint_desc *ep_desc = NULL; + int retval = 0; + // hint: 暂时只考虑对键盘的初始化 // 获取完整的config { struct usb_config_desc conf_desc = {0}; - xhci_get_config_desc(id, port_id, &conf_desc); + retval = xhci_get_config_desc(id, port_id, &conf_desc); + if (unlikely(retval != 0)) + return retval; + full_conf = kzalloc(conf_desc.total_len, 0); - xhci_get_config_desc_full(id, port_id, &conf_desc, full_conf); + if (unlikely(full_conf == NULL)) + return -ENOMEM; + + retval = xhci_get_config_desc_full(id, port_id, &conf_desc, full_conf); + if (unlikely(retval != 0)) + goto failed; } - xhci_get_interface_desc(full_conf, 0, &if_desc); + retval = xhci_get_interface_desc(full_conf, 0, &if_desc); + if (unlikely(retval != 0)) + goto failed; + if (if_desc->interface_class == USB_CLASS_HID) { // 由于暂时只支持键盘,因此把键盘的驱动也写在这里 // todo: 分离usb键盘驱动 - xhci_get_endpoint_desc(if_desc, 0, &ep_desc); - + retval = xhci_get_endpoint_desc(if_desc, 0, &ep_desc); + if (unlikely(retval != 0)) + goto failed; // kdebug("to set conf, val=%#010lx", ((struct usb_config_desc *)full_conf)->value); - xhci_set_configuration(id, port_id, ((struct usb_config_desc *)full_conf)->value); + retval = xhci_set_configuration(id, port_id, ((struct usb_config_desc *)full_conf)->value); + if (unlikely(retval != 0)) + goto failed; // kdebug("set conf ok"); - // todo: configure endpoint - xhci_configure_endpoint(id, port_id, ep_desc->endpoint_addr, USB_EP_INTERRUPT, ep_desc); - - xhci_hid_set_idle(id, port_id, if_desc); - - // 获取report desc - // todo: parse hid report + // configure endpoint + retval = xhci_configure_endpoint(id, port_id, ep_desc->endpoint_addr, USB_EP_INTERRUPT, ep_desc); + if (unlikely(retval != 0)) + goto failed; + retval = xhci_hid_set_idle(id, port_id, if_desc); + if (unlikely(retval != 0)) + goto failed; + + struct usb_hid_desc *hid_desc = NULL; + uint32_t hid_desc_len = 0; + // 获取hid desc + retval = xhci_get_hid_descriptor(id, port_id, full_conf, if_desc->interface_number, &hid_desc); + if (unlikely(retval != 0)) + goto failed; + + // 获取hid report + void *hid_report_data = kzalloc(hid_desc->report_desc_len, 0); + if (unlikely(hid_report_data == NULL)) + goto failed; + retval = + xhci_get_hid_report(id, port_id, if_desc->interface_number, hid_report_data, hid_desc->report_desc_len); + if (unlikely(retval != 0)) + { + kfree(hid_report_data); + goto failed; + } + + kdebug("to parse hid report"); + // todo: parse hid report + hid_parse_report(hid_report_data, hid_desc->report_desc_len); + kdebug("parse hid report done"); + kfree(hid_report_data); } + goto out; +failed:; + kerror("failed at xhci_configure_port, retval=%d", retval); +out:; kfree(full_conf); - return 0; + return retval; } /** * @brief 初始化xhci主机控制器的中断控制 @@ -1796,7 +1902,8 @@ static int xhci_hc_init_intr(int id) if (unlikely((int64_t)(retval) == -ENOMEM)) return -ENOMEM; xhci_hc[id].event_ring_table_vaddr = retval; - xhci_hc[id].current_event_ring_vaddr = xhci_hc[id].event_ring_vaddr; // 设置驱动程序要读取的下一个event ring trb的地址 + xhci_hc[id].current_event_ring_vaddr = + xhci_hc[id].event_ring_vaddr; // 设置驱动程序要读取的下一个event ring trb的地址 retval = 0; xhci_hc[id].current_event_ring_cycle = 1; @@ -1809,7 +1916,9 @@ static int xhci_hc_init_intr(int id) io_mfence(); xhci_write_intr_reg32(id, 0, XHCI_IR_TABLE_SIZE, 1); // 当前只有1个segment io_mfence(); - xhci_write_intr_reg64(id, 0, XHCI_IR_DEQUEUE, virt_2_phys(xhci_hc[id].current_event_ring_vaddr) | (1 << 3)); // 写入dequeue寄存器,并清除busy位(写1就会清除) + xhci_write_intr_reg64(id, 0, XHCI_IR_DEQUEUE, + virt_2_phys(xhci_hc[id].current_event_ring_vaddr) | + (1 << 3)); // 写入dequeue寄存器,并清除busy位(写1就会清除) io_mfence(); xhci_write_intr_reg64(id, 0, XHCI_IR_TABLE_ADDR, virt_2_phys(xhci_hc[id].event_ring_table_vaddr)); // 写入table地址 io_mfence(); @@ -1894,6 +2003,62 @@ static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring) return 0; } +/** + * @brief 获取接口的hid descriptor + * + * @param id 主机控制器号 + * @param port_id 端口号 + * @param full_conf 完整的cofig缓冲区 + * @param interface_number 接口号 + * @param ret_hid_desc 返回的指向hid描述符的指针 + * @return int 错误码 + */ +static int xhci_get_hid_descriptor(int id, int port_id, const void *full_conf, int interface_number, + struct usb_hid_desc **ret_hid_desc) +{ + if (unlikely(ret_hid_desc == NULL || full_conf == NULL)) + return -EINVAL; + kdebug("to get hid_descriptor."); + // 判断接口index是否合理 + if (interface_number >= ((struct usb_config_desc *)full_conf)->num_interfaces) + return -EINVAL; + uint32_t total_len = ((struct usb_config_desc *)full_conf)->total_len; + uint32_t pos = 0; + while (pos < total_len) + { + struct usb_hid_desc *ptr = (struct usb_hid_desc *)(full_conf + pos); + if (ptr->type != USB_DT_HID) + { + pos += ptr->len; + continue; + } + // 找到目标hid描述符 + *ret_hid_desc = ptr; + kdebug("Found hid descriptor for port:%d, if:%d, report_desc_len=%d", port_id, interface_number, + ptr->report_desc_len); + return 0; + } + + return -EINVAL; +} + +/** + * @brief 发送get_hid_descriptor请求,将hid + * + * @param id 主机控制器号 + * @param port_id 端口号 + * @param interface_number 接口号 + * @param ret_hid_report hid report要拷贝到的地址 + * @param hid_report_len hid report的长度 + * @return int 错误码 + */ +static int xhci_get_hid_report(int id, int port_id, int interface_number, void *ret_hid_report, uint32_t hid_report_len) +{ + int retval = xhci_get_desc(id, port_id, ret_hid_report, USB_DT_HID_REPORT, 0, interface_number, hid_report_len); + if (unlikely(retval != 0)) + kerror("xhci_get_hid_report failed: host_controller:%d, port:%d, interface %d", id, port_id, interface_number); + return retval; +} /** * @brief 初始化xhci控制器 * @@ -1909,7 +2074,10 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) } spin_lock(&xhci_controller_init_lock); - kinfo("Initializing xhci host controller: bus=%#02x, device=%#02x, func=%#02x, VendorID=%#04x, irq_line=%d, irq_pin=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, dev_hdr->header.Vendor_ID, dev_hdr->Interrupt_Line, dev_hdr->Interrupt_PIN); + kinfo("Initializing xhci host controller: bus=%#02x, device=%#02x, func=%#02x, VendorID=%#04x, irq_line=%d, " + "irq_pin=%d", + dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, dev_hdr->header.Vendor_ID, + dev_hdr->Interrupt_Line, dev_hdr->Interrupt_PIN); io_mfence(); int cid = xhci_hc_find_available_id(); if (cid < 0) @@ -1930,7 +2098,8 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) } io_mfence(); // 为当前控制器映射寄存器地址空间 - xhci_hc[cid].vbase = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + 65536 * xhci_hc[cid].controller_id; + xhci_hc[cid].vbase = + SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + 65536 * xhci_hc[cid].controller_id; // kdebug("dev_hdr->BAR0 & (~0xf)=%#018lx", dev_hdr->BAR0 & (~0xf)); mm_map_phys_addr(xhci_hc[cid].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true); io_mfence(); @@ -1975,7 +2144,8 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) } // if it is a Panther Point device, make sure sockets are xHCI controlled. if (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) & 0xffff) == 0x8086) && - (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) >> 16) & 0xffff) == 0x1E31) && + (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) >> 16) & 0xffff) == + 0x1E31) && ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 8) & 0xff) == 4)) { kdebug("Is a Panther Point device"); @@ -2082,6 +2252,7 @@ failed:; memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t)); failed_exceed_max:; - kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func); + kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device, + dev_hdr->header.func); spin_unlock(&xhci_controller_init_lock); } \ No newline at end of file From af37e98979a1b162f82df7b5db8e4c6cda9bf4b2 Mon Sep 17 00:00:00 2001 From: DaJiYuQia <88259094+DaJiYuQia@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:50:47 +0800 Subject: [PATCH 03/11] Patch in kfifo add lock (#60) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 对加锁进行了修改 * bugfix: 解决指针错误的问题 Co-authored-by: longjin --- kernel/common/kfifo.h | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/kernel/common/kfifo.h b/kernel/common/kfifo.h index 63a7b566..1c9c7778 100644 --- a/kernel/common/kfifo.h +++ b/kernel/common/kfifo.h @@ -1,6 +1,7 @@ #pragma once #include +#include struct kfifo_t { @@ -73,10 +74,10 @@ int kfifo_alloc(struct kfifo_t *fifo, uint32_t size, uint64_t reserved); /** * @brief 释放通过kfifo_alloc创建的fifo缓冲区 - * + * * @param fifo fifo队列结构体 */ -void kfifo_free_alloc(struct kfifo_t* fifo); +void kfifo_free_alloc(struct kfifo_t *fifo); /** * @brief 使用指定的缓冲区来初始化kfifo缓冲队列 @@ -116,3 +117,37 @@ uint32_t kfifo_out(struct kfifo_t *fifo, void *to, uint32_t size); * @return uint32_t 取出的数据大小 */ uint32_t kfifo_out_peek(struct kfifo_t *fifo, void *to, uint32_t size); + +/** + * @brief 向kfifo缓冲区推入指定大小的数据并在过程加锁 + * + * @param fifo 队列结构体 + * @param from 来源数据地址 + * @param size 数据大小(字节数) + * @param lock 自旋锁 + * @return uint32_t 推入的数据大小 + */ +uint32_t __always_inline kfifo_in_lockd(struct kfifo_t *fifo, const void *from, uint32_t size, spinlock_t *lock) +{ + spin_lock(lock); + uint32_t retval = kfifo_in(&fifo, &from, size); + spin_unlock(lock); + return retval; +} + +/** + * @brief 从kfifo缓冲区取出数据,并从队列中删除数据,并在过程加锁 + * + * @param fifo 队列结构体 + * @param to 拷贝目标地址 + * @param size 数据大小(字节数) + * @param lock 自旋锁 + * @return uint32_t 取出的数据大小 + */ +uint32_t __always_inline kfifo_out_lockd(struct kfifo_t *fifo, void *to, uint32_t size, spinlock_t *lock) +{ + spin_lock(lock); + uint32_t retval = kfifo_out(&fifo, &to, size); + spin_unlock(lock); + return retval; +} From fbe1e23e97bf380ed187da88cba1ed075c5e435f Mon Sep 17 00:00:00 2001 From: longjin Date: Sun, 16 Oct 2022 11:08:32 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E5=B0=86makefile=E4=B8=AD=E7=9A=84gcc?= =?UTF-8?q?=E5=AD=97=E6=A0=B7=E7=94=A8$(CC)=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E4=BB=A3=E6=9B=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 1 + kernel/Makefile | 4 ++-- kernel/arch/x86_64/Makefile | 4 ++-- kernel/common/math/Makefile | 6 +++--- kernel/debug/Makefile | 6 +++--- kernel/driver/acpi/Makefile | 2 +- kernel/driver/disk/Makefile | 4 ++-- kernel/driver/hid/Makefile | 2 +- kernel/driver/hid/usbhid/Makefile | 2 +- kernel/driver/interrupt/Makefile | 6 +++--- kernel/driver/keyboard/Makefile | 2 +- kernel/driver/mouse/Makefile | 2 +- kernel/driver/multiboot2/Makefile | 2 +- kernel/driver/pci/Makefile | 4 ++-- kernel/driver/timers/Makefile | 4 ++-- kernel/driver/tty/Makefile | 2 +- kernel/driver/uart/Makefile | 2 +- kernel/driver/usb/Makefile | 4 ++-- kernel/driver/video/Makefile | 2 +- kernel/exception/Makefile | 8 ++++---- kernel/filesystem/Makefile | 2 +- kernel/filesystem/VFS/Makefile | 2 +- kernel/filesystem/devfs/Makefile | 2 +- kernel/filesystem/fat32/Makefile | 2 +- kernel/filesystem/rootfs/Makefile | 2 +- kernel/ipc/Makefile | 2 +- kernel/ktest/Makefile | 10 +++++----- kernel/lib/Makefile | 2 +- kernel/lib/libELF/Makefile | 2 +- kernel/lib/libUI/Makefile | 6 +++--- kernel/lib/sys/Makefile | 2 +- kernel/mm/Makefile | 16 ++++++++-------- kernel/process/Makefile | 4 ++-- kernel/sched/Makefile | 2 +- kernel/smp/Makefile | 4 ++-- kernel/syscall/Makefile | 2 +- kernel/time/Makefile | 4 ++-- user/apps/about/Makefile | 2 +- user/apps/shell/Makefile | 8 ++++---- user/libs/libKeyboard/Makefile | 2 +- user/libs/libc/Makefile | 20 ++++++++++---------- user/libs/libc/math/Makefile | 6 +++--- user/libs/libc/sys/Makefile | 4 ++-- user/libs/libc/sysdeps/x86_64/Makefile | 2 +- user/libs/libsystem/Makefile | 2 +- 45 files changed, 91 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index b6a81230..b354df1c 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ ifeq ($(DEBUG), DEBUG) GLOBAL_CFLAGS += -g endif +export CC=gcc .PHONY: all all: kernel user diff --git a/kernel/Makefile b/kernel/Makefile index a9db8fc3..afc8a33f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -22,14 +22,14 @@ kernel_subdirs := common driver process debug filesystem time arch exception mm head.o: head.S - gcc -E head.S > _head.s # 预处理 + $(CC) -E head.S > _head.s # 预处理 as $(ASFLAGS) -o head.o _head.s main.o: main.c # -fno-builtin: 不使用C语言内建函数 # The -m64 option sets int to 32bits and long and pointer to 64 bits and generates code for AMD’s x86-64 architecture. - gcc $(CFLAGS) -c main.c -o main.o + $(CC) $(CFLAGS) -c main.c -o main.o all: kernel diff --git a/kernel/arch/x86_64/Makefile b/kernel/arch/x86_64/Makefile index 0234eef0..097231ed 100644 --- a/kernel/arch/x86_64/Makefile +++ b/kernel/arch/x86_64/Makefile @@ -3,8 +3,8 @@ CFLAGS += -I . all: x86_64_ipi.o ia64_msi.o x86_64_ipi.o: x86_64_ipi.c - gcc $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o + $(CC) $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o ia64_msi.o: ia64_msi.c - gcc $(CFLAGS) -c ia64_msi.c -o ia64_msi.o + $(CC) $(CFLAGS) -c ia64_msi.c -o ia64_msi.o diff --git a/kernel/common/math/Makefile b/kernel/common/math/Makefile index 996d4fed..c70df022 100644 --- a/kernel/common/math/Makefile +++ b/kernel/common/math/Makefile @@ -5,10 +5,10 @@ CFLAGS += -I . all: fabs.o round.o pow.o fabs.o: fabs.c - gcc $(CFLAGS) -c fabs.c -o fabs.o + $(CC) $(CFLAGS) -c fabs.c -o fabs.o round.o: round.c - gcc $(CFLAGS) -c round.c -o round.o + $(CC) $(CFLAGS) -c round.c -o round.o pow.o: pow.c - gcc $(CFLAGS) -c pow.c -o pow.o \ No newline at end of file + $(CC) $(CFLAGS) -c pow.c -o pow.o \ No newline at end of file diff --git a/kernel/debug/Makefile b/kernel/debug/Makefile index 281c5633..7329f5c4 100644 --- a/kernel/debug/Makefile +++ b/kernel/debug/Makefile @@ -4,11 +4,11 @@ all: traceback.o CFLAGS += -I . kallsyms.o: kallsyms.c - gcc -o kallsyms kallsyms.c + $(CC) -o kallsyms kallsyms.c rm -rf kallsyms.o traceback.o: traceback/traceback.c - gcc $(CFLAGS) -c traceback/traceback.c -o traceback/traceback.o + $(CC) $(CFLAGS) -c traceback/traceback.c -o traceback/traceback.o # 生成内核栈符号表的汇编文件 @@ -16,7 +16,7 @@ generate_kallsyms: kallsyms.o echo "Generating kallsyms..." nm -n $(kernel_root_path)/kernel | ./kallsyms > kallsyms.S - gcc -c kallsyms.S -o kallsyms.o + $(CC) -c kallsyms.S -o kallsyms.o @echo "Kallsyms generated." diff --git a/kernel/driver/acpi/Makefile b/kernel/driver/acpi/Makefile index 8679a6fb..4fed3167 100644 --- a/kernel/driver/acpi/Makefile +++ b/kernel/driver/acpi/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . acpi.o: acpi.c - gcc $(CFLAGS) -c acpi.c -o acpi.o + $(CC) $(CFLAGS) -c acpi.c -o acpi.o diff --git a/kernel/driver/disk/Makefile b/kernel/driver/disk/Makefile index 44a63927..960b6131 100644 --- a/kernel/driver/disk/Makefile +++ b/kernel/driver/disk/Makefile @@ -4,7 +4,7 @@ all: ata.o ahci.o CFLAGS += -I . ata.o: ata.c - gcc $(CFLAGS) -c ata.c -o ata.o + $(CC) $(CFLAGS) -c ata.c -o ata.o ahci.o: ahci/ahci.c - gcc $(CFLAGS) -c ahci/ahci.c -o ahci/ahci.o \ No newline at end of file + $(CC) $(CFLAGS) -c ahci/ahci.c -o ahci/ahci.o \ No newline at end of file diff --git a/kernel/driver/hid/Makefile b/kernel/driver/hid/Makefile index 63f6e33f..72f3f42e 100644 --- a/kernel/driver/hid/Makefile +++ b/kernel/driver/hid/Makefile @@ -12,7 +12,7 @@ $(kernel_driver_hid_subdirs): ECHO $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" $(kernel_driver_hid_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_driver_hid_objs) $(kernel_driver_hid_subdirs) @echo $(kernel_driver_hid_objs) diff --git a/kernel/driver/hid/usbhid/Makefile b/kernel/driver/hid/usbhid/Makefile index 39103944..2b50bbac 100644 --- a/kernel/driver/hid/usbhid/Makefile +++ b/kernel/driver/hid/usbhid/Makefile @@ -8,7 +8,7 @@ ECHO: @echo "$@" $(kernel_driver_usbhid_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_driver_hid_objs) $(kernel_driver_hid_subdirs) @echo $(kernel_driver_hid_objs) diff --git a/kernel/driver/interrupt/Makefile b/kernel/driver/interrupt/Makefile index 4d02de52..e886b99a 100644 --- a/kernel/driver/interrupt/Makefile +++ b/kernel/driver/interrupt/Makefile @@ -4,11 +4,11 @@ all: pic.o # 中断处理芯片的驱动程序 ifeq ($(PIC), _INTR_8259A_) pic.o: 8259A/8259A.c - gcc $(CFLAGS) -c 8259A/8259A.c -o pic.o + $(CC) $(CFLAGS) -c 8259A/8259A.c -o pic.o else pic.o: apic/apic.c apic_timer.o - gcc $(CFLAGS) -c apic/apic.c -o pic.o + $(CC) $(CFLAGS) -c apic/apic.c -o pic.o apic_timer.o: apic/apic_timer.c - gcc $(CFLAGS) -c apic/apic_timer.c -o apic/apic_timer.o + $(CC) $(CFLAGS) -c apic/apic_timer.c -o apic/apic_timer.o endif \ No newline at end of file diff --git a/kernel/driver/keyboard/Makefile b/kernel/driver/keyboard/Makefile index 245b69e9..517494b4 100644 --- a/kernel/driver/keyboard/Makefile +++ b/kernel/driver/keyboard/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . ps2_keyboard.o: ps2_keyboard.c - gcc $(CFLAGS) -c ps2_keyboard.c -o ps2_keyboard.o \ No newline at end of file + $(CC) $(CFLAGS) -c ps2_keyboard.c -o ps2_keyboard.o \ No newline at end of file diff --git a/kernel/driver/mouse/Makefile b/kernel/driver/mouse/Makefile index 93e1a00e..192de29e 100644 --- a/kernel/driver/mouse/Makefile +++ b/kernel/driver/mouse/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . ps2_mouse.o: ps2_mouse.c - gcc $(CFLAGS) -c ps2_mouse.c -o ps2_mouse.o \ No newline at end of file + $(CC) $(CFLAGS) -c ps2_mouse.c -o ps2_mouse.o \ No newline at end of file diff --git a/kernel/driver/multiboot2/Makefile b/kernel/driver/multiboot2/Makefile index ebe0652d..0e352497 100644 --- a/kernel/driver/multiboot2/Makefile +++ b/kernel/driver/multiboot2/Makefile @@ -4,4 +4,4 @@ all: multiboot2.o CFLAGS += -I . multiboot2.o: multiboot2.c - gcc $(CFLAGS) -c multiboot2.c -o multiboot2.o \ No newline at end of file + $(CC) $(CFLAGS) -c multiboot2.c -o multiboot2.o \ No newline at end of file diff --git a/kernel/driver/pci/Makefile b/kernel/driver/pci/Makefile index b96890c5..55f6c1b9 100644 --- a/kernel/driver/pci/Makefile +++ b/kernel/driver/pci/Makefile @@ -5,7 +5,7 @@ CFLAGS += -I . pci.o: pci.c - gcc $(CFLAGS) -c pci.c -o pci.o + $(CC) $(CFLAGS) -c pci.c -o pci.o msi.o: msi.c - gcc $(CFLAGS) -c msi.c -o msi.o + $(CC) $(CFLAGS) -c msi.c -o msi.o diff --git a/kernel/driver/timers/Makefile b/kernel/driver/timers/Makefile index 42ca1932..21650ea8 100644 --- a/kernel/driver/timers/Makefile +++ b/kernel/driver/timers/Makefile @@ -4,7 +4,7 @@ all: rtc.o HPET.o CFLAGS += -I . rtc.o: rtc/rtc.c - gcc $(CFLAGS) -c rtc/rtc.c -o rtc/rtc.o + $(CC) $(CFLAGS) -c rtc/rtc.c -o rtc/rtc.o HPET.o: HPET/HPET.c - gcc $(CFLAGS) -c HPET/HPET.c -o HPET/HPET.o + $(CC) $(CFLAGS) -c HPET/HPET.c -o HPET/HPET.o diff --git a/kernel/driver/tty/Makefile b/kernel/driver/tty/Makefile index e7a913c7..5af16979 100644 --- a/kernel/driver/tty/Makefile +++ b/kernel/driver/tty/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . tty.o: tty.c - gcc $(CFLAGS) -c tty.c -o tty.o \ No newline at end of file + $(CC) $(CFLAGS) -c tty.c -o tty.o \ No newline at end of file diff --git a/kernel/driver/uart/Makefile b/kernel/driver/uart/Makefile index 9f8ea0dd..9f068e5f 100644 --- a/kernel/driver/uart/Makefile +++ b/kernel/driver/uart/Makefile @@ -4,4 +4,4 @@ all: uart.o CFLAGS += -I . uart.o: uart.c - gcc $(CFLAGS) -c uart.c -o uart.o + $(CC) $(CFLAGS) -c uart.c -o uart.o diff --git a/kernel/driver/usb/Makefile b/kernel/driver/usb/Makefile index aab3468b..27beeef0 100644 --- a/kernel/driver/usb/Makefile +++ b/kernel/driver/usb/Makefile @@ -3,7 +3,7 @@ CFLAGS += -I . all: usb.o xhci.o usb.o: usb.c - gcc $(CFLAGS) -c usb.c -o usb.o + $(CC) $(CFLAGS) -c usb.c -o usb.o xhci.o: xhci/xhci.c - gcc $(CFLAGS) -c xhci/xhci.c -o xhci/xhci.o \ No newline at end of file + $(CC) $(CFLAGS) -c xhci/xhci.c -o xhci/xhci.o \ No newline at end of file diff --git a/kernel/driver/video/Makefile b/kernel/driver/video/Makefile index 57713fe4..eb0fafb1 100644 --- a/kernel/driver/video/Makefile +++ b/kernel/driver/video/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . video.o: video.c - gcc $(CFLAGS) -c video.c -o video.o + $(CC) $(CFLAGS) -c video.c -o video.o diff --git a/kernel/exception/Makefile b/kernel/exception/Makefile index e3e0f72b..4539f068 100644 --- a/kernel/exception/Makefile +++ b/kernel/exception/Makefile @@ -5,14 +5,14 @@ CFLAGS += -I . all: entry.o irq.o softirq.o trap.o entry.o: entry.S - gcc -E entry.S > _entry.s + $(CC) -E entry.S > _entry.s as $(ASFLAGS) -o entry.o _entry.s trap.o: trap.c - gcc $(CFLAGS) -c trap.c -o trap.o + $(CC) $(CFLAGS) -c trap.c -o trap.o softirq.o: softirq.c - gcc $(CFLAGS) -c softirq.c -o softirq.o + $(CC) $(CFLAGS) -c softirq.c -o softirq.o irq.o: irq.c - gcc $(CFLAGS) -c irq.c -o irq.o \ No newline at end of file + $(CC) $(CFLAGS) -c irq.c -o irq.o \ No newline at end of file diff --git a/kernel/filesystem/Makefile b/kernel/filesystem/Makefile index 06a538f8..4f50c9f3 100644 --- a/kernel/filesystem/Makefile +++ b/kernel/filesystem/Makefile @@ -10,7 +10,7 @@ ECHO: $(kernel_fs_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o $(kernel_fs_subdirs): ECHO $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" diff --git a/kernel/filesystem/VFS/Makefile b/kernel/filesystem/VFS/Makefile index 5b016cf9..ff78a304 100644 --- a/kernel/filesystem/VFS/Makefile +++ b/kernel/filesystem/VFS/Makefile @@ -10,7 +10,7 @@ ECHO: $(kernel_fs_vfs_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_fs_vfs_objs) diff --git a/kernel/filesystem/devfs/Makefile b/kernel/filesystem/devfs/Makefile index 75a79c41..ac658731 100644 --- a/kernel/filesystem/devfs/Makefile +++ b/kernel/filesystem/devfs/Makefile @@ -10,7 +10,7 @@ ECHO: $(kernel_fs_devfs_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_fs_devfs_objs) diff --git a/kernel/filesystem/fat32/Makefile b/kernel/filesystem/fat32/Makefile index d4926865..721720d2 100644 --- a/kernel/filesystem/fat32/Makefile +++ b/kernel/filesystem/fat32/Makefile @@ -10,7 +10,7 @@ ECHO: $(kernel_fs_fat32_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_fs_fat32_objs) diff --git a/kernel/filesystem/rootfs/Makefile b/kernel/filesystem/rootfs/Makefile index c8cbe2e2..2228ba3a 100644 --- a/kernel/filesystem/rootfs/Makefile +++ b/kernel/filesystem/rootfs/Makefile @@ -10,7 +10,7 @@ ECHO: $(kernel_fs_rootfs_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_fs_rootfs_objs) diff --git a/kernel/ipc/Makefile b/kernel/ipc/Makefile index 7ee40efa..2be17c47 100644 --- a/kernel/ipc/Makefile +++ b/kernel/ipc/Makefile @@ -4,7 +4,7 @@ all: pipe.o CFLAGS += -I . pipe.o: pipe.c - gcc $(CFLAGS) -c pipe.c -o pipe.o + $(CC) $(CFLAGS) -c pipe.c -o pipe.o clean: echo "Done." \ No newline at end of file diff --git a/kernel/ktest/Makefile b/kernel/ktest/Makefile index 2509f0ce..4c47f8ce 100644 --- a/kernel/ktest/Makefile +++ b/kernel/ktest/Makefile @@ -5,16 +5,16 @@ CFLAGS += -I . all: ktest.o bitree.o kfifo.o mutex.o idr.o ktest.o: ktest.c - gcc $(CFLAGS) -c ktest.c -o ktest.o + $(CC) $(CFLAGS) -c ktest.c -o ktest.o bitree.o: test-bitree.c - gcc $(CFLAGS) -c test-bitree.c -o test-bitree.o + $(CC) $(CFLAGS) -c test-bitree.c -o test-bitree.o kfifo.o: test-kfifo.c - gcc $(CFLAGS) -c test-kfifo.c -o test-kfifo.o + $(CC) $(CFLAGS) -c test-kfifo.c -o test-kfifo.o mutex.o: test-mutex.c - gcc $(CFLAGS) -c test-mutex.c -o test-mutex.o + $(CC) $(CFLAGS) -c test-mutex.c -o test-mutex.o idr.o: test-idr.c - gcc $(CFLAGS) -c test-idr.c -o test-idr.o \ No newline at end of file + $(CC) $(CFLAGS) -c test-idr.c -o test-idr.o \ No newline at end of file diff --git a/kernel/lib/Makefile b/kernel/lib/Makefile index 58ff5c35..8a0b85bc 100644 --- a/kernel/lib/Makefile +++ b/kernel/lib/Makefile @@ -12,7 +12,7 @@ $(kernel_lib_subdirs): ECHO $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" $(kernel_lib_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_lib_objs) $(kernel_lib_subdirs) @echo $(kernel_lib_objs) diff --git a/kernel/lib/libELF/Makefile b/kernel/lib/libELF/Makefile index 6e228b8a..15952aff 100644 --- a/kernel/lib/libELF/Makefile +++ b/kernel/lib/libELF/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . elf.o: elf.c - gcc $(CFLAGS) -c elf.c -o elf.o + $(CC) $(CFLAGS) -c elf.c -o elf.o diff --git a/kernel/lib/libUI/Makefile b/kernel/lib/libUI/Makefile index 1ad8edec..209e0562 100644 --- a/kernel/lib/libUI/Makefile +++ b/kernel/lib/libUI/Makefile @@ -4,10 +4,10 @@ all: screen_manager.o textui.o textui-render.o CFLAGS += -I . screen_manager.o: screen_manager.c - gcc $(CFLAGS) -c screen_manager.c -o screen_manager.o + $(CC) $(CFLAGS) -c screen_manager.c -o screen_manager.o textui.o: textui.c - gcc $(CFLAGS) -c textui.c -o textui.o + $(CC) $(CFLAGS) -c textui.c -o textui.o textui-render.o: textui-render.c - gcc $(CFLAGS) -c textui-render.c -o textui-render.o + $(CC) $(CFLAGS) -c textui-render.c -o textui-render.o diff --git a/kernel/lib/sys/Makefile b/kernel/lib/sys/Makefile index 2891405e..bf90c8ea 100644 --- a/kernel/lib/sys/Makefile +++ b/kernel/lib/sys/Makefile @@ -7,7 +7,7 @@ ECHO: @echo "$@" $(kernel_lib_sys_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o all: $(kernel_lib_sys_objs) @echo $(kernel_lib_sys_objs) diff --git a/kernel/mm/Makefile b/kernel/mm/Makefile index 2761d842..ea4a9d33 100644 --- a/kernel/mm/Makefile +++ b/kernel/mm/Makefile @@ -5,25 +5,25 @@ CFLAGS += -I . all:mm.o slab.o mm-stat.o vma.o mmap.o utils.o mmio.o mmio-buddy.o mm.o: mm.c - gcc $(CFLAGS) -c mm.c -o mm.o + $(CC) $(CFLAGS) -c mm.c -o mm.o slab.o: slab.c - gcc $(CFLAGS) -c slab.c -o slab.o + $(CC) $(CFLAGS) -c slab.c -o slab.o mm-stat.o: mm-stat.c - gcc $(CFLAGS) -c mm-stat.c -o mm-stat.o + $(CC) $(CFLAGS) -c mm-stat.c -o mm-stat.o vma.o: vma.c - gcc $(CFLAGS) -c vma.c -o vma.o + $(CC) $(CFLAGS) -c vma.c -o vma.o mmap.o: mmap.c - gcc $(CFLAGS) -c mmap.c -o mmap.o + $(CC) $(CFLAGS) -c mmap.c -o mmap.o utils.o: utils.c - gcc $(CFLAGS) -c utils.c -o utils.o + $(CC) $(CFLAGS) -c utils.c -o utils.o mmio.o: mmio.c - gcc $(CFLAGS) -c mmio.c -o mmio.o + $(CC) $(CFLAGS) -c mmio.c -o mmio.o mmio-buddy.o: mmio-buddy.c - gcc $(CFLAGS) -c mmio-buddy.c -o mmio-buddy.o \ No newline at end of file + $(CC) $(CFLAGS) -c mmio-buddy.c -o mmio-buddy.o \ No newline at end of file diff --git a/kernel/process/Makefile b/kernel/process/Makefile index 87172b3c..cbfeefb3 100644 --- a/kernel/process/Makefile +++ b/kernel/process/Makefile @@ -9,10 +9,10 @@ ECHO: $(kernel_process_objs): ECHO - gcc $(CFLAGS) -c $@ -o $@.o + $(CC) $(CFLAGS) -c $@ -o $@.o procs.o: proc.S - gcc -E proc.S > _proc.s + $(CC) -E proc.S > _proc.s as $(ASFLAGS) -o procs.o _proc.s all: procs.o $(kernel_process_objs) diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile index 54099cbc..c22a6e24 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . all: sched.o sched.o: sched.c - gcc $(CFLAGS) -c sched.c -o sched.o + $(CC) $(CFLAGS) -c sched.c -o sched.o diff --git a/kernel/smp/Makefile b/kernel/smp/Makefile index 7f7ab081..ab9c7b33 100644 --- a/kernel/smp/Makefile +++ b/kernel/smp/Makefile @@ -6,8 +6,8 @@ all: apu_boot.o smp.o apu_boot.o: apu_boot.S - gcc -E apu_boot.S > _apu_boot.s # 预处理 + $(CC) -E apu_boot.S > _apu_boot.s # 预处理 as $(ASFLAGS) -o apu_boot.o _apu_boot.s smp.o: smp.c - gcc $(CFLAGS) -c smp.c -o smp.o \ No newline at end of file + $(CC) $(CFLAGS) -c smp.c -o smp.o \ No newline at end of file diff --git a/kernel/syscall/Makefile b/kernel/syscall/Makefile index e82c325d..477a787a 100644 --- a/kernel/syscall/Makefile +++ b/kernel/syscall/Makefile @@ -5,4 +5,4 @@ CFLAGS += -I . all: syscall.o syscall.o: syscall.c - gcc $(CFLAGS) -c syscall.c -o syscall.o + $(CC) $(CFLAGS) -c syscall.c -o syscall.o diff --git a/kernel/time/Makefile b/kernel/time/Makefile index ffb594a8..9948a9a6 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile @@ -4,10 +4,10 @@ all: timer.o sleep.o CFLAGS += -I . timer.o: timer.c - gcc $(CFLAGS) -c timer.c -o timer.o + $(CC) $(CFLAGS) -c timer.c -o timer.o sleep.o: sleep.c - gcc $(CFLAGS) -c sleep.c -o sleep.o + $(CC) $(CFLAGS) -c sleep.c -o sleep.o clean: echo "Done." \ No newline at end of file diff --git a/user/apps/about/Makefile b/user/apps/about/Makefile index 8a3326cd..b34ed553 100644 --- a/user/apps/about/Makefile +++ b/user/apps/about/Makefile @@ -4,4 +4,4 @@ all: about.o objcopy -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/about $(output_dir)/about.elf about.o: about.c - gcc $(CFLAGS) -c about.c -o about.o + $(CC) $(CFLAGS) -c about.c -o about.o diff --git a/user/apps/shell/Makefile b/user/apps/shell/Makefile index 66125fd8..3a33eb30 100644 --- a/user/apps/shell/Makefile +++ b/user/apps/shell/Makefile @@ -4,13 +4,13 @@ all: shell.o cmd.o cmd_help.o cmd_test.o objcopy -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/shell $(output_dir)/shell.elf shell.o: shell.c - gcc $(CFLAGS) -c shell.c -o shell.o + $(CC) $(CFLAGS) -c shell.c -o shell.o cmd.o: cmd.c - gcc $(CFLAGS) -c cmd.c -o cmd.o + $(CC) $(CFLAGS) -c cmd.c -o cmd.o cmd_test.o: cmd_test.c - gcc $(CFLAGS) -c cmd_test.c -o cmd_test.o + $(CC) $(CFLAGS) -c cmd_test.c -o cmd_test.o cmd_help.o: cmd_help.c - gcc $(CFLAGS) -c cmd_help.c -o cmd_help.o + $(CC) $(CFLAGS) -c cmd_help.c -o cmd_help.o diff --git a/user/libs/libKeyboard/Makefile b/user/libs/libKeyboard/Makefile index 59d35c64..bb34dc7b 100644 --- a/user/libs/libKeyboard/Makefile +++ b/user/libs/libKeyboard/Makefile @@ -4,4 +4,4 @@ CFLAGS += -I . keyboard.o: keyboard.c - gcc $(CFLAGS) -c keyboard.c -o keyboard.o \ No newline at end of file + $(CC) $(CFLAGS) -c keyboard.c -o keyboard.o \ No newline at end of file diff --git a/user/libs/libc/Makefile b/user/libs/libc/Makefile index 00b7e797..60d6e1d6 100644 --- a/user/libs/libc/Makefile +++ b/user/libs/libc/Makefile @@ -18,31 +18,31 @@ libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o diren done unistd.o: unistd.c - gcc $(CFLAGS) -c unistd.c -o unistd.o + $(CC) $(CFLAGS) -c unistd.c -o unistd.o fcntl.o: fcntl.c - gcc $(CFLAGS) -c fcntl.c -o fcntl.o + $(CC) $(CFLAGS) -c fcntl.c -o fcntl.o malloc.o: malloc.c - gcc $(CFLAGS) -c malloc.c -o malloc.o + $(CC) $(CFLAGS) -c malloc.c -o malloc.o errno.o: errno.c - gcc $(CFLAGS) -c errno.c -o errno.o + $(CC) $(CFLAGS) -c errno.c -o errno.o printf.o: printf.c - gcc $(CFLAGS) -c printf.c -o printf.o + $(CC) $(CFLAGS) -c printf.c -o printf.o stdlib.o: stdlib.c - gcc $(CFLAGS) -c stdlib.c -o stdlib.o + $(CC) $(CFLAGS) -c stdlib.c -o stdlib.o ctype.o: ctype.c - gcc $(CFLAGS) -c ctype.c -o ctype.o + $(CC) $(CFLAGS) -c ctype.c -o ctype.o string.o: string.c - gcc $(CFLAGS) -c string.c -o string.o + $(CC) $(CFLAGS) -c string.c -o string.o dirent.o: dirent.c - gcc $(CFLAGS) -c dirent.c -o dirent.o + $(CC) $(CFLAGS) -c dirent.c -o dirent.o time.o: time.c - gcc $(CFLAGS) -c time.c -o time.o \ No newline at end of file + $(CC) $(CFLAGS) -c time.c -o time.o \ No newline at end of file diff --git a/user/libs/libc/math/Makefile b/user/libs/libc/math/Makefile index 996d4fed..c70df022 100644 --- a/user/libs/libc/math/Makefile +++ b/user/libs/libc/math/Makefile @@ -5,10 +5,10 @@ CFLAGS += -I . all: fabs.o round.o pow.o fabs.o: fabs.c - gcc $(CFLAGS) -c fabs.c -o fabs.o + $(CC) $(CFLAGS) -c fabs.c -o fabs.o round.o: round.c - gcc $(CFLAGS) -c round.c -o round.o + $(CC) $(CFLAGS) -c round.c -o round.o pow.o: pow.c - gcc $(CFLAGS) -c pow.c -o pow.o \ No newline at end of file + $(CC) $(CFLAGS) -c pow.c -o pow.o \ No newline at end of file diff --git a/user/libs/libc/sys/Makefile b/user/libs/libc/sys/Makefile index 39b79634..97b44b8b 100644 --- a/user/libs/libc/sys/Makefile +++ b/user/libs/libc/sys/Makefile @@ -5,7 +5,7 @@ CFLAGS += -I . wait.o: wait.c - gcc $(CFLAGS) -c wait.c -o wait.o + $(CC) $(CFLAGS) -c wait.c -o wait.o stat.o: stat.c - gcc $(CFLAGS) -c stat.c -o stat.o \ No newline at end of file + $(CC) $(CFLAGS) -c stat.c -o stat.o \ No newline at end of file diff --git a/user/libs/libc/sysdeps/x86_64/Makefile b/user/libs/libc/sysdeps/x86_64/Makefile index a66a3ef6..5519b2f8 100644 --- a/user/libs/libc/sysdeps/x86_64/Makefile +++ b/user/libs/libc/sysdeps/x86_64/Makefile @@ -4,7 +4,7 @@ all: start.o ifeq ($(ARCH), __x86_64__) start.o: - gcc $(CFLAGS) -c elf/start.c -o elf/start.o + $(CC) $(CFLAGS) -c elf/start.c -o elf/start.o endif clean: diff --git a/user/libs/libsystem/Makefile b/user/libs/libsystem/Makefile index f360387d..f708200d 100644 --- a/user/libs/libsystem/Makefile +++ b/user/libs/libsystem/Makefile @@ -5,4 +5,4 @@ all: libsystem libsystem: syscall.o syscall.o: syscall.c - gcc $(CFLAGS) -c syscall.c -o syscall.o + $(CC) $(CFLAGS) -c syscall.c -o syscall.o From 4830d04c2f167faf81ea8db9b3baa784766b5a55 Mon Sep 17 00:00:00 2001 From: longjin Date: Sun, 16 Oct 2022 18:19:05 +0800 Subject: [PATCH 05/11] =?UTF-8?q?bugfix:=20=E8=A7=A3=E5=86=B3=E4=BA=86igno?= =?UTF-8?q?re=5Fint=E5=9C=A8=E8=BF=90=E8=A1=8C=E6=97=B6=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=A0=B4=E5=9D=8F=E8=BF=9B=E7=A8=8B=E6=89=A7=E8=A1=8C=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/driver/interrupt/apic/apic.c | 3 +- kernel/driver/interrupt/apic/apic.h | 2 +- kernel/exception/entry.S | 7 ++ kernel/exception/irq.c | 150 ++++++++++++---------------- kernel/head.S | 4 +- kernel/main.c | 6 -- 6 files changed, 76 insertions(+), 96 deletions(-) diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index 806fbd72..63c5cd61 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -344,7 +344,7 @@ void apic_local_apic_init() * @brief 初始化apic控制器 * */ -void apic_init() +int apic_init() { // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉 for (int i = 32; i <= 55; ++i) @@ -386,6 +386,7 @@ void apic_init() kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys); } sti(); + return 0; } /** * @brief 中断服务程序 diff --git a/kernel/driver/interrupt/apic/apic.h b/kernel/driver/interrupt/apic/apic.h index 5d64b105..3a001ce0 100644 --- a/kernel/driver/interrupt/apic/apic.h +++ b/kernel/driver/interrupt/apic/apic.h @@ -290,7 +290,7 @@ void apic_init_ap_core_local_apic(); * @brief 初始化apic控制器 * */ -void apic_init(); +int apic_init(); /** * @brief 读取指定类型的 Interrupt Control Structure diff --git a/kernel/exception/entry.S b/kernel/exception/entry.S index df38194f..2159f5bf 100644 --- a/kernel/exception/entry.S +++ b/kernel/exception/entry.S @@ -351,4 +351,11 @@ ENTRY(syscall_int) xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 jmp Err_Code +// irq模块初始化后的ignore_int入点 +ENTRY(ignore_int) + pushq $0 + pushq %rax + leaq ignore_int_handler(%rip), %rax // 获取ignore处理程序的地址 + xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 + jmp Err_Code diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index eb066eee..d68da32d 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -2,47 +2,47 @@ #include "irq.h" #include - #if _INTR_8259A_ #include #else #include #endif +#include "gate.h" #include #include #include -#include "gate.h" #include +extern void ignore_int(); #pragma GCC push_options #pragma GCC optimize("O0") // 保存函数调用现场的寄存器 -#define SAVE_ALL_REGS \ - "cld; \n\t" \ - "pushq %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %es, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %ds, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "xorq %rax, %rax;\n\t" \ - "pushq %rbp; \n\t" \ - "pushq %rdi; \n\t" \ - "pushq %rsi; \n\t" \ - "pushq %rdx; \n\t" \ - "pushq %rcx; \n\t" \ - "pushq %rbx; \n\t" \ - "pushq %r8 ; \n\t" \ - "pushq %r9 ; \n\t" \ - "pushq %r10; \n\t" \ - "pushq %r11; \n\t" \ - "pushq %r12; \n\t" \ - "pushq %r13; \n\t" \ - "pushq %r14; \n\t" \ - "pushq %r15; \n\t" \ - "movq $0x10, %rdx;\n\t" \ - "movq %rdx, %ds; \n\t" \ +#define SAVE_ALL_REGS \ + "cld; \n\t" \ + "pushq %rax; \n\t" \ + "pushq %rax; \n\t" \ + "movq %es, %rax; \n\t" \ + "pushq %rax; \n\t" \ + "movq %ds, %rax; \n\t" \ + "pushq %rax; \n\t" \ + "xorq %rax, %rax;\n\t" \ + "pushq %rbp; \n\t" \ + "pushq %rdi; \n\t" \ + "pushq %rsi; \n\t" \ + "pushq %rdx; \n\t" \ + "pushq %rcx; \n\t" \ + "pushq %rbx; \n\t" \ + "pushq %r8 ; \n\t" \ + "pushq %r9 ; \n\t" \ + "pushq %r10; \n\t" \ + "pushq %r11; \n\t" \ + "pushq %r12; \n\t" \ + "pushq %r13; \n\t" \ + "pushq %r14; \n\t" \ + "pushq %r15; \n\t" \ + "movq $0x10, %rdx;\n\t" \ + "movq %rdx, %ds; \n\t" \ "movq %rdx, %es; \n\t" // 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt @@ -52,14 +52,13 @@ // 构造中断entry // 为了复用返回函数的代码,需要压入一个错误码0 // todo: 将这里改为volatile,也许能解决编译选项为O1时,系统崩溃的问题 -#define Build_IRQ(number) \ - void IRQ_NAME(number); \ - __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \ - "pushq $0x00 \n\t" SAVE_ALL_REGS \ - "movq %rsp, %rdi \n\t" \ - "leaq ret_from_intr(%rip), %rax \n\t" \ - "pushq %rax \n\t" \ - "movq $" #number ", %rsi \n\t" \ +#define Build_IRQ(number) \ + void IRQ_NAME(number); \ + __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \ + "pushq $0x00 \n\t" SAVE_ALL_REGS "movq %rsp, %rdi \n\t" \ + "leaq ret_from_intr(%rip), %rax \n\t" \ + "pushq %rax \n\t" \ + "movq $" #number ", %rsi \n\t" \ "jmp do_IRQ \n\t"); // 构造中断入口 @@ -89,32 +88,11 @@ Build_IRQ(0x36); Build_IRQ(0x37); // 初始化中断数组 -void (*interrupt_table[24])(void) = - { - IRQ0x20interrupt, - IRQ0x21interrupt, - IRQ0x22interrupt, - IRQ0x23interrupt, - IRQ0x24interrupt, - IRQ0x25interrupt, - IRQ0x26interrupt, - IRQ0x27interrupt, - IRQ0x28interrupt, - IRQ0x29interrupt, - IRQ0x2ainterrupt, - IRQ0x2binterrupt, - IRQ0x2cinterrupt, - IRQ0x2dinterrupt, - IRQ0x2einterrupt, - IRQ0x2finterrupt, - IRQ0x30interrupt, - IRQ0x31interrupt, - IRQ0x32interrupt, - IRQ0x33interrupt, - IRQ0x34interrupt, - IRQ0x35interrupt, - IRQ0x36interrupt, - IRQ0x37interrupt, +void (*interrupt_table[24])(void) = { + IRQ0x20interrupt, IRQ0x21interrupt, IRQ0x22interrupt, IRQ0x23interrupt, IRQ0x24interrupt, IRQ0x25interrupt, + IRQ0x26interrupt, IRQ0x27interrupt, IRQ0x28interrupt, IRQ0x29interrupt, IRQ0x2ainterrupt, IRQ0x2binterrupt, + IRQ0x2cinterrupt, IRQ0x2dinterrupt, IRQ0x2einterrupt, IRQ0x2finterrupt, IRQ0x30interrupt, IRQ0x31interrupt, + IRQ0x32interrupt, IRQ0x33interrupt, IRQ0x34interrupt, IRQ0x35interrupt, IRQ0x36interrupt, IRQ0x37interrupt, }; /** @@ -139,18 +117,9 @@ Build_IRQ(0x80); // 系统调用入口 void (*syscall_intr_table[1])(void) = {IRQ0x80interrupt}; // 初始化IPI中断服务程序数组 -void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = - { - IRQ0xc8interrupt, - IRQ0xc9interrupt, - IRQ0xcainterrupt, - IRQ0xcbinterrupt, - IRQ0xccinterrupt, - IRQ0xcdinterrupt, - IRQ0xceinterrupt, - IRQ0xcfinterrupt, - IRQ0xd0interrupt, - IRQ0xd1interrupt, +void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = { + IRQ0xc8interrupt, IRQ0xc9interrupt, IRQ0xcainterrupt, IRQ0xcbinterrupt, IRQ0xccinterrupt, + IRQ0xcdinterrupt, IRQ0xceinterrupt, IRQ0xcfinterrupt, IRQ0xd0interrupt, IRQ0xd1interrupt, }; // 初始化local apic中断服务程序数组 @@ -164,18 +133,9 @@ Build_IRQ(0x9c); Build_IRQ(0x9d); Build_IRQ(0x9e); Build_IRQ(0x9f); -void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = - { - IRQ0x96interrupt, - IRQ0x97interrupt, - IRQ0x98interrupt, - IRQ0x99interrupt, - IRQ0x9ainterrupt, - IRQ0x9binterrupt, - IRQ0x9cinterrupt, - IRQ0x9dinterrupt, - IRQ0x9einterrupt, - IRQ0x9finterrupt, +void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = { + IRQ0x96interrupt, IRQ0x97interrupt, IRQ0x98interrupt, IRQ0x99interrupt, IRQ0x9ainterrupt, + IRQ0x9binterrupt, IRQ0x9cinterrupt, IRQ0x9dinterrupt, IRQ0x9einterrupt, IRQ0x9finterrupt, }; /** @@ -189,7 +149,8 @@ void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = * @param irq_name 中断名 * @return int */ -int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_intr_controller *controller, char *irq_name) +int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, + hardware_intr_controller *controller, char *irq_name) { // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素 irq_desc_t *p = NULL; @@ -252,6 +213,10 @@ int irq_unregister(ul irq_num) */ void irq_init() { + // 将idt重置为新的ignore_int入点(此前在head.S中有设置, + // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP + for (int i = 0; i < 256; ++i) + set_intr_gate(i, 0, ignore_int); #if _INTR_8259A_ init_8259A(); #else @@ -261,4 +226,15 @@ void irq_init() #endif } -#pragma GCC optimize("O0") \ No newline at end of file +#pragma GCC optimize("O0") + +/** + * @brief 当系统收到未知的中断时,执行此处理函数 + * + * @param regs + * @param error_code + */ +void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) +{ + kwarn("Unknown interrupt or fault at RIP.\n"); +} \ No newline at end of file diff --git a/kernel/head.S b/kernel/head.S index cc840da7..1f9e2c78 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -326,6 +326,7 @@ entry64: jnc start_smp setup_IDT: + // 该部分代码只在启动初期使用,后面的c文件中会重新设置IDT, leaq m_ignore_int(%rip), %rdx // 将ignore_int的地址暂时存到中段描述符的高8B movq $(0x08 << 16), %rax // 设置段选择子。由IDT结构和段选择子结构可知,本行设置段基地址为0x100000,TI=0,RPL=0 movw %dx, %ax @@ -460,6 +461,7 @@ go_to_smp_kernel: .quad smp_ap_start // ==== 异常/中断处理模块 ignore int: 忽略中断 +// (该部分代码只在启动初期使用,后面的c文件中会重新设置IDT,从而重设ignore_int的中断入点) m_ignore_int: // 切换到c语言的ignore_int movq go_to_ignore_int(%rip), %rax @@ -470,7 +472,7 @@ m_ignore_int: go_to_ignore_int: - .quad ignore_int + .quad ignore_int_handler ENTRY(head_stack_start) diff --git a/kernel/main.c b/kernel/main.c index e8f11e2f..b48d505c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -209,10 +209,4 @@ void Start_Kernel(void) while (1) pause(); } - -void ignore_int() -{ - kwarn("Unknown interrupt or fault at RIP.\n"); - sti(); -} #pragma GCC pop_options \ No newline at end of file From bf8f61b500575d3cb39c43848d76197881719669 Mon Sep 17 00:00:00 2001 From: login Date: Sun, 16 Oct 2022 19:38:46 +0800 Subject: [PATCH 06/11] =?UTF-8?q?bugfix:=20=E8=A7=A3=E5=86=B3=E4=BA=86igno?= =?UTF-8?q?re=5Fint=E5=9C=A8=E8=BF=90=E8=A1=8C=E6=97=B6=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=A0=B4=E5=9D=8F=E8=BF=9B=E7=A8=8B=E6=89=A7=E8=A1=8C=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=20(#61)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/driver/interrupt/apic/apic.c | 3 +- kernel/driver/interrupt/apic/apic.h | 2 +- kernel/exception/entry.S | 7 ++ kernel/exception/irq.c | 150 ++++++++++++---------------- kernel/head.S | 4 +- kernel/main.c | 6 -- 6 files changed, 76 insertions(+), 96 deletions(-) diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index 806fbd72..63c5cd61 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -344,7 +344,7 @@ void apic_local_apic_init() * @brief 初始化apic控制器 * */ -void apic_init() +int apic_init() { // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉 for (int i = 32; i <= 55; ++i) @@ -386,6 +386,7 @@ void apic_init() kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys); } sti(); + return 0; } /** * @brief 中断服务程序 diff --git a/kernel/driver/interrupt/apic/apic.h b/kernel/driver/interrupt/apic/apic.h index 5d64b105..3a001ce0 100644 --- a/kernel/driver/interrupt/apic/apic.h +++ b/kernel/driver/interrupt/apic/apic.h @@ -290,7 +290,7 @@ void apic_init_ap_core_local_apic(); * @brief 初始化apic控制器 * */ -void apic_init(); +int apic_init(); /** * @brief 读取指定类型的 Interrupt Control Structure diff --git a/kernel/exception/entry.S b/kernel/exception/entry.S index df38194f..2159f5bf 100644 --- a/kernel/exception/entry.S +++ b/kernel/exception/entry.S @@ -351,4 +351,11 @@ ENTRY(syscall_int) xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 jmp Err_Code +// irq模块初始化后的ignore_int入点 +ENTRY(ignore_int) + pushq $0 + pushq %rax + leaq ignore_int_handler(%rip), %rax // 获取ignore处理程序的地址 + xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 + jmp Err_Code diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index eb066eee..d68da32d 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -2,47 +2,47 @@ #include "irq.h" #include - #if _INTR_8259A_ #include #else #include #endif +#include "gate.h" #include #include #include -#include "gate.h" #include +extern void ignore_int(); #pragma GCC push_options #pragma GCC optimize("O0") // 保存函数调用现场的寄存器 -#define SAVE_ALL_REGS \ - "cld; \n\t" \ - "pushq %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %es, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %ds, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "xorq %rax, %rax;\n\t" \ - "pushq %rbp; \n\t" \ - "pushq %rdi; \n\t" \ - "pushq %rsi; \n\t" \ - "pushq %rdx; \n\t" \ - "pushq %rcx; \n\t" \ - "pushq %rbx; \n\t" \ - "pushq %r8 ; \n\t" \ - "pushq %r9 ; \n\t" \ - "pushq %r10; \n\t" \ - "pushq %r11; \n\t" \ - "pushq %r12; \n\t" \ - "pushq %r13; \n\t" \ - "pushq %r14; \n\t" \ - "pushq %r15; \n\t" \ - "movq $0x10, %rdx;\n\t" \ - "movq %rdx, %ds; \n\t" \ +#define SAVE_ALL_REGS \ + "cld; \n\t" \ + "pushq %rax; \n\t" \ + "pushq %rax; \n\t" \ + "movq %es, %rax; \n\t" \ + "pushq %rax; \n\t" \ + "movq %ds, %rax; \n\t" \ + "pushq %rax; \n\t" \ + "xorq %rax, %rax;\n\t" \ + "pushq %rbp; \n\t" \ + "pushq %rdi; \n\t" \ + "pushq %rsi; \n\t" \ + "pushq %rdx; \n\t" \ + "pushq %rcx; \n\t" \ + "pushq %rbx; \n\t" \ + "pushq %r8 ; \n\t" \ + "pushq %r9 ; \n\t" \ + "pushq %r10; \n\t" \ + "pushq %r11; \n\t" \ + "pushq %r12; \n\t" \ + "pushq %r13; \n\t" \ + "pushq %r14; \n\t" \ + "pushq %r15; \n\t" \ + "movq $0x10, %rdx;\n\t" \ + "movq %rdx, %ds; \n\t" \ "movq %rdx, %es; \n\t" // 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt @@ -52,14 +52,13 @@ // 构造中断entry // 为了复用返回函数的代码,需要压入一个错误码0 // todo: 将这里改为volatile,也许能解决编译选项为O1时,系统崩溃的问题 -#define Build_IRQ(number) \ - void IRQ_NAME(number); \ - __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \ - "pushq $0x00 \n\t" SAVE_ALL_REGS \ - "movq %rsp, %rdi \n\t" \ - "leaq ret_from_intr(%rip), %rax \n\t" \ - "pushq %rax \n\t" \ - "movq $" #number ", %rsi \n\t" \ +#define Build_IRQ(number) \ + void IRQ_NAME(number); \ + __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \ + "pushq $0x00 \n\t" SAVE_ALL_REGS "movq %rsp, %rdi \n\t" \ + "leaq ret_from_intr(%rip), %rax \n\t" \ + "pushq %rax \n\t" \ + "movq $" #number ", %rsi \n\t" \ "jmp do_IRQ \n\t"); // 构造中断入口 @@ -89,32 +88,11 @@ Build_IRQ(0x36); Build_IRQ(0x37); // 初始化中断数组 -void (*interrupt_table[24])(void) = - { - IRQ0x20interrupt, - IRQ0x21interrupt, - IRQ0x22interrupt, - IRQ0x23interrupt, - IRQ0x24interrupt, - IRQ0x25interrupt, - IRQ0x26interrupt, - IRQ0x27interrupt, - IRQ0x28interrupt, - IRQ0x29interrupt, - IRQ0x2ainterrupt, - IRQ0x2binterrupt, - IRQ0x2cinterrupt, - IRQ0x2dinterrupt, - IRQ0x2einterrupt, - IRQ0x2finterrupt, - IRQ0x30interrupt, - IRQ0x31interrupt, - IRQ0x32interrupt, - IRQ0x33interrupt, - IRQ0x34interrupt, - IRQ0x35interrupt, - IRQ0x36interrupt, - IRQ0x37interrupt, +void (*interrupt_table[24])(void) = { + IRQ0x20interrupt, IRQ0x21interrupt, IRQ0x22interrupt, IRQ0x23interrupt, IRQ0x24interrupt, IRQ0x25interrupt, + IRQ0x26interrupt, IRQ0x27interrupt, IRQ0x28interrupt, IRQ0x29interrupt, IRQ0x2ainterrupt, IRQ0x2binterrupt, + IRQ0x2cinterrupt, IRQ0x2dinterrupt, IRQ0x2einterrupt, IRQ0x2finterrupt, IRQ0x30interrupt, IRQ0x31interrupt, + IRQ0x32interrupt, IRQ0x33interrupt, IRQ0x34interrupt, IRQ0x35interrupt, IRQ0x36interrupt, IRQ0x37interrupt, }; /** @@ -139,18 +117,9 @@ Build_IRQ(0x80); // 系统调用入口 void (*syscall_intr_table[1])(void) = {IRQ0x80interrupt}; // 初始化IPI中断服务程序数组 -void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = - { - IRQ0xc8interrupt, - IRQ0xc9interrupt, - IRQ0xcainterrupt, - IRQ0xcbinterrupt, - IRQ0xccinterrupt, - IRQ0xcdinterrupt, - IRQ0xceinterrupt, - IRQ0xcfinterrupt, - IRQ0xd0interrupt, - IRQ0xd1interrupt, +void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = { + IRQ0xc8interrupt, IRQ0xc9interrupt, IRQ0xcainterrupt, IRQ0xcbinterrupt, IRQ0xccinterrupt, + IRQ0xcdinterrupt, IRQ0xceinterrupt, IRQ0xcfinterrupt, IRQ0xd0interrupt, IRQ0xd1interrupt, }; // 初始化local apic中断服务程序数组 @@ -164,18 +133,9 @@ Build_IRQ(0x9c); Build_IRQ(0x9d); Build_IRQ(0x9e); Build_IRQ(0x9f); -void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = - { - IRQ0x96interrupt, - IRQ0x97interrupt, - IRQ0x98interrupt, - IRQ0x99interrupt, - IRQ0x9ainterrupt, - IRQ0x9binterrupt, - IRQ0x9cinterrupt, - IRQ0x9dinterrupt, - IRQ0x9einterrupt, - IRQ0x9finterrupt, +void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = { + IRQ0x96interrupt, IRQ0x97interrupt, IRQ0x98interrupt, IRQ0x99interrupt, IRQ0x9ainterrupt, + IRQ0x9binterrupt, IRQ0x9cinterrupt, IRQ0x9dinterrupt, IRQ0x9einterrupt, IRQ0x9finterrupt, }; /** @@ -189,7 +149,8 @@ void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = * @param irq_name 中断名 * @return int */ -int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_intr_controller *controller, char *irq_name) +int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, + hardware_intr_controller *controller, char *irq_name) { // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素 irq_desc_t *p = NULL; @@ -252,6 +213,10 @@ int irq_unregister(ul irq_num) */ void irq_init() { + // 将idt重置为新的ignore_int入点(此前在head.S中有设置, + // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP + for (int i = 0; i < 256; ++i) + set_intr_gate(i, 0, ignore_int); #if _INTR_8259A_ init_8259A(); #else @@ -261,4 +226,15 @@ void irq_init() #endif } -#pragma GCC optimize("O0") \ No newline at end of file +#pragma GCC optimize("O0") + +/** + * @brief 当系统收到未知的中断时,执行此处理函数 + * + * @param regs + * @param error_code + */ +void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) +{ + kwarn("Unknown interrupt or fault at RIP.\n"); +} \ No newline at end of file diff --git a/kernel/head.S b/kernel/head.S index cc840da7..1f9e2c78 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -326,6 +326,7 @@ entry64: jnc start_smp setup_IDT: + // 该部分代码只在启动初期使用,后面的c文件中会重新设置IDT, leaq m_ignore_int(%rip), %rdx // 将ignore_int的地址暂时存到中段描述符的高8B movq $(0x08 << 16), %rax // 设置段选择子。由IDT结构和段选择子结构可知,本行设置段基地址为0x100000,TI=0,RPL=0 movw %dx, %ax @@ -460,6 +461,7 @@ go_to_smp_kernel: .quad smp_ap_start // ==== 异常/中断处理模块 ignore int: 忽略中断 +// (该部分代码只在启动初期使用,后面的c文件中会重新设置IDT,从而重设ignore_int的中断入点) m_ignore_int: // 切换到c语言的ignore_int movq go_to_ignore_int(%rip), %rax @@ -470,7 +472,7 @@ m_ignore_int: go_to_ignore_int: - .quad ignore_int + .quad ignore_int_handler ENTRY(head_stack_start) diff --git a/kernel/main.c b/kernel/main.c index e8f11e2f..b48d505c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -209,10 +209,4 @@ void Start_Kernel(void) while (1) pause(); } - -void ignore_int() -{ - kwarn("Unknown interrupt or fault at RIP.\n"); - sti(); -} #pragma GCC pop_options \ No newline at end of file From 1752fc1e8100694efa55492c0644e31d4670ebd1 Mon Sep 17 00:00:00 2001 From: longjin Date: Sun, 16 Oct 2022 20:41:35 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0kthread=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=EF=BC=8C=E5=87=8F=E5=B0=91=E6=AD=A7=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/process/kthread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/process/kthread.c b/kernel/process/kthread.c index 092a48c2..92bdc42f 100644 --- a/kernel/process/kthread.c +++ b/kernel/process/kthread.c @@ -27,7 +27,7 @@ struct kthread_create_info_t void *data; int node; - // kthreadd守护进程传递给kthread_create的结果 + // kthreadd守护进程传递给kthread_create的结果, 成功则返回PCB,不成功则该值为负数错误码。若该值为NULL,意味着创建过程尚未完成 struct process_control_block *result; struct List list; @@ -170,6 +170,7 @@ static int kthread(void *_create) // 将当前pcb返回给创建者 create->result = current_pcb; + current_pcb->state &= ~PROC_RUNNING; // 设置当前进程不是RUNNING态 // 发起调度,使得当前内核线程休眠。直到创建者通过process_wakeup将当前内核线程唤醒 sched(); From d364ed7d796633d7189c44dfc433abdcf40250fa Mon Sep 17 00:00:00 2001 From: longjin Date: Sun, 16 Oct 2022 20:54:02 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8=E5=BC=82=E5=B8=B8=E9=99=B7=E9=98=B1=E9=97=A8=E8=A2=AB?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=B8=85=E7=A9=BA=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/exception/irq.c | 17 +------- kernel/exception/trap.c | 92 +++++++++++++++++++++++++++++------------ 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index d68da32d..941d47e2 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -13,7 +13,6 @@ #include #include #include -extern void ignore_int(); #pragma GCC push_options #pragma GCC optimize("O0") @@ -213,10 +212,7 @@ int irq_unregister(ul irq_num) */ void irq_init() { - // 将idt重置为新的ignore_int入点(此前在head.S中有设置, - // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP - for (int i = 0; i < 256; ++i) - set_intr_gate(i, 0, ignore_int); + #if _INTR_8259A_ init_8259A(); #else @@ -227,14 +223,3 @@ void irq_init() #endif } #pragma GCC optimize("O0") - -/** - * @brief 当系统收到未知的中断时,执行此处理函数 - * - * @param regs - * @param error_code - */ -void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) -{ - kwarn("Unknown interrupt or fault at RIP.\n"); -} \ No newline at end of file diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index ad05edde..fe2e2e69 100644 --- a/kernel/exception/trap.c +++ b/kernel/exception/trap.c @@ -1,15 +1,19 @@ #include "trap.h" #include "gate.h" -#include #include -#include #include +#include +#include #include + +extern void ignore_int(); + // 0 #DE 除法错误 void do_divide_error(struct pt_regs *regs, unsigned long error_code) { // kerror("do_divide_error(0)"); - kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -20,7 +24,8 @@ void do_debug(struct pt_regs *regs, unsigned long error_code) { printk("[ "); printk_color(RED, BLACK, "ERROR / TRAP"); - printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -32,7 +37,8 @@ void do_nmi(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(BLUE, BLACK, "INT"); - printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -44,7 +50,8 @@ void do_int3(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(YELLOW, BLACK, "TRAP"); - printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -56,7 +63,8 @@ void do_overflow(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(YELLOW, BLACK, "TRAP"); - printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -66,7 +74,8 @@ void do_overflow(struct pt_regs *regs, unsigned long error_code) void do_bounds(struct pt_regs *regs, unsigned long error_code) { - kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -76,7 +85,8 @@ void do_bounds(struct pt_regs *regs, unsigned long error_code) void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code) { - kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code, + regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -86,7 +96,8 @@ void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code) void do_dev_not_avaliable(struct pt_regs *regs, unsigned long error_code) { - kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -98,7 +109,8 @@ void do_double_fault(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(RED, BLACK, "Terminate"); - printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -108,7 +120,8 @@ void do_double_fault(struct pt_regs *regs, unsigned long error_code) void do_coprocessor_segment_overrun(struct pt_regs *regs, unsigned long error_code) { - kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -120,7 +133,8 @@ void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code) printk("["); printk_color(RED, BLACK, "ERROR"); - printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); printk_color(YELLOW, BLACK, "Information:\n"); // 解析错误码 @@ -149,7 +163,8 @@ void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code) void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code) { - kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -159,7 +174,8 @@ void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code) void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code) { - kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -169,9 +185,12 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code) void do_general_protection(struct pt_regs *regs, unsigned long error_code) { - kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); if (error_code & 0x01) - printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n"); + printk_color(RED, BLACK, + "The exception occurred during delivery of an event external to the program,such as an interrupt " + "or an earlier exception.\n"); if (error_code & 0x02) printk_color(RED, BLACK, "Refers to a gate descriptor in the IDT;\n"); @@ -196,10 +215,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) unsigned long cr2 = 0; - __asm__ __volatile__("movq %%cr2, %0" - : "=r"(cr2)::"memory"); + __asm__ __volatile__("movq %%cr2, %0" : "=r"(cr2)::"memory"); - kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, + regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid); kerror("regs->rax = %#018lx\n", regs->rax); if (!(error_code & 0x01)) printk_color(RED, BLACK, "Page Not-Present,\t"); @@ -223,7 +242,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) printk_color(RED, BLACK, "\n"); printk_color(RED, BLACK, "CR2:%#018lx\n", cr2); - + traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -235,7 +254,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code) { - kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); while (1) hlt(); @@ -245,7 +265,8 @@ void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code) void do_alignment_check(struct pt_regs *regs, unsigned long error_code) { - kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -255,7 +276,8 @@ void do_alignment_check(struct pt_regs *regs, unsigned long error_code) void do_machine_check(struct pt_regs *regs, unsigned long error_code) { - kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -265,7 +287,8 @@ void do_machine_check(struct pt_regs *regs, unsigned long error_code) void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code) { - kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -275,7 +298,8 @@ void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code) void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code) { - kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -283,8 +307,24 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code) // 21-21 Intel保留,请勿使用 +/** + * @brief 当系统收到未知的中断时,执行此处理函数 + * + * @param regs + * @param error_code + */ +void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) +{ + kwarn("Unknown interrupt or fault at RIP.\n"); +} + void sys_vector_init() { + // 将idt重置为新的ignore_int入点(此前在head.S中有设置, + // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP + for (int i = 0; i < 256; ++i) + set_intr_gate(i, 0, ignore_int); + set_trap_gate(0, 0, divide_error); set_trap_gate(1, 0, debug); set_intr_gate(2, 0, nmi); From 34205659b5e64f87c7284313901331467c77cc18 Mon Sep 17 00:00:00 2001 From: kong <45937622+kkkkkong@users.noreply.github.com> Date: Mon, 17 Oct 2022 18:04:41 +0800 Subject: [PATCH 09/11] Patch isolate sched_cfs (#62) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 独立cfs到新的文件 * update * bugfix: 解决调度器卡住的问题 Co-authored-by: longjin --- .vscode/settings.json | 3 +- kernel/common/kfifo.h | 8 +-- kernel/sched/Makefile | 7 +- kernel/sched/cfs.c | 154 ++++++++++++++++++++++++++++++++++++++++ kernel/sched/cfs.h | 45 ++++++++++++ kernel/sched/sched.c | 159 ++---------------------------------------- kernel/sched/sched.h | 51 ++------------ 7 files changed, 219 insertions(+), 208 deletions(-) create mode 100644 kernel/sched/cfs.c create mode 100644 kernel/sched/cfs.h diff --git a/.vscode/settings.json b/.vscode/settings.json index f840a4b2..96619eba 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -146,7 +146,8 @@ "lockref.h": "c", "compiler_attributes.h": "c", "timer.h": "c", - "hid.h": "c" + "hid.h": "c", + "cfs.h": "c" }, "C_Cpp.errorSquiggles": "Enabled", "esbonio.sphinx.confDir": "" diff --git a/kernel/common/kfifo.h b/kernel/common/kfifo.h index 1c9c7778..f0490eb5 100644 --- a/kernel/common/kfifo.h +++ b/kernel/common/kfifo.h @@ -127,10 +127,10 @@ uint32_t kfifo_out_peek(struct kfifo_t *fifo, void *to, uint32_t size); * @param lock 自旋锁 * @return uint32_t 推入的数据大小 */ -uint32_t __always_inline kfifo_in_lockd(struct kfifo_t *fifo, const void *from, uint32_t size, spinlock_t *lock) +uint32_t __always_inline kfifo_in_locked(struct kfifo_t *fifo, const void *from, uint32_t size, spinlock_t *lock) { spin_lock(lock); - uint32_t retval = kfifo_in(&fifo, &from, size); + uint32_t retval = kfifo_in(fifo, from, size); spin_unlock(lock); return retval; } @@ -144,10 +144,10 @@ uint32_t __always_inline kfifo_in_lockd(struct kfifo_t *fifo, const void *from, * @param lock 自旋锁 * @return uint32_t 取出的数据大小 */ -uint32_t __always_inline kfifo_out_lockd(struct kfifo_t *fifo, void *to, uint32_t size, spinlock_t *lock) +uint32_t __always_inline kfifo_out_locked(struct kfifo_t *fifo, void *to, uint32_t size, spinlock_t *lock) { spin_lock(lock); - uint32_t retval = kfifo_out(&fifo, &to, size); + uint32_t retval = kfifo_out(fifo, to, size); spin_unlock(lock); return retval; } diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile index c22a6e24..7a90f4c9 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile @@ -2,7 +2,12 @@ CFLAGS += -I . -all: sched.o +all: sched.o cfs.o + +cfs.o: cfs.c + $(CC) $(CFLAGS) -c cfs.c -o cfs.o sched.o: sched.c $(CC) $(CFLAGS) -c sched.c -o sched.o +clean: + echo "Done." \ No newline at end of file diff --git a/kernel/sched/cfs.c b/kernel/sched/cfs.c new file mode 100644 index 00000000..9319891f --- /dev/null +++ b/kernel/sched/cfs.c @@ -0,0 +1,154 @@ +#include "cfs.h" +#include +#include +#include + +struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 + +/** + * @brief 从就绪队列中取出PCB + * + * @return struct process_control_block* + */ +struct process_control_block *sched_cfs_dequeue() +{ + if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) + { + // kdebug("list empty, count=%d", sched_cfs_ready_queue[proc_current_cpu_id].count); + return &initial_proc_union.pcb; + } + + struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list); + + list_del(&proc->list); + --sched_cfs_ready_queue[proc_current_cpu_id].count; + return proc; +} + +/** + * @brief 将PCB加入就绪队列 + * + * @param pcb + */ +void sched_cfs_enqueue(struct process_control_block *pcb) +{ + if (pcb == initial_proc[proc_current_cpu_id]) + return; + struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list); + if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0) + { + while (proc->virtual_runtime < pcb->virtual_runtime) + { + proc = container_of(list_next(&proc->list), struct process_control_block, list); + } + } + list_append(&proc->list, &pcb->list); + ++sched_cfs_ready_queue[proc_current_cpu_id].count; +} + +/** + * @brief 调度函数 + * + */ +void sched_cfs() +{ + + cli(); + + current_pcb->flags &= ~PF_NEED_SCHED; + // kdebug("current_pcb pid= %d", current_pcb->pid); + struct process_control_block *proc = sched_cfs_dequeue(); + // kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count); + if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换 + { + + // kdebug("current_pcb->virtual_runtime = %d,proc->vt= %d", current_pcb->virtual_runtime, proc->virtual_runtime); + if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理 + sched_cfs_enqueue(current_pcb); + // kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count); + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) + { + switch (proc->priority) + { + case 0: + case 1: + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count; + break; + case 2: + default: + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2; + break; + } + } + + + process_switch_mm(proc); + + switch_proc(current_pcb, proc); + } + else // 不进行切换 + { + // kdebug("not switch."); + sched_cfs_enqueue(proc); + + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) + { + switch (proc->priority) + { + case 0: + case 1: + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count; + break; + case 2: + default: + + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2; + break; + } + } + } + + sti(); +} + +/** + * @brief 当时钟中断到达时,更新时间片 + * + */ +void sched_update_jiffies() +{ + + switch (current_pcb->priority) + { + case 0: + case 1: + --sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies; + ++current_pcb->virtual_runtime; + break; + case 2: + default: + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2; + current_pcb->virtual_runtime += 2; + break; + } + // 时间片耗尽,标记可调度 + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) + current_pcb->flags |= PF_NEED_SCHED; +} + +/** + * @brief 初始化CFS调度器 + * + */ +void sched_cfs_init() +{ + memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t) * MAX_CPU_NUM); + for (int i = 0; i < MAX_CPU_NUM; ++i) + { + + list_init(&sched_cfs_ready_queue[i].proc_queue.list); + sched_cfs_ready_queue[i].count = 1; // 因为存在IDLE进程,因此为1 + sched_cfs_ready_queue[i].cpu_exec_proc_jiffies = 5; + sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff; + } +} \ No newline at end of file diff --git a/kernel/sched/cfs.h b/kernel/sched/cfs.h new file mode 100644 index 00000000..734783d4 --- /dev/null +++ b/kernel/sched/cfs.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +// @todo: 用红黑树重写cfs的队列 +struct sched_queue_t +{ + long count; // 当前队列中的数量 + long cpu_exec_proc_jiffies; // 进程可执行的时间片数量 + struct process_control_block proc_queue; +}; + +extern struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 + +/** + * @brief 调度函数 + * + */ +void sched_cfs(); + +/** + * @brief 将PCB加入就绪队列 + * + * @param pcb + */ +void sched_cfs_enqueue(struct process_control_block *pcb); + +/** + * @brief 从就绪队列中取出PCB + * + * @return struct process_control_block* + */ +struct process_control_block *sched_cfs_dequeue(); +/** + * @brief 初始化CFS进程调度器 + * + */ +void sched_cfs_init(); + +/** + * @brief 当时钟中断到达时,更新时间片 + * + */ +void sched_update_jiffies(); diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index c142c32e..8f3d7b36 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -2,54 +2,11 @@ #include #include #include - - -struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 - -/** - * @brief 从就绪队列中取出PCB - * - * @return struct process_control_block* - */ -struct process_control_block *sched_cfs_dequeue() -{ - if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) - { - // kdebug("list empty, count=%d", sched_cfs_ready_queue[proc_current_cpu_id].count); - return &initial_proc_union.pcb; - } - - struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list); - - list_del(&proc->list); - --sched_cfs_ready_queue[proc_current_cpu_id].count; - return proc; -} - -/** - * @brief 将PCB加入就绪队列 - * - * @param pcb - */ -void sched_cfs_enqueue(struct process_control_block *pcb) -{ - if (pcb == initial_proc[proc_current_cpu_id]) - return; - struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list); - if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0) - { - while (proc->virtual_runtime < pcb->virtual_runtime) - { - proc = container_of(list_next(&proc->list), struct process_control_block, list); - } - } - list_append(&proc->list, &pcb->list); - ++sched_cfs_ready_queue[proc_current_cpu_id].count; -} +#include /** * @brief 包裹shced_cfs_enqueue(),将PCB加入就绪队列 - * + * * @param pcb */ void sched_enqueue(struct process_control_block *pcb) @@ -57,124 +14,16 @@ void sched_enqueue(struct process_control_block *pcb) sched_cfs_enqueue(pcb); } -/** - * @brief 调度函数 - * - */ -void sched_cfs() -{ - - cli(); - - current_pcb->flags &= ~PF_NEED_SCHED; - struct process_control_block *proc = sched_cfs_dequeue(); - // kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count); - if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换 - { - - if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理 - sched_cfs_enqueue(current_pcb); - // kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count); - if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) - { - switch (proc->priority) - { - case 0: - case 1: - sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count; - break; - case 2: - default: - sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2; - break; - } - } - - // if (proc->pid == 0) - // { - // kdebug("switch to pid0, current pid%ld, vrt=%ld pid0 vrt=%ld", current_pcb->pid, current_pcb->virtual_runtime, proc->virtual_runtime); - // if(current_pcb->state != PROC_RUNNING) - // kdebug("current_pcb->state!=PROC_RUNNING"); - // } - - process_switch_mm(proc); - - switch_proc(current_pcb, proc); - } - else // 不进行切换 - { - // kdebug("not switch."); - sched_cfs_enqueue(proc); - - if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) - { - switch (proc->priority) - { - case 0: - case 1: - sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count; - // sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; - break; - case 2: - default: - // sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; - - sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2; - break; - } - } - } - - sti(); -} - /** * @brief 包裹sched_cfs(),调度函数 - * + * */ void sched() { sched_cfs(); } -/** - * @brief 当时钟中断到达时,更新时间片 - * - */ -void sched_update_jiffies() -{ - - switch (current_pcb->priority) - { - case 0: - case 1: - --sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies; - ++current_pcb->virtual_runtime; - break; - case 2: - default: - sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2; - current_pcb->virtual_runtime += 2; - break; - } - // 时间片耗尽,标记可调度 - if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) - current_pcb->flags |= PF_NEED_SCHED; -} - -/** - * @brief 初始化进程调度器 - * - */ void sched_init() { - memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t) * MAX_CPU_NUM); - for (int i = 0; i < MAX_CPU_NUM; ++i) - { - - list_init(&sched_cfs_ready_queue[i].proc_queue.list); - sched_cfs_ready_queue[i].count = 1; // 因为存在IDLE进程,因此为1 - sched_cfs_ready_queue[i].cpu_exec_proc_jiffies = 5; - sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff; - } + sched_cfs_init(); } \ No newline at end of file diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 8159ae72..8f088354 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2,60 +2,17 @@ #include #include - -// @todo: 用红黑树重写cfs的队列 -struct sched_queue_t -{ - long count; // 当前队列中的数量 - long cpu_exec_proc_jiffies; // 进程可执行的时间片数量 - struct process_control_block proc_queue; -}; - - -extern struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 - -/** - * @brief 调度函数 - * - */ -void sched_cfs(); - -/** - * @brief 包裹sched_cfs(),调度函数 - * - */ -void sched(); - -/** - * @brief 将PCB加入就绪队列 - * - * @param pcb - */ -void sched_cfs_enqueue(struct process_control_block *pcb); - /** * @brief 包裹sched_enqueue(),将PCB加入就绪队列 - * + * * @param pcb */ void sched_enqueue(struct process_control_block *pcb); - /** - * @brief 从就绪队列中取出PCB + * @brief 包裹sched_cfs(),调度函数 * - * @return struct process_control_block* */ -struct process_control_block *sched_cfs_dequeue(); +void sched(); -/** - * @brief 初始化进程调度器 - * - */ -void sched_init(); - -/** - * @brief 当时钟中断到达时,更新时间片 - * - */ -void sched_update_jiffies(); +void sched_init(); \ No newline at end of file From 173c988d5de29ab964da22ea48dfeec2b386fc29 Mon Sep 17 00:00:00 2001 From: longjin Date: Mon, 17 Oct 2022 18:40:07 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=99=A8=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/arch/x86_64/asm/cmpxchg.h | 2 +- kernel/common/hid.h | 2 +- kernel/process/process.h | 3 ++- kernel/sched/cfs.h | 6 ------ kernel/sched/sched.h | 8 +++++++- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/kernel/arch/x86_64/asm/cmpxchg.h b/kernel/arch/x86_64/asm/cmpxchg.h index f63ad259..520b4a97 100644 --- a/kernel/arch/x86_64/asm/cmpxchg.h +++ b/kernel/arch/x86_64/asm/cmpxchg.h @@ -78,4 +78,4 @@ extern void __cmpxchg_wrong_size(void) __compiletime_error("Bad argument size fo }) #define arch_try_cmpxchg(ptr, old_ptr, new_ptr) \ - __raw_try_cmpxchg((ptr), (old_ptr), (new_ptr), sizeof(*ptr)) \ No newline at end of file + __raw_try_cmpxchg((ptr), (old_ptr), (new_ptr), sizeof(*ptr)) diff --git a/kernel/common/hid.h b/kernel/common/hid.h index a215de3a..35ca8690 100644 --- a/kernel/common/hid.h +++ b/kernel/common/hid.h @@ -77,7 +77,7 @@ struct hid_parser int usage_max; int cnt_objects; // report descriptor中的对象数目 - int cnt_report // report desc中的report数目 + int cnt_report; // report desc中的report数目 }; diff --git a/kernel/process/process.h b/kernel/process/process.h index c2b9a700..9b6a0d16 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -44,7 +44,8 @@ .next_pcb = &proc, \ .parent_pcb = &proc, \ .exit_code = 0, \ - .wait_child_proc_exit = 0 \ + .wait_child_proc_exit = 0, \ + .worker_private = NULL \ } /** diff --git a/kernel/sched/cfs.h b/kernel/sched/cfs.h index 734783d4..00320e54 100644 --- a/kernel/sched/cfs.h +++ b/kernel/sched/cfs.h @@ -37,9 +37,3 @@ struct process_control_block *sched_cfs_dequeue(); * */ void sched_cfs_init(); - -/** - * @brief 当时钟中断到达时,更新时间片 - * - */ -void sched_update_jiffies(); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 8f088354..085050f9 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -15,4 +15,10 @@ void sched_enqueue(struct process_control_block *pcb); void sched(); -void sched_init(); \ No newline at end of file +void sched_init(); + +/** + * @brief 当时钟中断到达时,更新时间片 + * + */ +void sched_update_jiffies(); \ No newline at end of file From a9c5b3e45c1724d317fddfb22e406d2d09327a54 Mon Sep 17 00:00:00 2001 From: DaJiYuQia <88259094+DaJiYuQia@users.noreply.github.com> Date: Tue, 18 Oct 2022 20:38:34 +0800 Subject: [PATCH 11/11] Patch shell cursor (#59) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 调整代码减少bug * 修复换行光标bug Co-authored-by: longjin --- kernel/filesystem/VFS/VFS.c | 1 - kernel/lib/libUI/textui.c | 5 ++-- user/apps/shell/shell.c | 46 +++++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/kernel/filesystem/VFS/VFS.c b/kernel/filesystem/VFS/VFS.c index 24e2a9e6..010dd9c0 100644 --- a/kernel/filesystem/VFS/VFS.c +++ b/kernel/filesystem/VFS/VFS.c @@ -398,7 +398,6 @@ uint64_t do_open(const char *filename, int flags) // 寻找文件 struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0); - if (dentry == NULL && flags & O_CREAT) { // 先找到倒数第二级目录 diff --git a/kernel/lib/libUI/textui.c b/kernel/lib/libUI/textui.c index df5fa2cd..13224268 100644 --- a/kernel/lib/libUI/textui.c +++ b/kernel/lib/libUI/textui.c @@ -181,7 +181,8 @@ static int __textui_putchar_window(struct textui_window_t *window, uint16_t char ++vline->index; textui_refresh_characters(window, window->vline_operating, vline->index - 1, 1); // 换行 - if (vline->index >= window->chars_per_line) + // 加入光标后,因为会识别光标,所以需超过该行最大字符数才能创建新行 + if (vline->index > window->chars_per_line) { __textui_new_line(window, window->vline_operating); } @@ -295,7 +296,7 @@ int textui_putchar(uint16_t character, uint32_t FRcolor, uint32_t BKcolor) /** * @brief 初始化text ui框架 * - * @return int + * @return int */ int textui_init() { diff --git a/user/apps/shell/shell.c b/user/apps/shell/shell.c index fb1c4c60..ab9a8fba 100644 --- a/user/apps/shell/shell.c +++ b/user/apps/shell/shell.c @@ -1,12 +1,13 @@ -#include -#include -#include -#include -#include -#include -#include -#include #include "cmd.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include #define pause_cpu() asm volatile("pause\n\t"); #define MEM_HISTORY 1024 @@ -50,11 +51,14 @@ void main_loop(int kb_fd) { int argc = 0; char **argv; - + printf("[DragonOS] %s # ", shell_current_path); - + memset(input_buffer, 0, INPUT_BUFFER_SIZE); + //添加初始光标 + put_string(" ", COLOR_BLACK, COLOR_WHITE); + // 循环读取每一行到buffer count_history++; int count = shell_readline(kb_fd, input_buffer); @@ -125,6 +129,7 @@ void change_command(char *buf, int type) current_command_index = count_history - 2; strcpy(buf, history_commands[current_command_index]); printf("%s", buf); + put_string(" ", COLOR_BLACK, COLOR_WHITE); } /** * @brief 循环读取每一行 @@ -143,6 +148,8 @@ int shell_readline(int fd, char *buf) //向上方向键 if (count_history != 0 && key == 0xc8) { + // put_string(" ", COLOR_WHITE, COLOR_BLACK); + printf("%c", '\b'); clear_command(count, buf); count = 0; //向历史 @@ -152,6 +159,8 @@ int shell_readline(int fd, char *buf) //向下方向键 if (count_history != 0 && key == 0x50) { + // put_string(" ", COLOR_WHITE, COLOR_BLACK); + printf("%c", '\b'); clear_command(count, buf); count = 0; //向现在 @@ -162,9 +171,11 @@ int shell_readline(int fd, char *buf) { if (count > 0 && current_command_index >= count_history) { - memset(history_commands[current_command_index - 1], 0, sizeof(history_commands[current_command_index - 1])); + memset(history_commands[current_command_index - 1], 0, + sizeof(history_commands[current_command_index - 1])); count_history--; } + printf("%c", '\b'); return count; } @@ -174,14 +185,22 @@ int shell_readline(int fd, char *buf) { if (count > 0) { - buf[--count] = 0; + // 回退去除先前光标 printf("%c", '\b'); + // 去除字符 + printf("%c", '\b'); + buf[--count] = 0; + // 在最后一个字符处加光标 + put_string(" ", COLOR_BLACK, COLOR_WHITE); } } else { + printf("%c", '\b'); buf[count++] = key; printf("%c", key); + // 在最后一个字符处加光标 + put_string(" ", COLOR_BLACK, COLOR_WHITE); } if (count > 0 && current_command_index >= count_history) { @@ -197,7 +216,10 @@ int shell_readline(int fd, char *buf) // 输入缓冲区满了之后,直接返回 if (count >= INPUT_BUFFER_SIZE - 1) + { + printf("%c", '\b'); return count; + } pause_cpu(); }