mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 14:16:33 +00:00
将内核层空间移动到0xffff800000000000
This commit is contained in:
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)))
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user