mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
Merge branch 'master' into patch-screen-manager
This commit is contained in:
commit
fadeee36a2
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -114,7 +114,9 @@
|
|||||||
"errno.h": "c",
|
"errno.h": "c",
|
||||||
"bug.h": "c",
|
"bug.h": "c",
|
||||||
"apic_timer.h": "c",
|
"apic_timer.h": "c",
|
||||||
"sched.h": "c"
|
"sched.h": "c",
|
||||||
|
"preempt.h": "c",
|
||||||
|
"softirq.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
2
Makefile
2
Makefile
@ -7,7 +7,7 @@ export ARCH=__x86_64__
|
|||||||
export ROOT_PATH=$(shell pwd)
|
export ROOT_PATH=$(shell pwd)
|
||||||
|
|
||||||
export DEBUG=DEBUG
|
export DEBUG=DEBUG
|
||||||
export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -O0 -fno-stack-protector -D $(ARCH)
|
export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH) -O1
|
||||||
|
|
||||||
ifeq ($(DEBUG), DEBUG)
|
ifeq ($(DEBUG), DEBUG)
|
||||||
GLOBAL_CFLAGS += -g
|
GLOBAL_CFLAGS += -g
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
- 项目文档 **[docs.DragonOS.org](https://docs.dragonos.org)**
|
- 项目文档 **[docs.DragonOS.org](https://docs.dragonos.org)**
|
||||||
- 开源论坛 **[bbs.DragonOS.org](https://bbs.dragonos.org)**
|
- 开源论坛 **[bbs.DragonOS.org](https://bbs.dragonos.org)**
|
||||||
- 开发交流QQ群 **115763565**
|
- 开发交流QQ群 **115763565**
|
||||||
|
- 代码搜索引擎 [code.DragonOS.org](http://code.dragonos.org)
|
||||||
## 开发环境
|
## 开发环境
|
||||||
|
|
||||||
GCC>=8.0
|
GCC>=8.0
|
||||||
|
@ -10,7 +10,8 @@ This project is a operating system running on computer which is in X86_ 64 Archi
|
|||||||
- Home Page **[DragonOS.org](https://dragonos.org)**
|
- Home Page **[DragonOS.org](https://dragonos.org)**
|
||||||
- Documentation **[docs.DragonOS.org](https://docs.dragonos.org)**
|
- Documentation **[docs.DragonOS.org](https://docs.dragonos.org)**
|
||||||
- BBS **[bbs.DragonOS.org](https://bbs.dragonos.org)**
|
- BBS **[bbs.DragonOS.org](https://bbs.dragonos.org)**
|
||||||
|
- QQ group **115763565**
|
||||||
|
- code search engine [code.DragonOS.org](http://code.dragonos.org)
|
||||||
|
|
||||||
## Development Environment
|
## Development Environment
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "kprint.h"
|
#include "kprint.h"
|
||||||
#include "printk.h"
|
#include "printk.h"
|
||||||
|
// #pragma GCC optimize("O0")
|
||||||
// cpu支持的最大cpuid指令的基础主功能号
|
// cpu支持的最大cpuid指令的基础主功能号
|
||||||
uint Cpu_cpuid_max_Basic_mop;
|
uint Cpu_cpuid_max_Basic_mop;
|
||||||
// cpu支持的最大cpuid指令的扩展主功能号
|
// cpu支持的最大cpuid指令的扩展主功能号
|
||||||
|
@ -93,6 +93,7 @@ struct List
|
|||||||
static inline void list_init(struct List *list)
|
static inline void list_init(struct List *list)
|
||||||
{
|
{
|
||||||
list->next = list;
|
list->next = list;
|
||||||
|
io_mfence();
|
||||||
list->prev = list;
|
list->prev = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +107,11 @@ static inline void list_add(struct List *entry, struct List *node)
|
|||||||
{
|
{
|
||||||
|
|
||||||
node->next = entry->next;
|
node->next = entry->next;
|
||||||
|
barrier();
|
||||||
node->prev = entry;
|
node->prev = entry;
|
||||||
|
barrier();
|
||||||
node->next->prev = node;
|
node->next->prev = node;
|
||||||
|
barrier();
|
||||||
entry->next = node;
|
entry->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ static uint *get_pos_VBE_FB_addr();
|
|||||||
*/
|
*/
|
||||||
static int cls();
|
static int cls();
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
/**
|
/**
|
||||||
* @brief 滚动窗口(尚不支持向下滚动)
|
* @brief 滚动窗口(尚不支持向下滚动)
|
||||||
*
|
*
|
||||||
@ -53,7 +55,7 @@ static int cls();
|
|||||||
* @param animation 是否包含滑动动画
|
* @param animation 是否包含滑动动画
|
||||||
*/
|
*/
|
||||||
static int scroll(bool direction, int pixels, bool animation);
|
static int scroll(bool direction, int pixels, bool animation);
|
||||||
|
#pragma GCC pop_options
|
||||||
/**
|
/**
|
||||||
* @brief 将数字按照指定的要求转换成对应的字符串(2~36进制)
|
* @brief 将数字按照指定的要求转换成对应的字符串(2~36进制)
|
||||||
*
|
*
|
||||||
@ -184,7 +186,9 @@ static void auto_newline()
|
|||||||
#endif
|
#endif
|
||||||
pos.y = pos.max_y;
|
pos.y = pos.max_y;
|
||||||
int lines_to_scroll = 1;
|
int lines_to_scroll = 1;
|
||||||
|
barrier();
|
||||||
scroll(true, lines_to_scroll * pos.char_size_y, sw_show_scroll_animation);
|
scroll(true, lines_to_scroll * pos.char_size_y, sw_show_scroll_animation);
|
||||||
|
barrier();
|
||||||
pos.y -= (lines_to_scroll - 1);
|
pos.y -= (lines_to_scroll - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,7 +839,6 @@ static int scroll(bool direction, int pixels, bool animation)
|
|||||||
int md = pixels % pos.char_size_y;
|
int md = pixels % pos.char_size_y;
|
||||||
if (md)
|
if (md)
|
||||||
pixels = pixels + pos.char_size_y - md;
|
pixels = pixels + pos.char_size_y - md;
|
||||||
|
|
||||||
if (animation == false)
|
if (animation == false)
|
||||||
return do_scroll(direction, pixels);
|
return do_scroll(direction, pixels);
|
||||||
else
|
else
|
||||||
@ -957,3 +960,4 @@ int sprintk(char *buf, const char *fmt, ...)
|
|||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
// Created by longjin on 2022/1/21.
|
// Created by longjin on 2022/1/21.
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
#define PAD_ZERO 1 // 0填充
|
#define PAD_ZERO 1 // 0填充
|
||||||
#define LEFT 2 // 靠左对齐
|
#define LEFT 2 // 靠左对齐
|
||||||
#define RIGHT 4 // 靠右对齐
|
#define RIGHT 4 // 靠右对齐
|
||||||
@ -124,3 +125,4 @@ void printk_disable_animation();
|
|||||||
* @return int 字符串长度
|
* @return int 字符串长度
|
||||||
*/
|
*/
|
||||||
int sprintk(char *buf, const char *fmt, ...);
|
int sprintk(char *buf, const char *fmt, ...);
|
||||||
|
#pragma GCC pop_options
|
@ -2,6 +2,8 @@
|
|||||||
#include <common/compiler.h>
|
#include <common/compiler.h>
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
/**
|
/**
|
||||||
* @brief 当condition为true时输出警告信息
|
* @brief 当condition为true时输出警告信息
|
||||||
*
|
*
|
||||||
@ -19,3 +21,4 @@
|
|||||||
goto to; \
|
goto to; \
|
||||||
unlikely(__ret_warn_on); \
|
unlikely(__ret_warn_on); \
|
||||||
})
|
})
|
||||||
|
#pragma GCC pop_options
|
@ -10,6 +10,8 @@
|
|||||||
#include <process/process.h>
|
#include <process/process.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
// 导出定义在irq.c中的中段门表
|
// 导出定义在irq.c中的中段门表
|
||||||
extern void (*interrupt_table[24])(void);
|
extern void (*interrupt_table[24])(void);
|
||||||
|
|
||||||
@ -94,27 +96,7 @@ void apic_io_apic_init()
|
|||||||
|
|
||||||
// 不需要手动启动IO APIC,只要初始化了RTE寄存器之后,io apic就会自动启用了。
|
// 不需要手动启动IO APIC,只要初始化了RTE寄存器之后,io apic就会自动启用了。
|
||||||
// 而且不是每台电脑都有RCBA寄存器,因此不需要手动启用IO APIC
|
// 而且不是每台电脑都有RCBA寄存器,因此不需要手动启用IO APIC
|
||||||
/*
|
|
||||||
// get RCBA address
|
|
||||||
io_out32(0xcf8, 0x8000f8f0);
|
|
||||||
uint x = io_in32(0xcfc);
|
|
||||||
uint *p;
|
|
||||||
printk_color(RED, BLACK, "Get RCBA Address:%#010x\n", x);
|
|
||||||
x = x & 0xffffc000UL;
|
|
||||||
printk_color(RED, BLACK, "Get RCBA Address:%#010x\n", x);
|
|
||||||
|
|
||||||
// get OIC address
|
|
||||||
if (x > 0xfec00000 && x < 0xfee00000)
|
|
||||||
{
|
|
||||||
p = (unsigned int *)(x + 0x31feUL-apic_ioapic_map.addr_phys+apic_ioapic_map.virtual_index_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable IOAPIC
|
|
||||||
x = (*p & 0xffffff00) | 0x100;
|
|
||||||
io_mfence();
|
|
||||||
*p = x;
|
|
||||||
io_mfence();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -650,6 +632,7 @@ void apic_ioapic_edge_ack(ul irq_num) // 边沿触发
|
|||||||
*
|
*
|
||||||
* @param irq_num
|
* @param irq_num
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void apic_local_apic_edge_ack(ul irq_num)
|
void apic_local_apic_edge_ack(ul irq_num)
|
||||||
{
|
{
|
||||||
// 向EOI寄存器写入0x00表示结束中断
|
// 向EOI寄存器写入0x00表示结束中断
|
||||||
@ -660,6 +643,7 @@ void apic_local_apic_edge_ack(ul irq_num)
|
|||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 读取指定类型的 Interrupt Control Structure
|
* @brief 读取指定类型的 Interrupt Control Structure
|
||||||
*
|
*
|
||||||
@ -735,3 +719,4 @@ void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, u
|
|||||||
entry->destination.logical.reserved1 = 0;
|
entry->destination.logical.reserved1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
@ -5,6 +5,9 @@
|
|||||||
#include <exception/irq.h>
|
#include <exception/irq.h>
|
||||||
#include <mm/mm.h>
|
#include <mm/mm.h>
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
|
|
||||||
#define APIC_SUCCESS 0
|
#define APIC_SUCCESS 0
|
||||||
#define APIC_E_NOTFOUND 1
|
#define APIC_E_NOTFOUND 1
|
||||||
|
|
||||||
@ -319,3 +322,5 @@ void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答
|
|||||||
*/
|
*/
|
||||||
void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, uint8_t deliver_mode, uint8_t dest_mode,
|
void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, uint8_t deliver_mode, uint8_t dest_mode,
|
||||||
uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
|
uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
|
||||||
|
|
||||||
|
#pragma GCC pop_options
|
@ -4,14 +4,20 @@
|
|||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
|
||||||
|
// #pragma GCC push_options
|
||||||
|
// #pragma GCC optimize("O0")
|
||||||
uint64_t apic_timer_ticks_result = 0;
|
uint64_t apic_timer_ticks_result = 0;
|
||||||
|
|
||||||
void apic_timer_enable(uint64_t irq_num)
|
void apic_timer_enable(uint64_t irq_num)
|
||||||
{
|
{
|
||||||
// 启动apic定时器
|
// 启动apic定时器
|
||||||
|
io_mfence();
|
||||||
uint64_t val = apic_timer_get_LVT();
|
uint64_t val = apic_timer_get_LVT();
|
||||||
|
io_mfence();
|
||||||
val &= (~APIC_LVT_INT_MASKED);
|
val &= (~APIC_LVT_INT_MASKED);
|
||||||
|
io_mfence();
|
||||||
apic_timer_write_LVT(val);
|
apic_timer_write_LVT(val);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void apic_timer_disable(uint64_t irq_num)
|
void apic_timer_disable(uint64_t irq_num)
|
||||||
@ -29,18 +35,24 @@ void apic_timer_disable(uint64_t irq_num)
|
|||||||
uint64_t apic_timer_install(ul irq_num, void *arg)
|
uint64_t apic_timer_install(ul irq_num, void *arg)
|
||||||
{
|
{
|
||||||
// 设置div16
|
// 设置div16
|
||||||
|
io_mfence();
|
||||||
apic_timer_stop();
|
apic_timer_stop();
|
||||||
|
io_mfence();
|
||||||
apic_timer_set_div(APIC_TIMER_DIVISOR);
|
apic_timer_set_div(APIC_TIMER_DIVISOR);
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 设置初始计数
|
// 设置初始计数
|
||||||
apic_timer_set_init_cnt(*(uint64_t *)arg);
|
apic_timer_set_init_cnt(*(uint64_t *)arg);
|
||||||
|
io_mfence();
|
||||||
// 填写LVT
|
// 填写LVT
|
||||||
apic_timer_set_LVT(APIC_TIMER_IRQ_NUM, 1, APIC_LVT_Timer_Periodic);
|
apic_timer_set_LVT(APIC_TIMER_IRQ_NUM, 1, APIC_LVT_Timer_Periodic);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void apic_timer_uninstall(ul irq_num)
|
void apic_timer_uninstall(ul irq_num)
|
||||||
{
|
{
|
||||||
apic_timer_write_LVT(APIC_LVT_INT_MASKED);
|
apic_timer_write_LVT(APIC_LVT_INT_MASKED);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
hardware_intr_controller apic_timer_intr_controller =
|
hardware_intr_controller apic_timer_intr_controller =
|
||||||
@ -63,6 +75,7 @@ void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
|||||||
{
|
{
|
||||||
|
|
||||||
sched_update_jiffies();
|
sched_update_jiffies();
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,8 @@ extern uint64_t apic_timer_ticks_result;
|
|||||||
|
|
||||||
#define APIC_TIMER_IRQ_NUM 151
|
#define APIC_TIMER_IRQ_NUM 151
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
/**
|
/**
|
||||||
* @brief 设置apic定时器的分频计数
|
* @brief 设置apic定时器的分频计数
|
||||||
*
|
*
|
||||||
@ -79,3 +81,5 @@ extern uint64_t apic_timer_ticks_result;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void apic_timer_init();
|
void apic_timer_init();
|
||||||
|
|
||||||
|
#pragma GCC pop_options
|
@ -12,6 +12,8 @@
|
|||||||
#include <driver/interrupt/apic/apic_timer.h>
|
#include <driver/interrupt/apic/apic_timer.h>
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
static struct acpi_HPET_description_table_t *hpet_table;
|
static struct acpi_HPET_description_table_t *hpet_table;
|
||||||
static uint64_t HPET_REG_BASE = 0;
|
static uint64_t HPET_REG_BASE = 0;
|
||||||
static uint32_t HPET_COUNTER_CLK_PERIOD = 0; // 主计数器时间精度(单位:飞秒)
|
static uint32_t HPET_COUNTER_CLK_PERIOD = 0; // 主计数器时间精度(单位:飞秒)
|
||||||
@ -158,9 +160,9 @@ void HPET_measure_freq()
|
|||||||
// 顺便测定tsc频率
|
// 顺便测定tsc频率
|
||||||
test_tsc_start = rdtsc();
|
test_tsc_start = rdtsc();
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
while (measure_apic_timer_flag == false)
|
while (measure_apic_timer_flag == false)
|
||||||
;
|
;
|
||||||
|
kdebug("wait done");
|
||||||
|
|
||||||
irq_unregister(34);
|
irq_unregister(34);
|
||||||
|
|
||||||
@ -283,3 +285,4 @@ int HPET_init()
|
|||||||
// kdebug("HPET_freq=%ld", (long)HPET_freq);
|
// kdebug("HPET_freq=%ld", (long)HPET_freq);
|
||||||
// kdebug("HPET_freq=%lf", HPET_freq);
|
// kdebug("HPET_freq=%lf", HPET_freq);
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
||||||
|
@ -10,7 +10,7 @@ extern spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁
|
|||||||
#define MAX_USB_NUM 8 // pci总线上的usb设备的最大数量
|
#define MAX_USB_NUM 8 // pci总线上的usb设备的最大数量
|
||||||
|
|
||||||
// 在pci总线上寻找到的usb设备控制器的header
|
// 在pci总线上寻找到的usb设备控制器的header
|
||||||
struct pci_device_structure_header_t *usb_pdevs[MAX_USB_NUM];
|
static struct pci_device_structure_header_t *usb_pdevs[MAX_USB_NUM];
|
||||||
static int usb_pdevs_count = 0;
|
static int usb_pdevs_count = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,6 +34,7 @@ void usb_init()
|
|||||||
// 初始化每个usb控制器
|
// 初始化每个usb控制器
|
||||||
for (int i = 0; i < usb_pdevs_count; ++i)
|
for (int i = 0; i < usb_pdevs_count; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
switch (usb_pdevs[i]->ProgIF)
|
switch (usb_pdevs[i]->ProgIF)
|
||||||
{
|
{
|
||||||
case USB_TYPE_UHCI:
|
case USB_TYPE_UHCI:
|
||||||
@ -47,6 +48,7 @@ void usb_init()
|
|||||||
case USB_TYPE_XHCI:
|
case USB_TYPE_XHCI:
|
||||||
// 初始化对应的xhci控制器
|
// 初始化对应的xhci控制器
|
||||||
xhci_init((struct pci_device_structure_general_device_t *)usb_pdevs[i]);
|
xhci_init((struct pci_device_structure_general_device_t *)usb_pdevs[i]);
|
||||||
|
io_mfence();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include <exception/irq.h>
|
#include <exception/irq.h>
|
||||||
#include <driver/interrupt/apic/apic.h>
|
#include <driver/interrupt/apic/apic.h>
|
||||||
|
|
||||||
|
// 由于xhci寄存器读取需要对齐,因此禁用GCC优化选项
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
|
|
||||||
spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化)
|
spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化)
|
||||||
|
|
||||||
static int xhci_ctrl_count = 0; // xhci控制器计数
|
static int xhci_ctrl_count = 0; // xhci控制器计数
|
||||||
@ -52,7 +56,6 @@ hardware_intr_controller xhci_hc_intr_controller =
|
|||||||
例子:不能在一个32bit的寄存器中的偏移量8的位置开始读取1个字节
|
例子:不能在一个32bit的寄存器中的偏移量8的位置开始读取1个字节
|
||||||
这种情况下,我们必须从32bit的寄存器的0地址处开始读取32bit,然后通过移位的方式得到其中的字节。
|
这种情况下,我们必须从32bit的寄存器的0地址处开始读取32bit,然后通过移位的方式得到其中的字节。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define xhci_read_cap_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase + offset))
|
#define xhci_read_cap_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase + offset))
|
||||||
#define xhci_get_ptr_cap_reg8(id, offset) ((uint8_t *)(xhci_hc[id].vbase + offset))
|
#define xhci_get_ptr_cap_reg8(id, offset) ((uint8_t *)(xhci_hc[id].vbase + offset))
|
||||||
#define xhci_write_cap_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase + offset) = (uint8_t)value)
|
#define xhci_write_cap_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase + offset) = (uint8_t)value)
|
||||||
@ -195,11 +198,13 @@ static int xhci_hc_stop(int id)
|
|||||||
// 判断是否已经停止
|
// 判断是否已经停止
|
||||||
if (unlikely((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 1))
|
if (unlikely((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 1))
|
||||||
return 0;
|
return 0;
|
||||||
|
io_mfence();
|
||||||
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00000000);
|
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00000000);
|
||||||
|
io_mfence();
|
||||||
char timeout = 17;
|
char timeout = 17;
|
||||||
while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
|
while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
if (--timeout == 0)
|
if (--timeout == 0)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
@ -218,9 +223,11 @@ static int xhci_hc_reset(int id)
|
|||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
kdebug("usbsts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS));
|
kdebug("usbsts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS));
|
||||||
|
io_mfence();
|
||||||
// 判断HCHalted是否置位
|
// 判断HCHalted是否置位
|
||||||
if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
|
if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
kdebug("stopping usb hc...");
|
kdebug("stopping usb hc...");
|
||||||
// 未置位,需要先尝试停止usb主机控制器
|
// 未置位,需要先尝试停止usb主机控制器
|
||||||
retval = xhci_hc_stop(id);
|
retval = xhci_hc_stop(id);
|
||||||
@ -230,12 +237,16 @@ static int xhci_hc_reset(int id)
|
|||||||
int timeout = 500; // wait 500ms
|
int timeout = 500; // wait 500ms
|
||||||
// reset
|
// reset
|
||||||
uint32_t cmd = xhci_read_op_reg32(id, XHCI_OPS_USBCMD);
|
uint32_t cmd = xhci_read_op_reg32(id, XHCI_OPS_USBCMD);
|
||||||
|
io_mfence();
|
||||||
kdebug("cmd=%#010lx", cmd);
|
kdebug("cmd=%#010lx", cmd);
|
||||||
cmd |= (1 << 1);
|
cmd |= (1 << 1);
|
||||||
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, cmd);
|
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, cmd);
|
||||||
|
io_mfence();
|
||||||
kdebug("after rst, sts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS));
|
kdebug("after rst, sts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS));
|
||||||
|
io_mfence();
|
||||||
while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
|
while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
if (--timeout == 0)
|
if (--timeout == 0)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
@ -259,14 +270,15 @@ static int xhci_hc_stop_legacy(int id)
|
|||||||
// 判断当前entry是否为legacy support entry
|
// 判断当前entry是否为legacy support entry
|
||||||
if (xhci_read_cap_reg8(id, current_offset) == XHCI_XECP_ID_LEGACY)
|
if (xhci_read_cap_reg8(id, current_offset) == XHCI_XECP_ID_LEGACY)
|
||||||
{
|
{
|
||||||
|
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;
|
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);
|
usleep(1000);
|
||||||
if (--timeout == 0)
|
if (--timeout == 0)
|
||||||
{
|
{
|
||||||
@ -277,9 +289,10 @@ static int xhci_hc_stop_legacy(int id)
|
|||||||
// 处理完成
|
// 处理完成
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
io_mfence();
|
||||||
// 读取下一个entry的偏移增加量
|
// 读取下一个entry的偏移增加量
|
||||||
int next_off = ((xhci_read_cap_reg32(id, current_offset) & 0xff00) >> 8) << 2;
|
int next_off = ((xhci_read_cap_reg32(id, current_offset) & 0xff00) >> 8) << 2;
|
||||||
|
io_mfence();
|
||||||
// 将指针跳转到下一个entry
|
// 将指针跳转到下一个entry
|
||||||
current_offset = next_off ? (current_offset + next_off) : 0;
|
current_offset = next_off ? (current_offset + next_off) : 0;
|
||||||
} while (current_offset);
|
} while (current_offset);
|
||||||
@ -296,7 +309,9 @@ static int xhci_hc_stop_legacy(int id)
|
|||||||
*/
|
*/
|
||||||
static int xhci_hc_start_sched(int id)
|
static int xhci_hc_start_sched(int id)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 >> 2) | (1 << 3));
|
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 >> 2) | (1 << 3));
|
||||||
|
io_mfence();
|
||||||
usleep(100 * 1000);
|
usleep(100 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +323,9 @@ static int xhci_hc_start_sched(int id)
|
|||||||
*/
|
*/
|
||||||
static int xhci_hc_stop_sched(int id)
|
static int xhci_hc_stop_sched(int id)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00);
|
xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -336,13 +353,14 @@ static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
uint32_t dw0 = xhci_read_cap_reg32(id, list_off);
|
uint32_t dw0 = xhci_read_cap_reg32(id, list_off);
|
||||||
|
io_mfence();
|
||||||
uint32_t next_list_off = (dw0 >> 8) & 0xff;
|
uint32_t next_list_off = (dw0 >> 8) & 0xff;
|
||||||
next_list_off = next_list_off ? (list_off + (next_list_off << 2)) : 0;
|
next_list_off = next_list_off ? (list_off + (next_list_off << 2)) : 0;
|
||||||
|
|
||||||
if ((dw0 & 0xff) == XHCI_XECP_ID_PROTOCOL && ((dw0 & 0xff000000) >> 24) == version)
|
if ((dw0 & 0xff) == XHCI_XECP_ID_PROTOCOL && ((dw0 & 0xff000000) >> 24) == version)
|
||||||
{
|
{
|
||||||
uint32_t dw2 = xhci_read_cap_reg32(id, list_off + 8);
|
uint32_t dw2 = xhci_read_cap_reg32(id, list_off + 8);
|
||||||
|
io_mfence();
|
||||||
if (offset != NULL)
|
if (offset != NULL)
|
||||||
*offset = (uint32_t)(dw2 & 0xff) - 1; // 使其转换为zero based
|
*offset = (uint32_t)(dw2 & 0xff) - 1; // 使其转换为zero based
|
||||||
if (count != NULL)
|
if (count != NULL)
|
||||||
@ -368,8 +386,9 @@ static int xhci_hc_pair_ports(int id)
|
|||||||
{
|
{
|
||||||
|
|
||||||
struct xhci_caps_HCSPARAMS1_reg_t hcs1;
|
struct xhci_caps_HCSPARAMS1_reg_t hcs1;
|
||||||
|
io_mfence();
|
||||||
memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
|
memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
|
||||||
|
io_mfence();
|
||||||
// 从hcs1获取端口数量
|
// 从hcs1获取端口数量
|
||||||
xhci_hc[id].port_num = hcs1.max_ports;
|
xhci_hc[id].port_num = hcs1.max_ports;
|
||||||
|
|
||||||
@ -385,15 +404,18 @@ static int xhci_hc_pair_ports(int id)
|
|||||||
// 寻找所有的usb2端口
|
// 寻找所有的usb2端口
|
||||||
while (next_off)
|
while (next_off)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
next_off = xhci_hc_get_protocol_offset(id, next_off, 2, &offset, &cnt, &protocol_flags);
|
next_off = xhci_hc_get_protocol_offset(id, next_off, 2, &offset, &cnt, &protocol_flags);
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
if (cnt)
|
if (cnt)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cnt; ++i)
|
for (int i = 0; i < cnt; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u2++;
|
xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u2++;
|
||||||
xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB2;
|
xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB2;
|
||||||
|
io_mfence();
|
||||||
// usb2 high speed only
|
// usb2 high speed only
|
||||||
if (protocol_flags & 2)
|
if (protocol_flags & 2)
|
||||||
xhci_hc[id].ports[offset + i].flags |= XHCI_PROTOCOL_HSO;
|
xhci_hc[id].ports[offset + i].flags |= XHCI_PROTOCOL_HSO;
|
||||||
@ -405,12 +427,15 @@ static int xhci_hc_pair_ports(int id)
|
|||||||
next_off = xhci_hc[id].ext_caps_off;
|
next_off = xhci_hc[id].ext_caps_off;
|
||||||
while (next_off)
|
while (next_off)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
next_off = xhci_hc_get_protocol_offset(id, next_off, 3, &offset, &cnt, &protocol_flags);
|
next_off = xhci_hc_get_protocol_offset(id, next_off, 3, &offset, &cnt, &protocol_flags);
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
if (cnt)
|
if (cnt)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cnt; ++i)
|
for (int i = 0; i < cnt; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u3++;
|
xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u3++;
|
||||||
xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB3;
|
xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB3;
|
||||||
}
|
}
|
||||||
@ -424,13 +449,13 @@ static int xhci_hc_pair_ports(int id)
|
|||||||
{
|
{
|
||||||
if (unlikely(i == j))
|
if (unlikely(i == j))
|
||||||
continue;
|
continue;
|
||||||
|
io_mfence();
|
||||||
if ((xhci_hc[id].ports[i].offset == xhci_hc[id].ports[j].offset) &&
|
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].paired_port_num = j;
|
||||||
xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_HAS_PAIR;
|
xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_HAS_PAIR;
|
||||||
|
io_mfence();
|
||||||
xhci_hc[id].ports[j].paired_port_num = i;
|
xhci_hc[id].ports[j].paired_port_num = i;
|
||||||
xhci_hc[id].ports[j].flags |= XHCI_PROTOCOL_HAS_PAIR;
|
xhci_hc[id].ports[j].flags |= XHCI_PROTOCOL_HAS_PAIR;
|
||||||
}
|
}
|
||||||
@ -440,6 +465,7 @@ static int xhci_hc_pair_ports(int id)
|
|||||||
// 标记所有的usb3、单独的usb2端口为激活状态
|
// 标记所有的usb3、单独的usb2端口为激活状态
|
||||||
for (int i = 0; i < xhci_hc[id].port_num; ++i)
|
for (int i = 0; i < xhci_hc[id].port_num; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
if (XHCI_PORT_IS_USB3(id, i) ||
|
if (XHCI_PORT_IS_USB3(id, i) ||
|
||||||
(XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))))
|
(XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))))
|
||||||
xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_ACTIVE;
|
xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_ACTIVE;
|
||||||
@ -481,11 +507,12 @@ static uint64_t xhci_create_ring(int trbs)
|
|||||||
{
|
{
|
||||||
int total_size = trbs * sizeof(struct xhci_TRB_t);
|
int total_size = trbs * sizeof(struct xhci_TRB_t);
|
||||||
const uint64_t vaddr = (uint64_t)kmalloc(total_size, 0);
|
const uint64_t vaddr = (uint64_t)kmalloc(total_size, 0);
|
||||||
|
io_mfence();
|
||||||
memset((void *)vaddr, 0, total_size);
|
memset((void *)vaddr, 0, total_size);
|
||||||
|
io_mfence();
|
||||||
// 设置最后一个trb为link trb
|
// 设置最后一个trb为link trb
|
||||||
xhci_TRB_set_link_cmd(vaddr + total_size - sizeof(struct xhci_TRB_t));
|
xhci_TRB_set_link_cmd(vaddr + total_size - sizeof(struct xhci_TRB_t));
|
||||||
|
io_mfence();
|
||||||
return vaddr;
|
return vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,18 +526,19 @@ static uint64_t xhci_create_ring(int trbs)
|
|||||||
static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr)
|
static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr)
|
||||||
{
|
{
|
||||||
const uint64_t table_vaddr = (const uint64_t)kmalloc(64, 0); // table支持8个segment
|
const uint64_t table_vaddr = (const uint64_t)kmalloc(64, 0); // table支持8个segment
|
||||||
|
io_mfence();
|
||||||
if (unlikely(table_vaddr == NULL))
|
if (unlikely(table_vaddr == NULL))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
memset((void *)table_vaddr, 0, 64);
|
memset((void *)table_vaddr, 0, 64);
|
||||||
|
|
||||||
// 暂时只创建1个segment
|
// 暂时只创建1个segment
|
||||||
const uint64_t seg_vaddr = (const uint64_t)kmalloc(trbs * sizeof(struct xhci_TRB_t), 0);
|
const uint64_t seg_vaddr = (const uint64_t)kmalloc(trbs * sizeof(struct xhci_TRB_t), 0);
|
||||||
|
io_mfence();
|
||||||
if (unlikely(seg_vaddr == NULL))
|
if (unlikely(seg_vaddr == NULL))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memset((void *)seg_vaddr, 0, trbs * sizeof(struct xhci_TRB_t));
|
memset((void *)seg_vaddr, 0, trbs * sizeof(struct xhci_TRB_t));
|
||||||
|
io_mfence();
|
||||||
// 将segment地址和大小写入table
|
// 将segment地址和大小写入table
|
||||||
*(uint64_t *)(table_vaddr) = virt_2_phys(seg_vaddr);
|
*(uint64_t *)(table_vaddr) = virt_2_phys(seg_vaddr);
|
||||||
*(uint64_t *)(table_vaddr + 8) = trbs;
|
*(uint64_t *)(table_vaddr + 8) = trbs;
|
||||||
@ -522,13 +550,17 @@ static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr)
|
|||||||
void xhci_hc_irq_enable(uint64_t irq_num)
|
void xhci_hc_irq_enable(uint64_t irq_num)
|
||||||
{
|
{
|
||||||
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
||||||
|
io_mfence();
|
||||||
if (WARN_ON(cid == -1))
|
if (WARN_ON(cid == -1))
|
||||||
return;
|
return;
|
||||||
kdebug("start msi");
|
kdebug("start msi");
|
||||||
|
io_mfence();
|
||||||
pci_start_msi(xhci_hc[cid].pci_dev_hdr);
|
pci_start_msi(xhci_hc[cid].pci_dev_hdr);
|
||||||
kdebug("start sched");
|
kdebug("start sched");
|
||||||
|
io_mfence();
|
||||||
xhci_hc_start_sched(cid);
|
xhci_hc_start_sched(cid);
|
||||||
kdebug("start ports");
|
kdebug("start ports");
|
||||||
|
io_mfence();
|
||||||
xhci_hc_start_ports(cid);
|
xhci_hc_start_ports(cid);
|
||||||
kdebug("enabled");
|
kdebug("enabled");
|
||||||
}
|
}
|
||||||
@ -536,29 +568,34 @@ void xhci_hc_irq_enable(uint64_t irq_num)
|
|||||||
void xhci_hc_irq_disable(uint64_t irq_num)
|
void xhci_hc_irq_disable(uint64_t irq_num)
|
||||||
{
|
{
|
||||||
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
||||||
|
io_mfence();
|
||||||
if (WARN_ON(cid == -1))
|
if (WARN_ON(cid == -1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xhci_hc_stop_sched(cid);
|
xhci_hc_stop_sched(cid);
|
||||||
|
io_mfence();
|
||||||
pci_disable_msi(xhci_hc[cid].pci_dev_hdr);
|
pci_disable_msi(xhci_hc[cid].pci_dev_hdr);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
|
uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
|
||||||
{
|
{
|
||||||
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
||||||
|
io_mfence();
|
||||||
if (WARN_ON(cid == -1))
|
if (WARN_ON(cid == -1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg;
|
struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg;
|
||||||
struct msi_desc_t msi_desc;
|
struct msi_desc_t msi_desc;
|
||||||
memset(&msi_desc, 0, sizeof(struct msi_desc_t));
|
memset(&msi_desc, 0, sizeof(struct msi_desc_t));
|
||||||
|
io_mfence();
|
||||||
msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr;
|
msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr;
|
||||||
msi_desc.assert = info->assert;
|
msi_desc.assert = info->assert;
|
||||||
msi_desc.edge_trigger = info->edge_trigger;
|
msi_desc.edge_trigger = info->edge_trigger;
|
||||||
msi_desc.processor = info->processor;
|
msi_desc.processor = info->processor;
|
||||||
msi_desc.pci.msi_attribute.is_64 = 1;
|
msi_desc.pci.msi_attribute.is_64 = 1;
|
||||||
// todo: QEMU是使用msix的,因此要先在pci中实现msix
|
// todo: QEMU是使用msix的,因此要先在pci中实现msix
|
||||||
|
io_mfence();
|
||||||
int retval = pci_enable_msi(&msi_desc);
|
int retval = pci_enable_msi(&msi_desc);
|
||||||
kdebug("pci retval = %d", retval);
|
kdebug("pci retval = %d", retval);
|
||||||
kdebug("xhci irq %d installed.", irq_num);
|
kdebug("xhci irq %d installed.", irq_num);
|
||||||
@ -569,9 +606,11 @@ void xhci_hc_irq_uninstall(uint64_t irq_num)
|
|||||||
{
|
{
|
||||||
// todo
|
// todo
|
||||||
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
int cid = xhci_find_hcid_by_irq_num(irq_num);
|
||||||
|
io_mfence();
|
||||||
if (WARN_ON(cid == -1))
|
if (WARN_ON(cid == -1))
|
||||||
return;
|
return;
|
||||||
xhci_hc_stop(cid);
|
xhci_hc_stop(cid);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief xhci主机控制器的中断处理函数
|
* @brief xhci主机控制器的中断处理函数
|
||||||
@ -599,11 +638,14 @@ static int xhci_reset_port(const int id, const int port)
|
|||||||
// 相对于op寄存器基地址的偏移量
|
// 相对于op寄存器基地址的偏移量
|
||||||
uint64_t port_status_offset = XHCI_OPS_PRS + port * 16;
|
uint64_t port_status_offset = XHCI_OPS_PRS + port * 16;
|
||||||
// kdebug("to reset %d, offset=%#018lx", port, port_status_offset);
|
// kdebug("to reset %d, offset=%#018lx", port, port_status_offset);
|
||||||
|
io_mfence();
|
||||||
// 检查端口电源状态
|
// 检查端口电源状态
|
||||||
if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
|
if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
|
||||||
{
|
{
|
||||||
kdebug("port is power off, starting...");
|
kdebug("port is power off, starting...");
|
||||||
|
io_mfence();
|
||||||
xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9));
|
xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9));
|
||||||
|
io_mfence();
|
||||||
usleep(2000);
|
usleep(2000);
|
||||||
// 检测端口是否被启用, 若未启用,则报错
|
// 检测端口是否被启用, 若未启用,则报错
|
||||||
if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
|
if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
|
||||||
@ -613,10 +655,10 @@ static int xhci_reset_port(const int id, const int port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// kdebug("port:%d, power check ok", port);
|
// kdebug("port:%d, power check ok", port);
|
||||||
|
io_mfence();
|
||||||
// 确保端口的status被清0
|
// 确保端口的status被清0
|
||||||
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
|
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
|
||||||
|
io_mfence();
|
||||||
// 重置当前端口
|
// 重置当前端口
|
||||||
if (XHCI_PORT_IS_USB3(id, port))
|
if (XHCI_PORT_IS_USB3(id, port))
|
||||||
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 31));
|
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 31));
|
||||||
@ -629,7 +671,9 @@ static int xhci_reset_port(const int id, const int port)
|
|||||||
int timeout = 200;
|
int timeout = 200;
|
||||||
while (timeout)
|
while (timeout)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
|
uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
|
||||||
|
io_mfence();
|
||||||
if (XHCI_PORT_IS_USB3(id, port) && (val & (1 << 31)) == 0)
|
if (XHCI_PORT_IS_USB3(id, port) && (val & (1 << 31)) == 0)
|
||||||
break;
|
break;
|
||||||
else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0)
|
else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0)
|
||||||
@ -647,12 +691,14 @@ static int xhci_reset_port(const int id, const int port)
|
|||||||
// 等待恢复
|
// 等待恢复
|
||||||
usleep(USB_TIME_RST_REC * 1000);
|
usleep(USB_TIME_RST_REC * 1000);
|
||||||
uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
|
uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
|
||||||
|
io_mfence();
|
||||||
// 如果reset之后,enable bit仍然是1,那么说明reset成功
|
// 如果reset之后,enable bit仍然是1,那么说明reset成功
|
||||||
if (val & (1 << 1))
|
if (val & (1 << 1))
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
// 清除status change bit
|
// 清除status change bit
|
||||||
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
|
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
@ -691,6 +737,7 @@ static int xhci_hc_start_ports(int id)
|
|||||||
{
|
{
|
||||||
if (XHCI_PORT_IS_USB3(id, i) && XHCI_PORT_IS_ACTIVE(id, i))
|
if (XHCI_PORT_IS_USB3(id, i) && XHCI_PORT_IS_ACTIVE(id, i))
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
// reset该端口
|
// reset该端口
|
||||||
if (likely(xhci_reset_port(id, i) == 0)) // 如果端口reset成功,就获取它的描述符
|
if (likely(xhci_reset_port(id, i) == 0)) // 如果端口reset成功,就获取它的描述符
|
||||||
// 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的
|
// 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的
|
||||||
@ -731,14 +778,18 @@ static int xhci_hc_init_intr(int id)
|
|||||||
|
|
||||||
struct xhci_caps_HCSPARAMS1_reg_t hcs1;
|
struct xhci_caps_HCSPARAMS1_reg_t hcs1;
|
||||||
struct xhci_caps_HCSPARAMS2_reg_t hcs2;
|
struct xhci_caps_HCSPARAMS2_reg_t hcs2;
|
||||||
|
io_mfence();
|
||||||
memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
|
memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
|
||||||
|
io_mfence();
|
||||||
memcpy(&hcs2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t));
|
memcpy(&hcs2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t));
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
uint32_t max_segs = (1 << (uint32_t)(hcs2.ERST_Max));
|
uint32_t max_segs = (1 << (uint32_t)(hcs2.ERST_Max));
|
||||||
uint32_t max_interrupters = hcs1.max_intrs;
|
uint32_t max_interrupters = hcs1.max_intrs;
|
||||||
|
|
||||||
// 创建 event ring
|
// 创建 event ring
|
||||||
retval = xhci_create_event_ring(4096, &xhci_hc[id].event_ring_vaddr);
|
retval = xhci_create_event_ring(4096, &xhci_hc[id].event_ring_vaddr);
|
||||||
|
io_mfence();
|
||||||
if (unlikely((int64_t)(retval) == -ENOMEM))
|
if (unlikely((int64_t)(retval) == -ENOMEM))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
xhci_hc[id].event_ring_table_vaddr = retval;
|
xhci_hc[id].event_ring_table_vaddr = retval;
|
||||||
@ -747,15 +798,21 @@ static int xhci_hc_init_intr(int id)
|
|||||||
xhci_hc[id].current_event_ring_cycle = 1;
|
xhci_hc[id].current_event_ring_cycle = 1;
|
||||||
|
|
||||||
// 写入第0个中断寄存器组
|
// 写入第0个中断寄存器组
|
||||||
|
io_mfence();
|
||||||
xhci_write_intr_reg32(id, 0, XHCI_IR_MAN, 0x3); // 使能中断并清除pending位(这个pending位是写入1就清0的)
|
xhci_write_intr_reg32(id, 0, XHCI_IR_MAN, 0x3); // 使能中断并清除pending位(这个pending位是写入1就清0的)
|
||||||
|
io_mfence();
|
||||||
xhci_write_intr_reg32(id, 0, XHCI_IR_MOD, 0); // 关闭中断管制
|
xhci_write_intr_reg32(id, 0, XHCI_IR_MOD, 0); // 关闭中断管制
|
||||||
|
io_mfence();
|
||||||
xhci_write_intr_reg32(id, 0, XHCI_IR_TABLE_SIZE, 1); // 当前只有1个segment
|
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].event_ring_vaddr) | (1 << 3)); // 写入dequeue寄存器,并清除busy位(写1就会清除)
|
xhci_write_intr_reg64(id, 0, XHCI_IR_DEQUEUE, virt_2_phys(xhci_hc[id].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地址
|
xhci_write_intr_reg64(id, 0, XHCI_IR_TABLE_ADDR, virt_2_phys(xhci_hc[id].event_ring_table_vaddr)); // 写入table地址
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 清除状态位
|
// 清除状态位
|
||||||
xhci_write_op_reg32(id, XHCI_OPS_USBSTS, (1 << 10) | (1 << 4) | (1 << 3) | (1 << 2));
|
xhci_write_op_reg32(id, XHCI_OPS_USBSTS, (1 << 10) | (1 << 4) | (1 << 3) | (1 << 2));
|
||||||
|
io_mfence();
|
||||||
// 开启usb中断
|
// 开启usb中断
|
||||||
// 注册中断处理程序
|
// 注册中断处理程序
|
||||||
struct xhci_hc_irq_install_info_t install_info;
|
struct xhci_hc_irq_install_info_t install_info;
|
||||||
@ -766,7 +823,9 @@ static int xhci_hc_init_intr(int id)
|
|||||||
char *buf = (char *)kmalloc(16, 0);
|
char *buf = (char *)kmalloc(16, 0);
|
||||||
memset(buf, 0, 16);
|
memset(buf, 0, 16);
|
||||||
sprintk(buf, "xHCI HC%d", id);
|
sprintk(buf, "xHCI HC%d", id);
|
||||||
|
io_mfence();
|
||||||
irq_register(xhci_controller_irq_num[id], &install_info, &xhci_hc_irq_handler, id, &xhci_hc_intr_controller, buf);
|
irq_register(xhci_controller_irq_num[id], &install_info, &xhci_hc_irq_handler, id, &xhci_hc_intr_controller, buf);
|
||||||
|
io_mfence();
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
kdebug("xhci host controller %d: interrupt registered. irq num=%d", id, xhci_controller_irq_num[id]);
|
kdebug("xhci host controller %d: interrupt registered. irq num=%d", id, xhci_controller_irq_num[id]);
|
||||||
@ -790,7 +849,7 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
|
|
||||||
spin_lock(&xhci_controller_init_lock);
|
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();
|
int cid = xhci_hc_find_available_id();
|
||||||
if (cid < 0)
|
if (cid < 0)
|
||||||
{
|
{
|
||||||
@ -801,13 +860,14 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
memset(&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
|
memset(&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
|
||||||
xhci_hc[cid].controller_id = cid;
|
xhci_hc[cid].controller_id = cid;
|
||||||
xhci_hc[cid].pci_dev_hdr = dev_hdr;
|
xhci_hc[cid].pci_dev_hdr = dev_hdr;
|
||||||
|
io_mfence();
|
||||||
pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, 0x0006); // mem I/O access enable and bus master enable
|
pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, 0x0006); // mem I/O access enable and bus master enable
|
||||||
|
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));
|
// 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);
|
mm_map_phys_addr(xhci_hc[cid].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true);
|
||||||
|
io_mfence();
|
||||||
// 读取xhci控制寄存器
|
// 读取xhci控制寄存器
|
||||||
uint16_t iversion = *(uint16_t *)(xhci_hc[cid].vbase + XHCI_CAPS_HCIVERSION);
|
uint16_t iversion = *(uint16_t *)(xhci_hc[cid].vbase + XHCI_CAPS_HCIVERSION);
|
||||||
|
|
||||||
@ -824,9 +884,11 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
// kdebug("hcc1.xECP=%#010lx", hcc1.xECP);
|
// kdebug("hcc1.xECP=%#010lx", hcc1.xECP);
|
||||||
// 计算operational registers的地址
|
// 计算operational registers的地址
|
||||||
xhci_hc[cid].vbase_op = xhci_hc[cid].vbase + xhci_read_cap_reg8(cid, XHCI_CAPS_CAPLENGTH);
|
xhci_hc[cid].vbase_op = xhci_hc[cid].vbase + xhci_read_cap_reg8(cid, XHCI_CAPS_CAPLENGTH);
|
||||||
|
io_mfence();
|
||||||
xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved
|
xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved
|
||||||
|
io_mfence();
|
||||||
xhci_hc[cid].rts_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_RTSOFF) & (~0x1f); // bits [4:0] reserved.
|
xhci_hc[cid].rts_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_RTSOFF) & (~0x1f); // bits [4:0] reserved.
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
xhci_hc[cid].ext_caps_off = 1UL * (hcc1.xECP) * 4;
|
xhci_hc[cid].ext_caps_off = 1UL * (hcc1.xECP) * 4;
|
||||||
xhci_hc[cid].context_size = (hcc1.csz) ? 64 : 32;
|
xhci_hc[cid].context_size = (hcc1.csz) ? 64 : 32;
|
||||||
@ -845,25 +907,27 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff);
|
pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff);
|
||||||
pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff);
|
pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff);
|
||||||
}
|
}
|
||||||
|
io_mfence();
|
||||||
// 关闭legacy支持
|
// 关闭legacy支持
|
||||||
FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed);
|
FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed);
|
||||||
|
io_mfence();
|
||||||
// 重置xhci控制器
|
// 重置xhci控制器
|
||||||
FAIL_ON_TO(xhci_hc_reset(cid), failed);
|
FAIL_ON_TO(xhci_hc_reset(cid), failed);
|
||||||
|
io_mfence();
|
||||||
// 端口配对
|
// 端口配对
|
||||||
FAIL_ON_TO(xhci_hc_pair_ports(cid), failed);
|
FAIL_ON_TO(xhci_hc_pair_ports(cid), failed);
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// ========== 设置USB host controller =========
|
// ========== 设置USB host controller =========
|
||||||
// 获取页面大小
|
// 获取页面大小
|
||||||
kdebug("ops pgsize=%#010lx", xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE));
|
kdebug("ops pgsize=%#010lx", xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE));
|
||||||
xhci_hc[cid].page_size = (xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE) & 0xffff) << 12;
|
xhci_hc[cid].page_size = (xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE) & 0xffff) << 12;
|
||||||
kdebug("page size=%d", xhci_hc[cid].page_size);
|
kdebug("page size=%d", xhci_hc[cid].page_size);
|
||||||
|
io_mfence();
|
||||||
// 获取设备上下文空间
|
// 获取设备上下文空间
|
||||||
xhci_hc[cid].dcbaap_vaddr = (uint64_t)kmalloc(2048, 0); // 分配2KB的设备上下文地址数组空间
|
xhci_hc[cid].dcbaap_vaddr = (uint64_t)kmalloc(2048, 0); // 分配2KB的设备上下文地址数组空间
|
||||||
memset((void *)xhci_hc[cid].dcbaap_vaddr, 0, 2048);
|
memset((void *)xhci_hc[cid].dcbaap_vaddr, 0, 2048);
|
||||||
|
io_mfence();
|
||||||
kdebug("dcbaap_vaddr=%#018lx", xhci_hc[cid].dcbaap_vaddr);
|
kdebug("dcbaap_vaddr=%#018lx", xhci_hc[cid].dcbaap_vaddr);
|
||||||
if (unlikely(!xhci_is_aligned64(xhci_hc[cid].dcbaap_vaddr))) // 地址不是按照64byte对齐
|
if (unlikely(!xhci_is_aligned64(xhci_hc[cid].dcbaap_vaddr))) // 地址不是按照64byte对齐
|
||||||
{
|
{
|
||||||
@ -872,7 +936,7 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
}
|
}
|
||||||
// 写入dcbaap
|
// 写入dcbaap
|
||||||
xhci_write_op_reg64(cid, XHCI_OPS_DCBAAP, virt_2_phys(xhci_hc[cid].dcbaap_vaddr));
|
xhci_write_op_reg64(cid, XHCI_OPS_DCBAAP, virt_2_phys(xhci_hc[cid].dcbaap_vaddr));
|
||||||
|
io_mfence();
|
||||||
// 创建command ring
|
// 创建command ring
|
||||||
xhci_hc[cid].cmd_ring_vaddr = xhci_create_ring(XHCI_CMND_RING_TRBS);
|
xhci_hc[cid].cmd_ring_vaddr = xhci_create_ring(XHCI_CMND_RING_TRBS);
|
||||||
if (unlikely(!xhci_is_aligned64(xhci_hc[cid].cmd_ring_vaddr))) // 地址不是按照64byte对齐
|
if (unlikely(!xhci_is_aligned64(xhci_hc[cid].cmd_ring_vaddr))) // 地址不是按照64byte对齐
|
||||||
@ -883,17 +947,21 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
|
|
||||||
// 设置初始cycle bit为1
|
// 设置初始cycle bit为1
|
||||||
xhci_hc[cid].cmd_trb_cycle = XHCI_TRB_CYCLE_ON;
|
xhci_hc[cid].cmd_trb_cycle = XHCI_TRB_CYCLE_ON;
|
||||||
|
io_mfence();
|
||||||
// 写入command ring控制寄存器
|
// 写入command ring控制寄存器
|
||||||
xhci_write_op_reg64(cid, XHCI_OPS_CRCR, virt_2_phys(xhci_hc[cid].cmd_ring_vaddr) | xhci_hc[cid].cmd_trb_cycle);
|
xhci_write_op_reg64(cid, XHCI_OPS_CRCR, virt_2_phys(xhci_hc[cid].cmd_ring_vaddr) | xhci_hc[cid].cmd_trb_cycle);
|
||||||
// 写入配置寄存器
|
// 写入配置寄存器
|
||||||
uint32_t max_slots = hcs1.max_slots;
|
uint32_t max_slots = hcs1.max_slots;
|
||||||
kdebug("max slots = %d", max_slots);
|
kdebug("max slots = %d", max_slots);
|
||||||
|
io_mfence();
|
||||||
xhci_write_op_reg32(cid, XHCI_OPS_CONFIG, max_slots);
|
xhci_write_op_reg32(cid, XHCI_OPS_CONFIG, max_slots);
|
||||||
|
io_mfence();
|
||||||
// 写入设备通知控制寄存器
|
// 写入设备通知控制寄存器
|
||||||
xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
|
xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn);
|
FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn);
|
||||||
|
io_mfence();
|
||||||
++xhci_ctrl_count;
|
++xhci_ctrl_count;
|
||||||
spin_unlock(&xhci_controller_init_lock);
|
spin_unlock(&xhci_controller_init_lock);
|
||||||
return;
|
return;
|
||||||
@ -912,9 +980,10 @@ failed_free_dyn:; // 释放动态申请的内存
|
|||||||
kfree((void *)xhci_hc[cid].event_ring_vaddr);
|
kfree((void *)xhci_hc[cid].event_ring_vaddr);
|
||||||
|
|
||||||
failed:;
|
failed:;
|
||||||
|
io_mfence();
|
||||||
// 取消地址映射
|
// 取消地址映射
|
||||||
mm_unmap(xhci_hc[cid].vbase, 65536);
|
mm_unmap(xhci_hc[cid].vbase, 65536);
|
||||||
|
io_mfence();
|
||||||
// 清空数组
|
// 清空数组
|
||||||
memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
|
memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
|
||||||
|
|
||||||
@ -922,3 +991,4 @@ 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);
|
spin_unlock(&xhci_controller_init_lock);
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
@ -2,7 +2,7 @@
|
|||||||
#include <driver/usb/usb.h>
|
#include <driver/usb/usb.h>
|
||||||
#include <driver/pci/pci.h>
|
#include <driver/pci/pci.h>
|
||||||
#include <driver/pci/msi.h>
|
#include <driver/pci/msi.h>
|
||||||
|
// #pragma GCC optimize("O0")
|
||||||
#define XHCI_MAX_HOST_CONTROLLERS 4 // 本驱动程序最大支持4个xhci root hub controller
|
#define XHCI_MAX_HOST_CONTROLLERS 4 // 本驱动程序最大支持4个xhci root hub controller
|
||||||
#define XHCI_MAX_ROOT_HUB_PORTS 128 // 本驱动程序最大支持127个root hub 端口(第0个保留)
|
#define XHCI_MAX_ROOT_HUB_PORTS 128 // 本驱动程序最大支持127个root hub 端口(第0个保留)
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
#include <mm/mm.h>
|
#include <mm/mm.h>
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
//描述符表的结构体
|
//描述符表的结构体
|
||||||
struct desc_struct
|
struct desc_struct
|
||||||
{
|
{
|
||||||
@ -185,3 +187,5 @@ void set_tss64(unsigned int *Table, unsigned long rsp0, unsigned long rsp1, unsi
|
|||||||
*(unsigned long *)(Table + 21) = ist7;
|
*(unsigned long *)(Table + 21) = ist7;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma GCC pop_options
|
@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include <common/errno.h>
|
#include <common/errno.h>
|
||||||
|
|
||||||
// 对进行
|
|
||||||
#if _INTR_8259A_
|
#if _INTR_8259A_
|
||||||
#include <driver/interrupt/8259A/8259A.h>
|
#include <driver/interrupt/8259A/8259A.h>
|
||||||
#else
|
#else
|
||||||
@ -13,6 +14,8 @@
|
|||||||
#include "gate.h"
|
#include "gate.h"
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
// 保存函数调用现场的寄存器
|
// 保存函数调用现场的寄存器
|
||||||
#define SAVE_ALL_REGS \
|
#define SAVE_ALL_REGS \
|
||||||
"cld; \n\t" \
|
"cld; \n\t" \
|
||||||
@ -254,3 +257,4 @@ void irq_init()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#pragma GCC optimize("O0")
|
@ -10,10 +10,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <common/glib.h>
|
#include <common/glib.h>
|
||||||
|
|
||||||
#include <process/ptrace.h>
|
#include <process/ptrace.h>
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize ("O0")
|
||||||
|
|
||||||
#define IRQ_NUM 24
|
#define IRQ_NUM 24
|
||||||
#define SMP_IRQ_NUM 10
|
#define SMP_IRQ_NUM 10
|
||||||
@ -165,3 +166,4 @@ int irq_unregister(ul irq_num);
|
|||||||
* @brief 初始化中断模块
|
* @brief 初始化中断模块
|
||||||
*/
|
*/
|
||||||
void irq_init();
|
void irq_init();
|
||||||
|
#pragma GCC pop_options
|
@ -34,11 +34,12 @@
|
|||||||
#include <driver/video/video.h>
|
#include <driver/video/video.h>
|
||||||
|
|
||||||
#include <driver/interrupt/apic/apic_timer.h>
|
#include <driver/interrupt/apic/apic_timer.h>
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O3")
|
||||||
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
|
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
|
||||||
ul bsp_idt_size, bsp_gdt_size;
|
ul bsp_idt_size, bsp_gdt_size;
|
||||||
|
|
||||||
struct memory_desc memory_management_struct = {{0}, 0};
|
|
||||||
// struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
|
// struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
|
||||||
void test_slab();
|
void test_slab();
|
||||||
|
|
||||||
@ -126,12 +127,19 @@ void system_initialize()
|
|||||||
current_pcb->preempt_count = 0;
|
current_pcb->preempt_count = 0;
|
||||||
// 先初始化系统调用模块
|
// 先初始化系统调用模块
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
io_mfence();
|
||||||
// 再初始化进程模块。顺序不能调转
|
// 再初始化进程模块。顺序不能调转
|
||||||
sched_init();
|
sched_init();
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
timer_init();
|
timer_init();
|
||||||
|
|
||||||
|
// 这里必须加内存屏障,否则会出错
|
||||||
|
io_mfence();
|
||||||
smp_init();
|
smp_init();
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
|
|
||||||
cpu_init();
|
cpu_init();
|
||||||
ps2_keyboard_init();
|
ps2_keyboard_init();
|
||||||
// ps2_mouse_init();
|
// ps2_mouse_init();
|
||||||
@ -144,20 +152,24 @@ void system_initialize()
|
|||||||
|
|
||||||
// process_init();
|
// process_init();
|
||||||
HPET_init();
|
HPET_init();
|
||||||
|
io_mfence();
|
||||||
HPET_measure_freq();
|
HPET_measure_freq();
|
||||||
|
io_mfence();
|
||||||
// current_pcb->preempt_count = 0;
|
// current_pcb->preempt_count = 0;
|
||||||
// kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq());
|
// kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq());
|
||||||
|
|
||||||
process_init();
|
process_init();
|
||||||
// 对显示模块进行高级初始化,启用double buffer
|
// 对显示模块进行高级初始化,启用double buffer
|
||||||
video_init(true);
|
video_init(true);
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// fat32_init();
|
// fat32_init();
|
||||||
HPET_enable();
|
HPET_enable();
|
||||||
|
|
||||||
|
io_mfence();
|
||||||
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
|
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
|
||||||
apic_timer_init();
|
apic_timer_init();
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
//操作系统内核从这里开始执行
|
//操作系统内核从这里开始执行
|
||||||
@ -181,8 +193,9 @@ void Start_Kernel(void)
|
|||||||
mb2_magic &= 0xffffffff;
|
mb2_magic &= 0xffffffff;
|
||||||
multiboot2_magic = (uint)mb2_magic;
|
multiboot2_magic = (uint)mb2_magic;
|
||||||
multiboot2_boot_info_addr = mb2_info + PAGE_OFFSET;
|
multiboot2_boot_info_addr = mb2_info + PAGE_OFFSET;
|
||||||
|
io_mfence();
|
||||||
system_initialize();
|
system_initialize();
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
hlt();
|
hlt();
|
||||||
@ -191,5 +204,7 @@ void Start_Kernel(void)
|
|||||||
void ignore_int()
|
void ignore_int()
|
||||||
{
|
{
|
||||||
kwarn("Unknown interrupt or fault at RIP.\n");
|
kwarn("Unknown interrupt or fault at RIP.\n");
|
||||||
while(1);
|
while (1)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
@ -11,7 +11,10 @@
|
|||||||
static ul Total_Memory = 0;
|
static ul Total_Memory = 0;
|
||||||
static ul total_2M_pages = 0;
|
static ul total_2M_pages = 0;
|
||||||
static ul root_page_table_phys_addr = 0; // 内核层根页表的物理地址
|
static ul root_page_table_phys_addr = 0; // 内核层根页表的物理地址
|
||||||
|
// #pragma GCC push_options
|
||||||
|
// #pragma GCC optimize("O3")
|
||||||
|
|
||||||
|
struct memory_desc memory_management_struct = {{0}, 0};
|
||||||
/**
|
/**
|
||||||
* @brief 虚拟地址长度所需要的entry数量
|
* @brief 虚拟地址长度所需要的entry数量
|
||||||
*
|
*
|
||||||
@ -82,9 +85,10 @@ void mm_init()
|
|||||||
int count;
|
int count;
|
||||||
|
|
||||||
multiboot2_iter(multiboot2_get_memory, mb2_mem_info, &count);
|
multiboot2_iter(multiboot2_get_memory, mb2_mem_info, &count);
|
||||||
|
io_mfence();
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
//可用的内存
|
//可用的内存
|
||||||
if (mb2_mem_info->type == 1)
|
if (mb2_mem_info->type == 1)
|
||||||
Total_Memory += mb2_mem_info->len;
|
Total_Memory += mb2_mem_info->len;
|
||||||
@ -103,12 +107,12 @@ void mm_init()
|
|||||||
printk("[ INFO ] Total amounts of RAM : %ld bytes\n", Total_Memory);
|
printk("[ INFO ] Total amounts of RAM : %ld bytes\n", Total_Memory);
|
||||||
|
|
||||||
// 计算有效内存页数
|
// 计算有效内存页数
|
||||||
|
io_mfence();
|
||||||
for (int i = 0; i < memory_management_struct.len_e820; ++i)
|
for (int i = 0; i < memory_management_struct.len_e820; ++i)
|
||||||
{
|
{
|
||||||
if (memory_management_struct.e820[i].type != 1)
|
if (memory_management_struct.e820[i].type != 1)
|
||||||
continue;
|
continue;
|
||||||
|
io_mfence();
|
||||||
// 将内存段的起始物理地址按照2M进行对齐
|
// 将内存段的起始物理地址按照2M进行对齐
|
||||||
ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr);
|
ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr);
|
||||||
// 将内存段的终止物理地址的低2M区域清空,以实现对齐
|
// 将内存段的终止物理地址的低2M区域清空,以实现对齐
|
||||||
@ -117,7 +121,7 @@ void mm_init()
|
|||||||
// 内存段不可用
|
// 内存段不可用
|
||||||
if (addr_end <= addr_start)
|
if (addr_end <= addr_start)
|
||||||
continue;
|
continue;
|
||||||
|
io_mfence();
|
||||||
total_2M_pages += ((addr_end - addr_start) >> PAGE_2M_SHIFT);
|
total_2M_pages += ((addr_end - addr_start) >> PAGE_2M_SHIFT);
|
||||||
}
|
}
|
||||||
kinfo("Total amounts of 2M pages : %ld.", total_2M_pages);
|
kinfo("Total amounts of 2M pages : %ld.", total_2M_pages);
|
||||||
@ -126,16 +130,18 @@ void mm_init()
|
|||||||
ul max_addr = memory_management_struct.e820[memory_management_struct.len_e820].BaseAddr + memory_management_struct.e820[memory_management_struct.len_e820].Length;
|
ul max_addr = memory_management_struct.e820[memory_management_struct.len_e820].BaseAddr + memory_management_struct.e820[memory_management_struct.len_e820].Length;
|
||||||
// 初始化mms的bitmap
|
// 初始化mms的bitmap
|
||||||
// bmp的指针指向截止位置的4k对齐的上边界(防止修改了别的数据)
|
// bmp的指针指向截止位置的4k对齐的上边界(防止修改了别的数据)
|
||||||
|
io_mfence();
|
||||||
memory_management_struct.bmp = (unsigned long *)((memory_management_struct.start_brk + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
memory_management_struct.bmp = (unsigned long *)((memory_management_struct.start_brk + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
||||||
memory_management_struct.bits_size = max_addr >> PAGE_2M_SHIFT; // 物理地址空间的最大页面数
|
memory_management_struct.bits_size = max_addr >> PAGE_2M_SHIFT; // 物理地址空间的最大页面数
|
||||||
memory_management_struct.bmp_len = (((unsigned long)(max_addr >> PAGE_2M_SHIFT) + sizeof(unsigned long) * 8 - 1) / 8) & (~(sizeof(unsigned long) - 1)); // bmp由多少个unsigned long变量组成
|
memory_management_struct.bmp_len = (((unsigned long)(max_addr >> PAGE_2M_SHIFT) + sizeof(unsigned long) * 8 - 1) / 8) & (~(sizeof(unsigned long) - 1)); // bmp由多少个unsigned long变量组成
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 初始化bitmap, 先将整个bmp空间全部置位。稍后再将可用物理内存页复位。
|
// 初始化bitmap, 先将整个bmp空间全部置位。稍后再将可用物理内存页复位。
|
||||||
memset(memory_management_struct.bmp, 0xff, memory_management_struct.bmp_len);
|
memset(memory_management_struct.bmp, 0xff, memory_management_struct.bmp_len);
|
||||||
|
io_mfence();
|
||||||
|
kdebug("1212112");
|
||||||
// 初始化内存页结构
|
// 初始化内存页结构
|
||||||
// 将页结构映射于bmp之后
|
// 将页结构映射于bmp之后
|
||||||
|
|
||||||
memory_management_struct.pages_struct = (struct Page *)(((unsigned long)memory_management_struct.bmp + memory_management_struct.bmp_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
memory_management_struct.pages_struct = (struct Page *)(((unsigned long)memory_management_struct.bmp + memory_management_struct.bmp_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
||||||
|
|
||||||
memory_management_struct.count_pages = max_addr >> PAGE_2M_SHIFT;
|
memory_management_struct.count_pages = max_addr >> PAGE_2M_SHIFT;
|
||||||
@ -143,18 +149,25 @@ void mm_init()
|
|||||||
// 将pages_struct全部清空,以备后续初始化
|
// 将pages_struct全部清空,以备后续初始化
|
||||||
memset(memory_management_struct.pages_struct, 0x00, memory_management_struct.pages_struct_len); // init pages memory
|
memset(memory_management_struct.pages_struct, 0x00, memory_management_struct.pages_struct_len); // init pages memory
|
||||||
|
|
||||||
|
kdebug("ffff");
|
||||||
|
io_mfence();
|
||||||
// 初始化内存区域
|
// 初始化内存区域
|
||||||
memory_management_struct.zones_struct = (struct Zone *)(((ul)memory_management_struct.pages_struct + memory_management_struct.pages_struct_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
memory_management_struct.zones_struct = (struct Zone *)(((ul)memory_management_struct.pages_struct + memory_management_struct.pages_struct_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
||||||
|
io_mfence();
|
||||||
// 由于暂时无法计算zone结构体的数量,因此先将其设为0
|
// 由于暂时无法计算zone结构体的数量,因此先将其设为0
|
||||||
memory_management_struct.count_zones = 0;
|
memory_management_struct.count_zones = 0;
|
||||||
|
io_mfence();
|
||||||
// zones-struct 成员变量暂时按照5个来计算
|
// zones-struct 成员变量暂时按照5个来计算
|
||||||
memory_management_struct.zones_struct_len = (10 * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
memory_management_struct.zones_struct_len = (10 * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
||||||
|
io_mfence();
|
||||||
memset(memory_management_struct.zones_struct, 0x00, memory_management_struct.zones_struct_len);
|
memset(memory_management_struct.zones_struct, 0x00, memory_management_struct.zones_struct_len);
|
||||||
|
|
||||||
// ==== 遍历e820数组,完成成员变量初始化工作 ===
|
// ==== 遍历e820数组,完成成员变量初始化工作 ===
|
||||||
|
|
||||||
|
kdebug("ddd");
|
||||||
for (int i = 0; i < memory_management_struct.len_e820; ++i)
|
for (int i = 0; i < memory_management_struct.len_e820; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
if (memory_management_struct.e820[i].type != 1) // 不是操作系统可以使用的物理内存
|
if (memory_management_struct.e820[i].type != 1) // 不是操作系统可以使用的物理内存
|
||||||
continue;
|
continue;
|
||||||
ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr);
|
ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr);
|
||||||
@ -200,7 +213,7 @@ void mm_init()
|
|||||||
|
|
||||||
// 初始化0~2MB的物理页
|
// 初始化0~2MB的物理页
|
||||||
// 由于这个区间的内存由多个内存段组成,因此不会被以上代码初始化,需要我们手动配置page[0]。
|
// 由于这个区间的内存由多个内存段组成,因此不会被以上代码初始化,需要我们手动配置page[0]。
|
||||||
|
io_mfence();
|
||||||
memory_management_struct.pages_struct->zone = memory_management_struct.zones_struct;
|
memory_management_struct.pages_struct->zone = memory_management_struct.zones_struct;
|
||||||
memory_management_struct.pages_struct->addr_phys = 0UL;
|
memory_management_struct.pages_struct->addr_phys = 0UL;
|
||||||
set_page_attr(memory_management_struct.pages_struct, PAGE_PGT_MAPPED | PAGE_KERNEL_INIT | PAGE_KERNEL);
|
set_page_attr(memory_management_struct.pages_struct, PAGE_PGT_MAPPED | PAGE_KERNEL_INIT | PAGE_KERNEL);
|
||||||
@ -216,27 +229,13 @@ void mm_init()
|
|||||||
ZONE_NORMAL_INDEX = 0;
|
ZONE_NORMAL_INDEX = 0;
|
||||||
ZONE_UNMAPPED_INDEX = 0;
|
ZONE_UNMAPPED_INDEX = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
for (int i = 0; i < memory_management_struct.count_zones; ++i)
|
|
||||||
{
|
|
||||||
struct Zone *z = memory_management_struct.zones_struct + i;
|
|
||||||
// printk_color(ORANGE, BLACK, "zone_addr_start:%#18lx, zone_addr_end:%#18lx, zone_length:%#18lx, pages_group:%#18lx, count_pages:%#18lx\n",
|
|
||||||
// z->zone_addr_start, z->zone_addr_end, z->zone_length, z->pages_group, z->count_pages);
|
|
||||||
|
|
||||||
// 1GB以上的内存空间不做映射
|
|
||||||
// if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX))
|
|
||||||
// ZONE_UNMAPPED_INDEX = i;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX);
|
// kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX);
|
||||||
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
||||||
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
||||||
|
|
||||||
// printk_color(ORANGE, BLACK, "code_start:%#18lx, code_end:%#18lx, data_end:%#18lx, kernel_end:%#18lx, end_of_struct:%#18lx\n",
|
|
||||||
// memory_management_struct.kernel_code_start, memory_management_struct.kernel_code_end, memory_management_struct.kernel_data_end, memory_management_struct.kernel_end, memory_management_struct.end_of_struct);
|
|
||||||
|
|
||||||
// 初始化内存管理单元结构所占的物理页的结构体
|
// 初始化内存管理单元结构所占的物理页的结构体
|
||||||
|
|
||||||
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
||||||
// kdebug("mms_max_page=%ld", mms_max_page);
|
// kdebug("mms_max_page=%ld", mms_max_page);
|
||||||
|
|
||||||
@ -245,6 +244,7 @@ void mm_init()
|
|||||||
// 第0个page已经在上方配置
|
// 第0个page已经在上方配置
|
||||||
for (ul j = 1; j <= mms_max_page; ++j)
|
for (ul j = 1; j <= mms_max_page; ++j)
|
||||||
{
|
{
|
||||||
|
barrier();
|
||||||
tmp_page = memory_management_struct.pages_struct + j;
|
tmp_page = memory_management_struct.pages_struct + j;
|
||||||
page_init(tmp_page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
|
page_init(tmp_page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
|
||||||
page_num = tmp_page->addr_phys >> PAGE_2M_SHIFT;
|
page_num = tmp_page->addr_phys >> PAGE_2M_SHIFT;
|
||||||
@ -278,6 +278,7 @@ unsigned long page_init(struct Page *page, ul flags)
|
|||||||
if ((!page->ref_counts) || (page->attr & PAGE_SHARED))
|
if ((!page->ref_counts) || (page->attr & PAGE_SHARED))
|
||||||
{
|
{
|
||||||
++page->ref_counts;
|
++page->ref_counts;
|
||||||
|
barrier();
|
||||||
++page->zone->total_pages_link;
|
++page->zone->total_pages_link;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -977,3 +978,4 @@ int8_t mm_is_2M_page(uint64_t paddr)
|
|||||||
return 1;
|
return 1;
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
// #pragma GCC pop_options
|
@ -145,6 +145,7 @@
|
|||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
ul tmp; \
|
ul tmp; \
|
||||||
|
io_mfence();\
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"movq %%cr3, %0\n\t" \
|
"movq %%cr3, %0\n\t" \
|
||||||
"movq %0, %%cr3\n\t" \
|
"movq %0, %%cr3\n\t" \
|
||||||
|
@ -348,9 +348,9 @@ ul slab_init()
|
|||||||
kinfo("Initializing SLAB...");
|
kinfo("Initializing SLAB...");
|
||||||
// 将slab的内存池空间放置在mms的后方
|
// 将slab的内存池空间放置在mms的后方
|
||||||
ul tmp_addr = memory_management_struct.end_of_struct;
|
ul tmp_addr = memory_management_struct.end_of_struct;
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
spin_init(&kmalloc_cache_group[i].lock);
|
spin_init(&kmalloc_cache_group[i].lock);
|
||||||
// 将slab内存池对象的空间放置在mms的后面,并且预留4个unsigned long 的空间以防止内存越界
|
// 将slab内存池对象的空间放置在mms的后面,并且预留4个unsigned long 的空间以防止内存越界
|
||||||
kmalloc_cache_group[i].cache_pool_entry = (struct slab_obj *)memory_management_struct.end_of_struct;
|
kmalloc_cache_group[i].cache_pool_entry = (struct slab_obj *)memory_management_struct.end_of_struct;
|
||||||
@ -370,7 +370,7 @@ ul slab_init()
|
|||||||
|
|
||||||
// bmp后方预留4个unsigned long的空间防止内存越界,且按照8byte进行对齐
|
// bmp后方预留4个unsigned long的空间防止内存越界,且按照8byte进行对齐
|
||||||
memory_management_struct.end_of_struct = (ul)(memory_management_struct.end_of_struct + kmalloc_cache_group[i].cache_pool_entry->bmp_len + (sizeof(ul) << 2)) & (~(sizeof(ul) - 1));
|
memory_management_struct.end_of_struct = (ul)(memory_management_struct.end_of_struct + kmalloc_cache_group[i].cache_pool_entry->bmp_len + (sizeof(ul) << 2)) & (~(sizeof(ul) - 1));
|
||||||
|
io_mfence();
|
||||||
// @todo:此处可优化,直接把所有位设置为0,然后再对部分不存在对应的内存对象的位设置为1
|
// @todo:此处可优化,直接把所有位设置为0,然后再对部分不存在对应的内存对象的位设置为1
|
||||||
memset(kmalloc_cache_group[i].cache_pool_entry->bmp, 0xff, kmalloc_cache_group[i].cache_pool_entry->bmp_len);
|
memset(kmalloc_cache_group[i].cache_pool_entry->bmp, 0xff, kmalloc_cache_group[i].cache_pool_entry->bmp_len);
|
||||||
for (int j = 0; j < kmalloc_cache_group[i].cache_pool_entry->bmp_count; ++j)
|
for (int j = 0; j < kmalloc_cache_group[i].cache_pool_entry->bmp_count; ++j)
|
||||||
@ -378,6 +378,7 @@ ul slab_init()
|
|||||||
|
|
||||||
kmalloc_cache_group[i].count_total_using = 0;
|
kmalloc_cache_group[i].count_total_using = 0;
|
||||||
kmalloc_cache_group[i].count_total_free = kmalloc_cache_group[i].cache_pool_entry->count_free;
|
kmalloc_cache_group[i].count_total_free = kmalloc_cache_group[i].cache_pool_entry->count_free;
|
||||||
|
io_mfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Page *page = NULL;
|
struct Page *page = NULL;
|
||||||
@ -388,13 +389,17 @@ ul slab_init()
|
|||||||
ul page_num = 0;
|
ul page_num = 0;
|
||||||
for (int i = PAGE_2M_ALIGN(virt_2_phys(tmp_addr)) >> PAGE_2M_SHIFT; i <= tmp_page_mms_end; ++i)
|
for (int i = PAGE_2M_ALIGN(virt_2_phys(tmp_addr)) >> PAGE_2M_SHIFT; i <= tmp_page_mms_end; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
page = memory_management_struct.pages_struct + i;
|
page = memory_management_struct.pages_struct + i;
|
||||||
page_num = page->addr_phys >> PAGE_2M_SHIFT;
|
page_num = page->addr_phys >> PAGE_2M_SHIFT;
|
||||||
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
|
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
|
||||||
++page->zone->count_pages_using;
|
++page->zone->count_pages_using;
|
||||||
|
io_mfence();
|
||||||
--page->zone->count_pages_free;
|
--page->zone->count_pages_free;
|
||||||
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
|
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 为slab内存池对象分配内存空间
|
// 为slab内存池对象分配内存空间
|
||||||
ul *virt = NULL;
|
ul *virt = NULL;
|
||||||
@ -406,8 +411,11 @@ ul slab_init()
|
|||||||
page = Virt_To_2M_Page(virt);
|
page = Virt_To_2M_Page(virt);
|
||||||
|
|
||||||
page_num = page->addr_phys >> PAGE_2M_SHIFT;
|
page_num = page->addr_phys >> PAGE_2M_SHIFT;
|
||||||
|
|
||||||
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
|
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
|
||||||
|
|
||||||
++page->zone->count_pages_using;
|
++page->zone->count_pages_using;
|
||||||
|
io_mfence(); // 该位置必须加一个mfence,否则O3优化运行时会报错
|
||||||
--page->zone->count_pages_free;
|
--page->zone->count_pages_free;
|
||||||
page_init(page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
|
page_init(page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
#include <ktest/ktest.h>
|
#include <ktest/ktest.h>
|
||||||
|
|
||||||
|
// #pragma GCC push_options
|
||||||
|
// #pragma GCC optimize("O0")
|
||||||
|
|
||||||
spinlock_t process_global_pid_write_lock; // 增加pid的写锁
|
spinlock_t process_global_pid_write_lock; // 增加pid的写锁
|
||||||
long process_global_pid = 1; // 系统中最大的pid
|
long process_global_pid = 1; // 系统中最大的pid
|
||||||
|
|
||||||
@ -100,6 +103,7 @@ uint64_t process_exit_mm(struct process_control_block *pcb);
|
|||||||
uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start, uint64_t stack_size, struct pt_regs *current_regs);
|
uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start, uint64_t stack_size, struct pt_regs *current_regs);
|
||||||
|
|
||||||
void process_exit_thread(struct process_control_block *pcb);
|
void process_exit_thread(struct process_control_block *pcb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 切换进程
|
* @brief 切换进程
|
||||||
*
|
*
|
||||||
@ -108,7 +112,8 @@ void process_exit_thread(struct process_control_block *pcb);
|
|||||||
* 由于程序在进入内核的时候已经保存了寄存器,因此这里不需要保存寄存器。
|
* 由于程序在进入内核的时候已经保存了寄存器,因此这里不需要保存寄存器。
|
||||||
* 这里切换fs和gs寄存器
|
* 这里切换fs和gs寄存器
|
||||||
*/
|
*/
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
void __switch_to(struct process_control_block *prev, struct process_control_block *next)
|
void __switch_to(struct process_control_block *prev, struct process_control_block *next)
|
||||||
{
|
{
|
||||||
initial_tss[proc_current_cpu_id].rsp0 = next->thread->rbp;
|
initial_tss[proc_current_cpu_id].rsp0 = next->thread->rbp;
|
||||||
@ -124,6 +129,7 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
|
|||||||
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs));
|
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs));
|
||||||
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
|
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打开要执行的程序文件
|
* @brief 打开要执行的程序文件
|
||||||
@ -299,6 +305,8 @@ load_elf_failed:;
|
|||||||
* @param envp 环境变量
|
* @param envp 环境变量
|
||||||
* @return ul 错误码
|
* @return ul 错误码
|
||||||
*/
|
*/
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -403,6 +411,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
|||||||
exec_failed:;
|
exec_failed:;
|
||||||
process_do_exit(tmp);
|
process_do_exit(tmp);
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 内核init进程
|
* @brief 内核init进程
|
||||||
@ -410,6 +419,8 @@ exec_failed:;
|
|||||||
* @param arg
|
* @param arg
|
||||||
* @return ul 参数
|
* @return ul 参数
|
||||||
*/
|
*/
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
ul initial_kernel_thread(ul arg)
|
ul initial_kernel_thread(ul arg)
|
||||||
{
|
{
|
||||||
// kinfo("initial proc running...\targ:%#018lx", arg);
|
// kinfo("initial proc running...\targ:%#018lx", arg);
|
||||||
@ -446,6 +457,7 @@ ul initial_kernel_thread(ul arg)
|
|||||||
current_pcb->thread->rip = (ul)ret_from_system_call;
|
current_pcb->thread->rip = (ul)ret_from_system_call;
|
||||||
current_pcb->thread->rsp = (ul)current_pcb + STACK_SIZE - sizeof(struct pt_regs);
|
current_pcb->thread->rsp = (ul)current_pcb + STACK_SIZE - sizeof(struct pt_regs);
|
||||||
current_pcb->thread->fs = USER_DS | 0x3;
|
current_pcb->thread->fs = USER_DS | 0x3;
|
||||||
|
barrier();
|
||||||
current_pcb->thread->gs = USER_DS | 0x3;
|
current_pcb->thread->gs = USER_DS | 0x3;
|
||||||
|
|
||||||
// 主动放弃内核线程身份
|
// 主动放弃内核线程身份
|
||||||
@ -467,7 +479,7 @@ ul initial_kernel_thread(ul arg)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
||||||
/**
|
/**
|
||||||
* @brief 当子进程退出后向父进程发送通知
|
* @brief 当子进程退出后向父进程发送通知
|
||||||
*
|
*
|
||||||
@ -517,23 +529,29 @@ ul process_do_exit(ul code)
|
|||||||
int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigned long flags)
|
int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigned long flags)
|
||||||
{
|
{
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
|
barrier();
|
||||||
memset(®s, 0, sizeof(regs));
|
memset(®s, 0, sizeof(regs));
|
||||||
|
barrier();
|
||||||
// 在rbx寄存器中保存进程的入口地址
|
// 在rbx寄存器中保存进程的入口地址
|
||||||
regs.rbx = (ul)fn;
|
regs.rbx = (ul)fn;
|
||||||
// 在rdx寄存器中保存传入的参数
|
// 在rdx寄存器中保存传入的参数
|
||||||
regs.rdx = (ul)arg;
|
regs.rdx = (ul)arg;
|
||||||
|
barrier();
|
||||||
regs.ds = KERNEL_DS;
|
regs.ds = KERNEL_DS;
|
||||||
|
barrier();
|
||||||
regs.es = KERNEL_DS;
|
regs.es = KERNEL_DS;
|
||||||
|
barrier();
|
||||||
regs.cs = KERNEL_CS;
|
regs.cs = KERNEL_CS;
|
||||||
|
barrier();
|
||||||
regs.ss = KERNEL_DS;
|
regs.ss = KERNEL_DS;
|
||||||
|
barrier();
|
||||||
|
|
||||||
// 置位中断使能标志位
|
// 置位中断使能标志位
|
||||||
regs.rflags = (1 << 9);
|
regs.rflags = (1 << 9);
|
||||||
|
barrier();
|
||||||
// rip寄存器指向内核线程的引导程序
|
// rip寄存器指向内核线程的引导程序
|
||||||
regs.rip = (ul)kernel_thread_func;
|
regs.rip = (ul)kernel_thread_func;
|
||||||
|
barrier();
|
||||||
// kdebug("kernel_thread_func=%#018lx", kernel_thread_func);
|
// kdebug("kernel_thread_func=%#018lx", kernel_thread_func);
|
||||||
// kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func);
|
// kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func);
|
||||||
// kdebug("1111\tregs.rip = %#018lx", regs.rip);
|
// kdebug("1111\tregs.rip = %#018lx", regs.rip);
|
||||||
@ -577,23 +595,34 @@ void process_init()
|
|||||||
for (int i = 256; i < 512; ++i)
|
for (int i = 256; i < 512; ++i)
|
||||||
{
|
{
|
||||||
uint64_t *tmp = idle_pml4t_vaddr + i;
|
uint64_t *tmp = idle_pml4t_vaddr + i;
|
||||||
|
barrier();
|
||||||
if (*tmp == 0)
|
if (*tmp == 0)
|
||||||
{
|
{
|
||||||
void *pdpt = kmalloc(PAGE_4K_SIZE, 0);
|
void *pdpt = kmalloc(PAGE_4K_SIZE, 0);
|
||||||
|
barrier();
|
||||||
memset(pdpt, 0, PAGE_4K_SIZE);
|
memset(pdpt, 0, PAGE_4K_SIZE);
|
||||||
|
barrier();
|
||||||
set_pml4t(tmp, mk_pml4t(virt_2_phys(pdpt), PAGE_KERNEL_PGT));
|
set_pml4t(tmp, mk_pml4t(virt_2_phys(pdpt), PAGE_KERNEL_PGT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
barrier();
|
||||||
|
|
||||||
|
flush_tlb();
|
||||||
/*
|
/*
|
||||||
kdebug("initial_thread.rbp=%#018lx", initial_thread.rbp);
|
kdebug("initial_thread.rbp=%#018lx", initial_thread.rbp);
|
||||||
kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
|
kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
|
||||||
kdebug("initial_tss[0].ist1=%#018lx", initial_tss[0].ist1);
|
kdebug("initial_tss[0].ist1=%#018lx", initial_tss[0].ist1);
|
||||||
*/
|
*/
|
||||||
// 初始化pid的写锁
|
// 初始化pid的写锁
|
||||||
|
|
||||||
spin_init(&process_global_pid_write_lock);
|
spin_init(&process_global_pid_write_lock);
|
||||||
|
|
||||||
// 初始化进程的循环链表
|
// 初始化进程的循环链表
|
||||||
list_init(&initial_proc_union.pcb.list);
|
list_init(&initial_proc_union.pcb.list);
|
||||||
|
barrier();
|
||||||
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核线程
|
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核线程
|
||||||
|
barrier();
|
||||||
|
|
||||||
initial_proc_union.pcb.state = PROC_RUNNING;
|
initial_proc_union.pcb.state = PROC_RUNNING;
|
||||||
initial_proc_union.pcb.preempt_count = 0;
|
initial_proc_union.pcb.preempt_count = 0;
|
||||||
initial_proc_union.pcb.cpu_id = 0;
|
initial_proc_union.pcb.cpu_id = 0;
|
||||||
@ -617,6 +646,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
|
|
||||||
// 为新的进程分配栈空间,并将pcb放置在底部
|
// 为新的进程分配栈空间,并将pcb放置在底部
|
||||||
tsk = (struct process_control_block *)kmalloc(STACK_SIZE, 0);
|
tsk = (struct process_control_block *)kmalloc(STACK_SIZE, 0);
|
||||||
|
barrier();
|
||||||
|
|
||||||
if (tsk == NULL)
|
if (tsk == NULL)
|
||||||
{
|
{
|
||||||
@ -624,13 +654,17 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barrier();
|
||||||
memset(tsk, 0, sizeof(struct process_control_block));
|
memset(tsk, 0, sizeof(struct process_control_block));
|
||||||
|
io_mfence();
|
||||||
// 将当前进程的pcb复制到新的pcb内
|
// 将当前进程的pcb复制到新的pcb内
|
||||||
memcpy(tsk, current_pcb, sizeof(struct process_control_block));
|
memcpy(tsk, current_pcb, sizeof(struct process_control_block));
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 初始化进程的循环链表结点
|
// 初始化进程的循环链表结点
|
||||||
list_init(&tsk->list);
|
list_init(&tsk->list);
|
||||||
|
|
||||||
|
io_mfence();
|
||||||
// 判断是否为内核态调用fork
|
// 判断是否为内核态调用fork
|
||||||
if (current_pcb->flags & PF_KTHREAD && stack_start != 0)
|
if (current_pcb->flags & PF_KTHREAD && stack_start != 0)
|
||||||
tsk->flags |= PF_KFORK;
|
tsk->flags |= PF_KFORK;
|
||||||
@ -641,11 +675,14 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
// 增加全局的pid并赋值给新进程的pid
|
// 增加全局的pid并赋值给新进程的pid
|
||||||
spin_lock(&process_global_pid_write_lock);
|
spin_lock(&process_global_pid_write_lock);
|
||||||
tsk->pid = process_global_pid++;
|
tsk->pid = process_global_pid++;
|
||||||
|
barrier();
|
||||||
// 加入到进程链表中
|
// 加入到进程链表中
|
||||||
tsk->next_pcb = initial_proc_union.pcb.next_pcb;
|
tsk->next_pcb = initial_proc_union.pcb.next_pcb;
|
||||||
|
barrier();
|
||||||
initial_proc_union.pcb.next_pcb = tsk;
|
initial_proc_union.pcb.next_pcb = tsk;
|
||||||
|
barrier();
|
||||||
tsk->parent_pcb = current_pcb;
|
tsk->parent_pcb = current_pcb;
|
||||||
|
barrier();
|
||||||
|
|
||||||
spin_unlock(&process_global_pid_write_lock);
|
spin_unlock(&process_global_pid_write_lock);
|
||||||
|
|
||||||
@ -654,7 +691,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
|
|
||||||
tsk->parent_pcb = current_pcb;
|
tsk->parent_pcb = current_pcb;
|
||||||
wait_queue_init(&tsk->wait_child_proc_exit, NULL);
|
wait_queue_init(&tsk->wait_child_proc_exit, NULL);
|
||||||
|
barrier();
|
||||||
list_init(&tsk->list);
|
list_init(&tsk->list);
|
||||||
|
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
@ -1047,6 +1084,7 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
|
|||||||
|
|
||||||
child_regs = (struct pt_regs *)(((uint64_t)pcb) + STACK_SIZE - size);
|
child_regs = (struct pt_regs *)(((uint64_t)pcb) + STACK_SIZE - size);
|
||||||
memcpy(child_regs, (void *)current_regs, size);
|
memcpy(child_regs, (void *)current_regs, size);
|
||||||
|
barrier();
|
||||||
// 然后重写新的栈中,每个栈帧的rbp值
|
// 然后重写新的栈中,每个栈帧的rbp值
|
||||||
process_rewrite_rbp(child_regs, pcb);
|
process_rewrite_rbp(child_regs, pcb);
|
||||||
}
|
}
|
||||||
@ -1054,6 +1092,7 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
|
|||||||
{
|
{
|
||||||
child_regs = (struct pt_regs *)((uint64_t)pcb + STACK_SIZE - sizeof(struct pt_regs));
|
child_regs = (struct pt_regs *)((uint64_t)pcb + STACK_SIZE - sizeof(struct pt_regs));
|
||||||
memcpy(child_regs, current_regs, sizeof(struct pt_regs));
|
memcpy(child_regs, current_regs, sizeof(struct pt_regs));
|
||||||
|
barrier();
|
||||||
child_regs->rsp = stack_start;
|
child_regs->rsp = stack_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,3 +1127,5 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
|
|||||||
void process_exit_thread(struct process_control_block *pcb)
|
void process_exit_thread(struct process_control_block *pcb)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #pragma GCC pop_options
|
@ -9,7 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <common/cpu.h>
|
#include <common/cpu.h>
|
||||||
#include <common/glib.h>
|
#include <common/glib.h>
|
||||||
#include <mm/mm.h>
|
#include <mm/mm.h>
|
||||||
@ -19,6 +18,8 @@
|
|||||||
#include <filesystem/VFS/VFS.h>
|
#include <filesystem/VFS/VFS.h>
|
||||||
#include <common/wait_queue.h>
|
#include <common/wait_queue.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 进程最大可拥有的文件描述符数量
|
// 进程最大可拥有的文件描述符数量
|
||||||
#define PROC_MAX_FD_NUM 16
|
#define PROC_MAX_FD_NUM 16
|
||||||
|
|
||||||
@ -213,17 +214,21 @@ struct tss_struct
|
|||||||
.io_map_base_addr = 0 \
|
.io_map_base_addr = 0 \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
// 获取当前的pcb
|
// 获取当前的pcb
|
||||||
struct process_control_block *get_current_pcb()
|
struct process_control_block *get_current_pcb()
|
||||||
{
|
{
|
||||||
struct process_control_block *current = NULL;
|
struct process_control_block *current = NULL;
|
||||||
// 利用了当前pcb和栈空间总大小为32k大小对齐,将rsp低15位清空,即可获得pcb的起始地址
|
// 利用了当前pcb和栈空间总大小为32k大小对齐,将rsp低15位清空,即可获得pcb的起始地址
|
||||||
|
barrier();
|
||||||
__asm__ __volatile__("andq %%rsp, %0 \n\t"
|
__asm__ __volatile__("andq %%rsp, %0 \n\t"
|
||||||
: "=r"(current)
|
: "=r"(current)
|
||||||
: "0"(~32767UL));
|
: "0"(~32767UL));
|
||||||
|
barrier();
|
||||||
return current;
|
return current;
|
||||||
};
|
};
|
||||||
|
#pragma GCC pop_options
|
||||||
#define current_pcb get_current_pcb()
|
#define current_pcb get_current_pcb()
|
||||||
|
|
||||||
#define GET_CURRENT_PCB \
|
#define GET_CURRENT_PCB \
|
||||||
@ -350,7 +355,7 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne
|
|||||||
asm volatile("movq %0, %%cr3 \n\t" ::"r"(next_pcb->mm->pgd) \
|
asm volatile("movq %0, %%cr3 \n\t" ::"r"(next_pcb->mm->pgd) \
|
||||||
: "memory"); \
|
: "memory"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
// flush_tlb(); \
|
// flush_tlb();
|
||||||
|
|
||||||
// 获取当前cpu id
|
// 获取当前cpu id
|
||||||
#define proc_current_cpu_id (current_pcb->cpu_id)
|
#define proc_current_cpu_id (current_pcb->cpu_id)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <driver/video/video.h>
|
#include <driver/video/video.h>
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
|
|
||||||
|
|
||||||
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,3 +46,4 @@ void sched_init();
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void sched_update_jiffies();
|
void sched_update_jiffies();
|
||||||
|
|
||||||
|
@ -30,43 +30,51 @@ void smp_init()
|
|||||||
|
|
||||||
// kdebug("processor num=%d", total_processor_num);
|
// kdebug("processor num=%d", total_processor_num);
|
||||||
for (int i = 0; i < total_processor_num; ++i)
|
for (int i = 0; i < total_processor_num; ++i)
|
||||||
|
{
|
||||||
|
io_mfence();
|
||||||
proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
|
proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
//*(uchar *)0x20000 = 0xf4; // 在内存的0x20000处写入HLT指令(AP处理器会执行物理地址0x20000的代码)
|
//*(uchar *)0x20000 = 0xf4; // 在内存的0x20000处写入HLT指令(AP处理器会执行物理地址0x20000的代码)
|
||||||
// 将引导程序复制到物理地址0x20000处
|
// 将引导程序复制到物理地址0x20000处
|
||||||
memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
|
memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
|
||||||
|
io_mfence();
|
||||||
// 设置多核IPI中断门
|
// 设置多核IPI中断门
|
||||||
for (int i = 200; i < 210; ++i)
|
for (int i = 200; i < 210; ++i)
|
||||||
set_intr_gate(i, 0, SMP_interrupt_table[i - 200]);
|
set_intr_gate(i, 0, SMP_interrupt_table[i - 200]);
|
||||||
|
|
||||||
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
||||||
|
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 注册接收bsp处理器的hpet中断转发的处理函数
|
// 注册接收bsp处理器的hpet中断转发的处理函数
|
||||||
ipi_regiserIPI(0xc8, NULL, &ipi_0xc8_handler, NULL, NULL, "IPI 0xc8");
|
ipi_regiserIPI(0xc8, NULL, &ipi_0xc8_handler, NULL, NULL, "IPI 0xc8");
|
||||||
|
io_mfence();
|
||||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x00, ICR_INIT, ICR_ALL_EXCLUDE_Self, true, 0x00);
|
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x00, ICR_INIT, ICR_ALL_EXCLUDE_Self, true, 0x00);
|
||||||
kdebug("total_processor_num=%d", total_processor_num);
|
kdebug("total_processor_num=%d", total_processor_num);
|
||||||
for (int i = 1; i < total_processor_num; ++i) // i从1开始,不初始化bsp
|
for (int i = 1; i < total_processor_num; ++i) // i从1开始,不初始化bsp
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
if (proc_local_apic_structs[i]->ACPI_Processor_UID == 0)
|
if (proc_local_apic_structs[i]->ACPI_Processor_UID == 0)
|
||||||
--total_processor_num;
|
--total_processor_num;
|
||||||
|
io_mfence();
|
||||||
if (proc_local_apic_structs[i]->local_apic_id > total_processor_num)
|
if (proc_local_apic_structs[i]->local_apic_id > total_processor_num)
|
||||||
{
|
{
|
||||||
--total_processor_num;
|
--total_processor_num;
|
||||||
continue;}
|
continue;
|
||||||
|
}
|
||||||
kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id, proc_local_apic_structs[i]->flags);
|
kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id, proc_local_apic_structs[i]->flags);
|
||||||
|
io_mfence();
|
||||||
spin_lock(&multi_core_starting_lock);
|
spin_lock(&multi_core_starting_lock);
|
||||||
preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count
|
preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count
|
||||||
current_starting_cpu = proc_local_apic_structs[i]->local_apic_id;
|
current_starting_cpu = proc_local_apic_structs[i]->local_apic_id;
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 为每个AP处理器分配栈空间
|
// 为每个AP处理器分配栈空间
|
||||||
cpu_core_info[current_starting_cpu].stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
|
cpu_core_info[current_starting_cpu].stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
|
||||||
cpu_core_info[current_starting_cpu].ist_stack_start = (uint64_t)(kmalloc(STACK_SIZE, 0)) + STACK_SIZE;
|
cpu_core_info[current_starting_cpu].ist_stack_start = (uint64_t)(kmalloc(STACK_SIZE, 0)) + STACK_SIZE;
|
||||||
|
io_mfence();
|
||||||
memset((void *)cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE, 0, STACK_SIZE);
|
memset((void *)cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE, 0, STACK_SIZE);
|
||||||
memset((void *)cpu_core_info[current_starting_cpu].ist_stack_start - STACK_SIZE, 0, STACK_SIZE);
|
memset((void *)cpu_core_info[current_starting_cpu].ist_stack_start - STACK_SIZE, 0, STACK_SIZE);
|
||||||
|
io_mfence();
|
||||||
|
|
||||||
// 设置ap处理器的中断栈及内核栈中的cpu_id
|
// 设置ap处理器的中断栈及内核栈中的cpu_id
|
||||||
((struct process_control_block *)(cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE))->cpu_id = proc_local_apic_structs[i]->local_apic_id;
|
((struct process_control_block *)(cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE))->cpu_id = proc_local_apic_structs[i]->local_apic_id;
|
||||||
@ -77,18 +85,18 @@ void smp_init()
|
|||||||
memset(&initial_tss[current_starting_cpu], 0, sizeof(struct tss_struct));
|
memset(&initial_tss[current_starting_cpu], 0, sizeof(struct tss_struct));
|
||||||
|
|
||||||
set_tss_descriptor(10 + (current_starting_cpu * 2), (void *)(cpu_core_info[current_starting_cpu].tss_vaddr));
|
set_tss_descriptor(10 + (current_starting_cpu * 2), (void *)(cpu_core_info[current_starting_cpu].tss_vaddr));
|
||||||
|
io_mfence();
|
||||||
set_tss64((uint *)cpu_core_info[current_starting_cpu].tss_vaddr, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start,
|
set_tss64((uint *)cpu_core_info[current_starting_cpu].tss_vaddr, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start,
|
||||||
cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start);
|
cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start);
|
||||||
|
io_mfence();
|
||||||
// 连续发送两次start-up IPI
|
// 连续发送两次start-up IPI
|
||||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->local_apic_id);
|
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->local_apic_id);
|
||||||
|
io_mfence();
|
||||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->local_apic_id);
|
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->local_apic_id);
|
||||||
}
|
}
|
||||||
|
io_mfence();
|
||||||
while (num_cpu_started != total_processor_num)
|
while (num_cpu_started != total_processor_num)
|
||||||
__asm__ __volatile__("pause" ::
|
pause();
|
||||||
: "memory");
|
|
||||||
|
|
||||||
kinfo("Cleaning page table remapping...\n");
|
kinfo("Cleaning page table remapping...\n");
|
||||||
|
|
||||||
@ -96,6 +104,7 @@ void smp_init()
|
|||||||
uint64_t *global_CR3 = get_CR3();
|
uint64_t *global_CR3 = get_CR3();
|
||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i)
|
||||||
{
|
{
|
||||||
|
io_mfence();
|
||||||
*(ul *)(phys_2_virt(global_CR3) + i) = 0UL;
|
*(ul *)(phys_2_virt(global_CR3) + i) = 0UL;
|
||||||
}
|
}
|
||||||
kdebug("init proc's preempt_count=%ld", current_pcb->preempt_count);
|
kdebug("init proc's preempt_count=%ld", current_pcb->preempt_count);
|
||||||
@ -121,7 +130,7 @@ void smp_ap_start()
|
|||||||
__asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(stack_start)
|
__asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(stack_start)
|
||||||
: "memory");*/
|
: "memory");*/
|
||||||
ksuccess("AP core successfully started!");
|
ksuccess("AP core successfully started!");
|
||||||
|
io_mfence();
|
||||||
++num_cpu_started;
|
++num_cpu_started;
|
||||||
|
|
||||||
kdebug("current cpu = %d", current_starting_cpu);
|
kdebug("current cpu = %d", current_starting_cpu);
|
||||||
@ -155,6 +164,7 @@ void smp_ap_start()
|
|||||||
// kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
|
// kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
|
||||||
spin_unlock(&multi_core_starting_lock);
|
spin_unlock(&multi_core_starting_lock);
|
||||||
preempt_disable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count
|
preempt_disable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count
|
||||||
|
io_mfence();
|
||||||
sti();
|
sti();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -22,9 +22,18 @@ extern uint64_t sys_clock(struct pt_regs *regs);
|
|||||||
* @brief 导出系统调用处理函数的符号
|
* @brief 导出系统调用处理函数的符号
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define SYSCALL_COMMON(syscall_num, symbol) extern unsigned long symbol(struct pt_regs *regs);
|
|
||||||
SYSCALL_COMMON(0, system_call_not_exists); // 导出system_call_not_exists函数
|
/**
|
||||||
#undef SYSCALL_COMMON // 取消前述宏定义
|
* @brief 系统调用不存在时的处理函数
|
||||||
|
*
|
||||||
|
* @param regs 进程3特权级下的寄存器
|
||||||
|
* @return ul
|
||||||
|
*/
|
||||||
|
ul system_call_not_exists(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
kerror("System call [ ID #%d ] not exists.", regs->rax);
|
||||||
|
return ESYSCALL_NOT_EXISTS;
|
||||||
|
} // 取消前述宏定义
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 重新定义为:把系统调用函数加入系统调用表
|
* @brief 重新定义为:把系统调用函数加入系统调用表
|
||||||
|
@ -36,11 +36,7 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg
|
|||||||
* @param regs 进程3特权级下的寄存器
|
* @param regs 进程3特权级下的寄存器
|
||||||
* @return ul
|
* @return ul
|
||||||
*/
|
*/
|
||||||
ul system_call_not_exists(struct pt_regs *regs)
|
ul system_call_not_exists(struct pt_regs *regs);
|
||||||
{
|
|
||||||
kerror("System call [ ID #%d ] not exists.", regs->rax);
|
|
||||||
return ESYSCALL_NOT_EXISTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打印字符串的系统调用
|
* @brief 打印字符串的系统调用
|
||||||
|
9
tools/batch_delete_loop.py
Normal file
9
tools/batch_delete_loop.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
start = int(input("Start from: "))
|
||||||
|
end = int(input("End at: "))
|
||||||
|
|
||||||
|
for i in range(start, end+1):
|
||||||
|
print("Deleting: " + str(i))
|
||||||
|
os.system("sudo losetup -d /dev/loop" + str(i))
|
||||||
|
print("Done!")
|
Loading…
x
Reference in New Issue
Block a user