将内核层空间移动到0xffff800000000000

This commit is contained in:
fslongjin
2022-04-09 21:11:07 +08:00
parent 24b351c9ec
commit 05dc7ac73b
14 changed files with 321 additions and 175 deletions

View File

@ -7,6 +7,7 @@ struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES];
uint32_t count_ahci_devices = 0;
uint64_t ahci_port_base_vaddr; // 端口映射base addr
uint64_t ahci_port_base_phys_addr; // 端口映射的物理基地址ahci控制器的参数的地址都是物理地址
static void start_cmd(HBA_PORT *port);
static void stop_cmd(HBA_PORT *port);
@ -24,21 +25,24 @@ static int ahci_find_cmdslot(HBA_PORT *port);
*/
void ahci_init()
{
kinfo("Initializing AHCI...");
pci_get_device_structure(0x1, 0x6, ahci_devs, &count_ahci_devices);
// 映射ABAR
mm_map_phys_addr(AHCI_MAPPING_BASE, ((ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5)) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
//kdebug("ABAR mapped!");
// kdebug("ABAR mapped!");
for (int i = 0; i < count_ahci_devices; ++i)
{
//kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
// 赋值HBA_MEM结构体
// kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
// 赋值HBA_MEM结构体
ahci_devices[i].dev_struct = ahci_devs[i];
ahci_devices[i].hba_mem = (HBA_MEM *)(cal_HBA_MEM_VIRT_ADDR(i));
kdebug("ahci_devices[i].hba_mem = %#018lx", (ul)ahci_devices[i].hba_mem);
}
// todo: 支持多个ahci控制器。
ahci_port_base_vaddr = (uint64_t)kmalloc(1048576, 0);
kdebug("ahci_port_base_vaddr=%#018lx", ahci_port_base_vaddr);
ahci_probe_port(0);
port_rebase(&ahci_devices[0].hba_mem->ports[0], 0);
@ -118,7 +122,7 @@ static void ahci_probe_port(const uint32_t device_num)
static void start_cmd(HBA_PORT *port)
{
// Wait until CR (bit15) is cleared
while (port->cmd & HBA_PxCMD_CR)
while ((port->cmd) & HBA_PxCMD_CR)
;
// Set FRE (bit4) and ST (bit0)
@ -160,29 +164,29 @@ static void port_rebase(HBA_PORT *port, int portno)
// Command list entry maxim count = 32
// Command list maxim size = 32*32 = 1K per port
port->clb = ahci_port_base_vaddr + (portno << 10);
port->clb = virt_2_phys(ahci_port_base_vaddr + (portno << 10));
memset((void *)(port->clb), 0, 1024);
memset((void *)(phys_2_virt(port->clb)), 0, 1024);
// FIS offset: 32K+256*portno
// FIS entry size = 256 bytes per port
port->fb = ahci_port_base_vaddr + (32 << 10) + (portno << 8);
port->fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (portno << 8));
memset((void *)(port->fb), 0, 256);
memset((void *)(phys_2_virt(port->fb)), 0, 256);
// Command table offset: 40K + 8K*portno
// Command table size = 256*32 = 8K per port
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)(port->clb);
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)(phys_2_virt(port->clb));
for (int i = 0; i < 32; ++i)
{
cmdheader[i].prdtl = 8; // 8 prdt entries per command table
// 256 bytes per command table, 64+16+48+16*8
// Command table offset: 40K + 8K*portno + cmdheader_index*256
cmdheader[i].ctba = ahci_port_base_vaddr + (40 << 10) + (portno << 13) + (i << 8);
cmdheader[i].ctba = virt_2_phys((ahci_port_base_vaddr + (40 << 10) + (portno << 13) + (i << 8)));
memset((void *)cmdheader[i].ctba, 0, 256);
memset((void *)phys_2_virt(cmdheader[i].ctba), 0, 256);
}
start_cmd(port); // Start command engine
}
@ -206,20 +210,20 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
if (slot == -1)
return E_NOEMPTYSLOT;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)phys_2_virt(port->clb);
cmdheader += slot;
cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
cmdheader->w = 0; // Read from device
cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)phys_2_virt(cmdheader->ctba);
memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
// 8K bytes (16 sectors) per PRDT
int i;
for (i = 0; i < cmdheader->prdtl - 1; ++i)
{
cmdtbl->prdt_entry[i].dba = buf;
cmdtbl->prdt_entry[i].dba = virt_2_phys(buf);
cmdtbl->prdt_entry[i].dbc = 8 * 1024 - 1; // 8K bytes (this value should always be set to 1 less than the actual value)
cmdtbl->prdt_entry[i].i = 1;
buf += 4 * 1024; // 4K uint16_ts
@ -227,7 +231,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
}
// Last entry
cmdtbl->prdt_entry[i].dba = buf;
cmdtbl->prdt_entry[i].dba = virt_2_phys(buf);
cmdtbl->prdt_entry[i].dbc = (count << 9) - 1; // 512 bytes per sector
cmdtbl->prdt_entry[i].i = 1;
@ -296,7 +300,7 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
if (slot == -1)
return E_NOEMPTYSLOT;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)phys_2_virt(port->clb);
cmdheader += slot;
cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
@ -305,7 +309,7 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
cmdheader->p = 1;
cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)phys_2_virt(cmdheader->ctba);
memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
int i = 0;
@ -438,7 +442,7 @@ static void ahci_end_request()
ahci_req_queue.in_service = NULL;
// 进行下一轮的磁盘请求 由于未实现单独的io调度器这里会造成长时间的io等待
if (ahci_req_queue.request_count>0)
if (ahci_req_queue.request_count > 0)
ahci_query_disk();
}

View File

@ -7,6 +7,8 @@
#include "../../acpi/acpi.h"
#include <exception/softirq.h>
#include <process/process.h>
#include <sched/sched.h>
// 导出定义在irq.c中的中段门表
extern void (*interrupt_table[24])(void);
@ -472,6 +474,11 @@ void do_IRQ(struct pt_regs *rsp, ul number)
// 检测是否有未处理的软中断
if (softirq_status != 0)
do_softirq();
// 检测当前进程是否可被调度
struct process_control_block *current_proc = get_current_pcb();
if (current_proc->flags & PROC_NEED_SCHED)
sched_cfs();
}
/**

View File

@ -3,18 +3,18 @@
#include "../../common/glib.h"
#include "../../common/kprint.h"
uintptr_t boot_info_addr;
uintptr_t multiboot2_boot_info_addr;
unsigned int multiboot2_magic;
unsigned int boot_info_size;
unsigned int multiboot2_boot_info_size;
bool multiboot2_init(void)
{
uintptr_t *addr = (uintptr_t *)boot_info_addr;
uintptr_t *addr = (uintptr_t *)multiboot2_boot_info_addr;
if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
;
return false;
// addr+0 处保存了大小
boot_info_size = *(unsigned int *)addr;
multiboot2_boot_info_size = *(unsigned int *)addr;
return true;
}
@ -22,9 +22,9 @@ void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned i
void *data, unsigned int *count)
{
uintptr_t addr = boot_info_addr;
// 下一字节开始为 tag 信息
struct iter_data_t *tag = (struct iter_data_t *)(addr + 8);
uintptr_t addr = multiboot2_boot_info_addr;
// 接下来的第8字节开始为 tag 信息
struct iter_data_t *tag = (struct iter_data_t *)((void*)addr + 8);
for (; tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
{

View File

@ -27,6 +27,7 @@
*/
extern unsigned int multiboot2_magic;
extern uintptr_t multiboot2_boot_info_addr;
/* How many bytes from the start of the file we search for the header. */
static const unsigned int MULTIBOOT_SEARCH = 32768;

View File

@ -4,6 +4,8 @@
#include <driver/interrupt/apic/apic.h>
#include <exception/softirq.h>
#include <driver/timers/timer.h>
#include <process/process.h>
#include <sched/sched.h>
static struct acpi_HPET_description_table_t *hpet_table;
static uint64_t HPET_REG_BASE = 0;
@ -52,8 +54,27 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
{
case 0: // 定时器0中断
++timer_jiffies;
if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies) // 若当前时间比定时任务的时间间隔大,则进入中断下半部
// 若当前时间比定时任务的时间间隔大,则进入中断下半部
if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies)
set_softirq_status(TIMER_SIRQ);
/*
switch (current_pcb->priority)
{
case 0:
case 1:
--sched_cfs_ready_queue.cpu_exec_proc_jiffies;
++current_pcb->virtual_runtime;
break;
case 2:
default:
sched_cfs_ready_queue.cpu_exec_proc_jiffies -= 2;
current_pcb->virtual_runtime += 2;
break;
}
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
current_pcb->flags |= PROC_NEED_SCHED;
*/
break;
default:
@ -75,15 +96,16 @@ int HPET_init()
hpet_table = (struct acpi_HPET_description_table_t *)hpet_table_addr;
// 由于这段内存与io/apic的映射在同一物理页内因此不需要重复映射
HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + hpet_table->address;
// 读取计时精度并计算频率
uint64_t tmp;
tmp = *(uint64_t *)(HPET_REG_BASE + GCAP_ID);
HPET_COUNTER_CLK_PERIOD = (tmp >> 32) & 0xffffffff;
HPET_freq = 1.0 * 1e15 / HPET_COUNTER_CLK_PERIOD;
HPET_NUM_TIM_CAP = (tmp >> 8) & 0x1f; // 读取计时器数量
kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, HPET_freq);
double x = 1*2;
x = 1.0*3.65;
//kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, (double)HPET_freq);
struct apic_IO_APIC_RTE_entry entry;
// 使用I/O APIC 的IRQ2接收hpet定时器0的中断
apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0);