simple bga ok
This commit is contained in:
parent
58d6a5c65f
commit
7645cffff8
12
include/bga.h
Normal file
12
include/bga.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "pci.h"
|
||||
#include "type.h"
|
||||
|
||||
#define BGA_SWAP_BUFFERS 0x0101
|
||||
#define BGA_GET_HEIGHT 0x0102
|
||||
#define BGA_GET_WIDTH 0x0103
|
||||
#define BGA_GET_SCALE 0x0104
|
||||
#define BGA_DISABLE 0x0105
|
||||
|
||||
int bga_init_with_dev(pci_dev_t* dev);
|
||||
int bga_ioctl(uintptr_t cmd, uintptr_t arg);
|
||||
@ -45,6 +45,8 @@ enum DEVICES_TYPE {
|
||||
uint32_t pci_read(uint16_t bus, uint16_t device, uint16_t function, uint32_t offset);
|
||||
void pci_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t data);
|
||||
pci_dev_t pci_get_device_desriptor(uint8_t bus, uint8_t device, uint8_t function);
|
||||
pci_dev_t* get_pci_bga();
|
||||
uint32_t pci_read_bar(pci_dev_t* pci_dev, int bar_id);
|
||||
|
||||
#define NR_PCI_DEV 8
|
||||
|
||||
|
||||
@ -134,6 +134,7 @@ void write_page_pde(u32 PageDirPhyAddr, u32 AddrLin, u32 TblPhyAddr, u32 Attribu
|
||||
void write_page_pte(u32 TblPhyAddr, u32 AddrLin, u32 PhyAddr, u32 Attribute);
|
||||
u32 vmalloc(u32 size);
|
||||
int lin_mapping_phy(u32 AddrLin, u32 phy_addr, u32 pid, u32 pde_Attribute, u32 pte_Attribute); // edit by visual 2016.5.19
|
||||
int klin_mapping_phy(u32 AddrLin, u32 phy_addr, u32 pde_Attribute, u32 pte_Attribute); // edit by visual 2016.5.19
|
||||
void clear_kernel_pagepte_low(); // add by visual 2016.5.12
|
||||
|
||||
/* add by catfood */
|
||||
|
||||
@ -187,6 +187,14 @@ read_esp(void)
|
||||
return esp;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
read_cr3(void)
|
||||
{
|
||||
u32 cr3;
|
||||
asm volatile("movl %%cr3,%0" : "=r" (cr3));
|
||||
return cr3;
|
||||
}
|
||||
|
||||
static inline u64
|
||||
read_tsc(void)
|
||||
{
|
||||
|
||||
@ -33,6 +33,7 @@ KERN_SRCFILES :=kernel/kernel.asm \
|
||||
kernel/serialport.c \
|
||||
kernel/vga.c \
|
||||
kernel/pci.c \
|
||||
kernel/bga.c \
|
||||
lib/klib.c \
|
||||
|
||||
|
||||
|
||||
140
kernel/bga.c
Normal file
140
kernel/bga.c
Normal file
@ -0,0 +1,140 @@
|
||||
#include "type.h"
|
||||
#include "assert.h"
|
||||
#include "console.h"
|
||||
#include "const.h"
|
||||
#include "keyboard.h"
|
||||
#include "memman.h"
|
||||
#include "proc.h"
|
||||
#include "protect.h"
|
||||
#include "proto.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "x86.h"
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "pci.h"
|
||||
#include "bga.h"
|
||||
|
||||
#define VBE_DISPI_IOPORT_INDEX 0x01CE
|
||||
#define VBE_DISPI_IOPORT_DATA 0x01CF
|
||||
|
||||
#define VBE_DISPI_INDEX_ID 0x0
|
||||
#define VBE_DISPI_INDEX_XRES 0x1
|
||||
#define VBE_DISPI_INDEX_YRES 0x2
|
||||
#define VBE_DISPI_INDEX_BPP 0x3
|
||||
#define VBE_DISPI_INDEX_ENABLE 0x4
|
||||
#define VBE_DISPI_INDEX_BANK 0x5
|
||||
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
|
||||
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
|
||||
#define VBE_DISPI_INDEX_X_OFFSET 0x8
|
||||
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
|
||||
|
||||
#define VBE_DISPI_DISABLED 0x00
|
||||
#define VBE_DISPI_ENABLED 0x01
|
||||
#define VBE_DISPI_LFB_ENABLED 0x40
|
||||
|
||||
static uint16_t bga_screen_width, bga_screen_height;
|
||||
static uint32_t bga_screen_line_size, bga_screen_buffer_size;
|
||||
static uint32_t bga_buf_paddr;
|
||||
|
||||
static inline void _bga_write_reg(uint16_t cmd, uint16_t data)
|
||||
{
|
||||
outw(VBE_DISPI_IOPORT_INDEX, cmd);
|
||||
outw(VBE_DISPI_IOPORT_DATA, data);
|
||||
}
|
||||
|
||||
static inline uint16_t _bga_read_reg(uint16_t cmd)
|
||||
{
|
||||
outw(VBE_DISPI_IOPORT_INDEX, cmd);
|
||||
return inw(VBE_DISPI_IOPORT_DATA);
|
||||
}
|
||||
|
||||
static void _bga_set_resolution(uint16_t width, uint16_t height)
|
||||
{
|
||||
_bga_write_reg(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_XRES, width);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_YRES, height);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_VIRT_WIDTH, width);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_VIRT_HEIGHT, (uint16_t)height * 2);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_BPP, 32);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_X_OFFSET, 0);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_Y_OFFSET, 0);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_BANK, 0);
|
||||
|
||||
bga_screen_line_size = (uint32_t)width * 4;
|
||||
}
|
||||
|
||||
int bga_ioctl(uintptr_t cmd, uintptr_t arg)
|
||||
{
|
||||
uint32_t y_offset = 0;
|
||||
switch (cmd) {
|
||||
case BGA_GET_HEIGHT:
|
||||
return bga_screen_height;
|
||||
case BGA_GET_WIDTH:
|
||||
return bga_screen_width;
|
||||
case BGA_GET_SCALE:
|
||||
return 1;
|
||||
case BGA_SWAP_BUFFERS:
|
||||
y_offset = bga_screen_height * (arg & 1);
|
||||
_bga_write_reg(VBE_DISPI_INDEX_Y_OFFSET, (uint16_t)y_offset);
|
||||
return 0;
|
||||
case BGA_DISABLE:
|
||||
_bga_write_reg(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// static memzone_t* _bga_mmap(file_t* file, mmap_params_t* params)
|
||||
// {
|
||||
// bool map_shared = ((params->flags & MAP_SHARED) > 0);
|
||||
|
||||
// if (!map_shared) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// memzone_t* zone = memzone_new_random(RUNNING_THREAD->process->address_space, bga_screen_buffer_size);
|
||||
// if (!zone) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// zone->mmu_flags |= MMU_FLAG_PERM_WRITE | MMU_FLAG_PERM_READ | MMU_FLAG_UNCACHED;
|
||||
// zone->type |= ZONE_TYPE_DEVICE;
|
||||
// zone->file = file_duplicate(file);
|
||||
// zone->ops = &mmap_file_vm_ops;
|
||||
|
||||
// for (int offset = 0; offset < bga_screen_buffer_size; offset += VMM_PAGE_SIZE) {
|
||||
// vmm_map_page(zone->vaddr + offset, bga_buf_paddr + offset, zone->mmu_flags);
|
||||
// }
|
||||
|
||||
// return zone;
|
||||
// }
|
||||
|
||||
|
||||
static void bga_set_resolution(uint32_t width, uint32_t height)
|
||||
{
|
||||
_bga_set_resolution(width, height);
|
||||
bga_screen_width = width;
|
||||
bga_screen_height = height;
|
||||
bga_screen_buffer_size = bga_screen_line_size * height * 2;
|
||||
}
|
||||
|
||||
|
||||
int bga_init_with_dev(pci_dev_t* dev)
|
||||
{
|
||||
if (dev->type != DEVICE_DISPLAY) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bga_buf_paddr = pci_read_bar(dev, 0) & 0xfffffff0;
|
||||
bga_set_resolution(1024, 768);
|
||||
kprintf("bga buf paddr=%p; buf size= %d KB\n", bga_buf_paddr, bga_screen_buffer_size / 1024);
|
||||
for (int k = 0; k < bga_screen_buffer_size; k += 4096) {
|
||||
klin_mapping_phy(bga_buf_paddr + k, bga_buf_paddr + k, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW);
|
||||
}
|
||||
uint32_t *test = (uint32_t *)bga_buf_paddr;
|
||||
for (int i = 0; i <= 1024*20; ++ i) test[i] = 0xff3312;
|
||||
return 0;
|
||||
}
|
||||
@ -23,6 +23,8 @@
|
||||
#include "stdio.h"
|
||||
#include "tty.h"
|
||||
#include "serialport.h"
|
||||
#include "bga.h"
|
||||
#include "pci.h"
|
||||
|
||||
static int initialize_processes(); // added by xw, 18/5/26
|
||||
static int initialize_cpus(); // added by xw, 18/6/2
|
||||
@ -32,10 +34,8 @@ static int initialize_cpus(); // added by xw, 18/6/2
|
||||
*======================================================================*/
|
||||
int kernel_main()
|
||||
{
|
||||
init_serial();
|
||||
init_pci();
|
||||
clear_kernel_pagepte_low();
|
||||
while(1);
|
||||
init_serial();
|
||||
int error;
|
||||
|
||||
disp_pos = 0;
|
||||
@ -45,6 +45,10 @@ int kernel_main()
|
||||
|
||||
init(); // 内存管理模块的初始化 add by liang
|
||||
init_tty_main();
|
||||
init_pci();
|
||||
pci_dev_t* dev_bga = get_pci_bga();
|
||||
bga_init_with_dev(dev_bga);
|
||||
kprintf("cr3 ready= %p\n", cr3_ready);
|
||||
// initialize PCBs, added by xw, 18/5/26
|
||||
error = initialize_processes();
|
||||
if (error != 0)
|
||||
|
||||
@ -341,3 +341,69 @@ void clear_kernel_pagepte_low()
|
||||
memset((void *)(K_PHY2LIN(KernelPageTblAddr + 0x1000)), 0, 4096 * page_num); // 从内核页表中清除线性地址的低端映射关系
|
||||
refresh_page_cache();
|
||||
}
|
||||
|
||||
int klin_mapping_phy(u32 AddrLin, // 线性地址
|
||||
u32 phy_addr, // 物理地址,若为MAX_UNSIGNED_INT(0xFFFFFFFF),则表示需要由该函数判断是否分配物理地址,否则将phy_addr直接和AddrLin建立映射
|
||||
u32 pde_Attribute, // 页目录中的属性位
|
||||
u32 pte_Attribute) // 页表中的属性位
|
||||
{
|
||||
u32 pte_addr_phy;
|
||||
u32 pde_addr_phy = read_cr3(); // add by visual 2016.5.19
|
||||
|
||||
if (0 == pte_exist(pde_addr_phy, AddrLin))
|
||||
{ // 页表不存在,创建一个,并填进页目录中
|
||||
pte_addr_phy = (u32)do_kmalloc_4k(); // 为页表申请一页
|
||||
memset((void *)K_PHY2LIN(pte_addr_phy), 0, num_4K); // add by visual 2016.5.26
|
||||
|
||||
if (pte_addr_phy < 0 || (pte_addr_phy & 0x3FF) != 0) // add by visual 2016.5.9
|
||||
{
|
||||
kprintf("\x1b[31;47mlin_mapping_phy Error:pte_addr_phy\x1b[m");
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_page_pde(pde_addr_phy, // 页目录物理地址
|
||||
AddrLin, // 线性地址
|
||||
pte_addr_phy, // 页表物理地址
|
||||
pde_Attribute); // 属性
|
||||
}
|
||||
else
|
||||
{ // 页表存在,获取该页表物理地址
|
||||
pte_addr_phy = (*((u32 *)K_PHY2LIN(read_cr3()) + get_pde_index(AddrLin))) & 0xFFFFF000;
|
||||
}
|
||||
|
||||
if (MAX_UNSIGNED_INT == phy_addr) // add by visual 2016.5.19
|
||||
{ // 由函数申请内存
|
||||
if (0 == phy_exist(pte_addr_phy, AddrLin))
|
||||
{ // 无物理页,申请物理页并修改phy_addr
|
||||
if (AddrLin >= K_PHY2LIN(0))
|
||||
phy_addr = do_kmalloc_4k(); // 从内核物理地址申请一页
|
||||
else
|
||||
{
|
||||
phy_addr = do_malloc_4k(); // 从用户物理地址空间申请一页
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 有物理页,什么也不做,直接返回,必须返回
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // 指定填写phy_addr
|
||||
// 不用修改phy_addr
|
||||
}
|
||||
|
||||
if (phy_addr < 0 || (phy_addr & 0x3FF) != 0)
|
||||
{
|
||||
kprintf("\x1b[31;47mlin_mapping_phy:phy_addr ERROR\x1b[m");
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_page_pte(pte_addr_phy, // 页表物理地址
|
||||
AddrLin, // 线性地址
|
||||
phy_addr, // 物理页物理地址
|
||||
pte_Attribute); // 属性
|
||||
refresh_page_cache();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -164,3 +164,11 @@ uint32_t pci_read_bar(pci_dev_t* pci_dev, int bar_id) {
|
||||
}
|
||||
|
||||
void init_pci() { pci_find_devices(); }
|
||||
|
||||
pci_dev_t* get_pci_bga()
|
||||
{
|
||||
for (int i = 0; i < NR_PCI_DEV; ++ i) {
|
||||
if (pci_devs[i].type == DEVICE_DISPLAY) return &pci_devs[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user