Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1288 → Rev 1289

/kernel/trunk/arch/amd64/include/vesa.h
0,0 → 1,40
/*
* Copyright (C) 2006-2006 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __VESA_H__
#define __VESA_H__
 
 
int vesa_present(void);
void vesa_init(void);
 
 
#endif
 
 
 
/kernel/trunk/arch/amd64/include/pm.h
36,8 → 36,10
#endif
 
#define IDT_ITEMS 64
#define GDT_ITEMS 8
#define GDT_ITEMS 9
 
#define VESA_INIT_SEGMENT 0x8000
 
#define NULL_DES 0
/* Warning: Do not reorder next items, unless you look into syscall.c!!! */
#define KTEXT_DES 1
47,6 → 49,7
#define KTEXT32_DES 5
/* EndOfWarning */
#define TSS_DES 6
#define VESA_INIT_DES 8
 
#define gdtselector(des) ((des)<<3)
#define idtselector(des) ((des)<<4)
/kernel/trunk/arch/amd64/Makefile.inc
90,6 → 90,7
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/delay.S \
/kernel/trunk/arch/amd64/src/amd64.c
34,6 → 34,7
 
#include <proc/thread.h>
#include <arch/ega.h>
#include <arch/vesa.h>
#include <genarch/i8042/i8042.h>
#include <arch/i8254.h>
#include <arch/i8259.h>
132,6 → 133,10
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
#ifdef CONFIG_FB
if (vesa_present()) vesa_init();
else
#endif
ega_init(); /* video */
/* Enable debugger */
debugger_init();
/kernel/trunk/arch/amd64/src/pm.c
108,7 → 108,9
/* TSS descriptor - set up will be completed later,
* on AMD64 it is 64-bit - 2 items in table */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* VESA Init descriptor */
{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
};
 
idescriptor_t idt[IDT_ITEMS];
/kernel/trunk/arch/amd64/src/boot/boot.S
72,6 → 72,24
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
#ifdef CONFIG_FB
mov $vesa_init,%esi;
mov $VESA_INIT_SEGMENT<<4,%edi;
mov $e_vesa_init-vesa_init,%ecx;
cld;
rep movsb;
 
mov $VESA_INIT_SEGMENT<<4,%edi;
call *%edi;
mov %esi,KA2PA(vesa_ph_addr);
mov %di,KA2PA(vesa_height);
shr $16,%edi;
mov %di,KA2PA(vesa_width);
mov %bx,KA2PA(vesa_scanline);
shr $16,%ebx;
mov %bx,KA2PA(vesa_bpp);
#endif
 
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
252,6 → 270,188
cli
hlt
 
#ifdef CONFIG_FB
.code32
vesa_init:
jmp $gdtselector(VESA_INIT_DES),$vesa_init_real-vesa_init;
.code16
vesa_init_real:
 
mov %cr0,%eax;
and $~1,%eax;
mov %eax,%cr0;
 
 
jmp $VESA_INIT_SEGMENT,$vesa_init_real2-vesa_init;
 
vesa_init_real2:
 
 
mov %esp,%ebp;
mov %ss,%cx;
mov $VESA_INIT_SEGMENT,%bx;
mov %bx,%ss;
mov $0x0000fffc,%esp;
push %ds;
push %es;
push %fs;
push %gs;
push %ebp;
push %cx;
 
mov %bx,%ds;
mov %bx,%es;
mov %bx,%fs;
mov %bx,%gs;
 
mov $vesa_idt-vesa_init,%ebx;
lidtl (%ebx);
 
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP==24
#undef CONFIG_VESA_BPP_a
#define CONFIG_VESA_BPP_a 32
#endif
 
 
mov $VESA_GET_INFO,%ax;
mov $e_vesa_init-vesa_init,%di
push %di;
int $0x10;
pop %di;
cmp $VESA_OK,%al;
jnz 0f;
mov 2+VESA_MODE_LIST_PTR_OFFSET(%di),%si;
mov %si,%gs;
mov VESA_MODE_LIST_PTR_OFFSET(%di),%si;
 
add $VESA_INFO_SIZE,%di;
 
1:# Try next mode
mov %gs:(%si),%cx;
cmp $VESA_END_OF_MODES,%cx;
jz 0f;
inc %si;
inc %si;
push %cx;
push %di;
push %si;
mov $VESA_GET_MODE_INFO,%ax;
int $0x10;
pop %si;
pop %di;
pop %cx;
cmp $VESA_OK,%al;
jnz 0f;
 
 
mov $CONFIG_VESA_WIDTH,%ax;
cmp VESA_MODE_WIDTH_OFFSET(%di),%ax;
jnz 1b;
mov $CONFIG_VESA_HEIGHT,%ax;
cmp VESA_MODE_HEIGHT_OFFSET(%di),%ax;
jnz 1b;
mov $CONFIG_VESA_BPP,%al;
cmp VESA_MODE_BPP_OFFSET(%di),%al;
jz 2f;
mov $CONFIG_VESA_BPP_a,%al;
cmp VESA_MODE_BPP_OFFSET(%di),%al;
jnz 1b;
 
2:
 
mov %cx,%bx;
or $0xC000,%bx;
push %di;
mov $VESA_SET_MODE,%ax;
int $0x10;
pop %di;
cmp $VESA_OK,%al;
jnz 0f;
mov VESA_MODE_PHADDR_OFFSET(%di),%esi;
mov VESA_MODE_WIDTH_OFFSET(%di),%ax;
shl $16,%eax;
mov VESA_MODE_HEIGHT_OFFSET(%di),%ax;
mov VESA_MODE_BPP_OFFSET(%di),%bl;
xor %bh,%bh;
shl $16,%ebx;
mov VESA_MODE_SCANLINE_OFFSET(%di),%bx;
mov %eax,%edi;
 
8:
 
mov %cr0,%eax;
or $1,%eax;
mov %eax,%cr0;
 
jmp 9f;
9:
 
pop %cx;
pop %ebp;
pop %gs;
pop %fs;
pop %es;
pop %ds;
mov %cx,%ss;
mov %ebp,%esp;
 
ljmpl $gdtselector(KTEXT32_DES),$(vesa_init_protect-vesa_init+VESA_INIT_SEGMENT<<4);
 
vesa_init_protect:
.code32
ret;
 
0: #Error no Prefered mode found
 
mov $0x111,%cx;
push %di;
push %cx;
mov $VESA_GET_MODE_INFO,%ax;
int $0x10;
pop %cx;
pop %di;
cmp $VESA_OK,%al;
jnz 1f;
jmp 2b;
 
1:mov $0x0003,%ax;
int $0x10;
mov $0xffffffff,%edi; /* EGA text mode used, because of problems with VESA */
jmp 8;
 
 
vesa_idt:
.word 0x03ff
.long 0
.align 4
e_vesa_init:
#endif
 
 
.section K_DATA_START, "aw", @progbits
.align 4096
/kernel/trunk/arch/ia32/include/vesa.h
29,7 → 29,6
#ifndef __VESA_H__
#define __VESA_H__
 
#define VIDEORAM_LIN_ADDR 0xA0000000
 
int vesa_present(void);
void vesa_init(void);
/kernel/trunk/arch/ia32/src/pm.c
68,7 → 68,7
/* TLS descriptor */
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
/* VESA Init descriptor */
{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 },
{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
};
 
/kernel/trunk/arch/ia32/src/drivers/vesa.c
32,6 → 32,7
#include <arch/vesa.h>
#include <putchar.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/as.h>
#include <arch/mm/page.h>
#include <synch/spinlock.h>
54,15 → 55,28
}
 
 
static __u32 log2(__u32 x)
{
__u32 l=2;
if(x<=PAGE_SIZE) return PAGE_WIDTH+1;
x--;
while(x>>=1) l++;
return l;
}
 
void vesa_init(void)
{
int a;
 
__address videoram_lin_addr;
 
videoram_lin_addr=PA2KA(PFN2ADDR(frame_alloc( log2(vesa_scanline*vesa_height) -FRAME_WIDTH,FRAME_KA)));
/* Map videoram */
for(a=0;a<((vesa_scanline*vesa_height+PAGE_SIZE-1)>>PAGE_WIDTH);a++)
page_mapping_insert(AS_KERNEL, VIDEORAM_LIN_ADDR+a*4096, vesa_ph_addr+a*4096, PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, videoram_lin_addr+a*4096, vesa_ph_addr+a*4096, PAGE_NOT_CACHEABLE);
fb_init( VIDEORAM_LIN_ADDR,vesa_width,vesa_height,vesa_bpp,vesa_scanline);
fb_init( videoram_lin_addr,vesa_width,vesa_height,vesa_bpp,vesa_scanline);
putchar('\n');
}