Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1682 → Rev 1683

/shark/branches/xen/oslib/kl/advtimer.c
File deleted
/shark/branches/xen/oslib/kl/oq.txt
File deleted
/shark/branches/xen/oslib/kl/aspace.c
File deleted
/shark/branches/xen/oslib/kl/Makefile
File deleted
/shark/branches/xen/oslib/kl/mem.c
File deleted
/shark/branches/xen/oslib/kl/time.c
File deleted
/shark/branches/xen/oslib/kl/event.c
File deleted
/shark/branches/xen/oslib/kl/todo.txt
File deleted
/shark/branches/xen/oslib/kl/estub.c
File deleted
/shark/branches/xen/oslib/kl/event1.c
File deleted
/shark/branches/xen/oslib/kl/cxsw-2.c
File deleted
/shark/branches/xen/oslib/kl/init.c
File deleted
/shark/branches/xen/oslib/kl/abort.s
File deleted
/shark/branches/xen/oslib/kl/intevt.c
File deleted
/shark/branches/xen/oslib/kl/timeint.s
File deleted
/shark/branches/xen/oslib/lib/readme
File deleted
/shark/branches/xen/oslib/lib/Makefile
File deleted
/shark/branches/xen/oslib/ll/sys/ll/aspace.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/time.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/ll-data.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/exc.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/ll-func.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/event.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/ll-mem.h
File deleted
/shark/branches/xen/oslib/ll/sys/ll/ll-instr.h
File deleted
/shark/branches/xen/oslib/ll/sys/types.h
File deleted
/shark/branches/xen/oslib/ll/i386/apic.h
File deleted
/shark/branches/xen/oslib/ll/i386/mem.h
File deleted
/shark/branches/xen/oslib/ll/i386/defs.h
File deleted
/shark/branches/xen/oslib/ll/i386/hw-io.h
File deleted
/shark/branches/xen/oslib/ll/i386/sel.h
File deleted
/shark/branches/xen/oslib/ll/i386/hw-data.h
File deleted
/shark/branches/xen/oslib/ll/i386/mb-info.h
File deleted
/shark/branches/xen/oslib/ll/i386/64bit.h
File deleted
/shark/branches/xen/oslib/ll/i386/hw-arch.h
File deleted
/shark/branches/xen/oslib/ll/i386/error.h
File deleted
/shark/branches/xen/oslib/ll/i386/x-dosmem.h
File deleted
/shark/branches/xen/oslib/ll/i386/int.h
File deleted
/shark/branches/xen/oslib/ll/i386/x-dos.h
File deleted
/shark/branches/xen/oslib/ll/i386/pit.h
File deleted
/shark/branches/xen/oslib/ll/i386/farptr.h
File deleted
/shark/branches/xen/oslib/ll/i386/x-bios.h
File deleted
/shark/branches/xen/oslib/ll/i386/cons.h
File deleted
/shark/branches/xen/oslib/ll/i386/tss-ctx.h
File deleted
/shark/branches/xen/oslib/ll/i386/hw-func.h
File deleted
/shark/branches/xen/oslib/ll/i386/mb-hdr.h
File deleted
/shark/branches/xen/oslib/ll/i386/linkage.h
File deleted
/shark/branches/xen/oslib/ll/i386/advtimer.h
File deleted
/shark/branches/xen/oslib/ll/i386/pic.h
File deleted
/shark/branches/xen/oslib/ll/i386/hw-instr.h
File deleted
/shark/branches/xen/oslib/ll/ll.h
File deleted
/shark/branches/xen/oslib/mk/os.x
File deleted
/shark/branches/xen/oslib/mk/oldgnu.mk
File deleted
/shark/branches/xen/oslib/mk/gnu.mk
File deleted
/shark/branches/xen/oslib/mk/linux.mk
File deleted
/shark/branches/xen/oslib/docs/todo.txt
File deleted
/shark/branches/xen/oslib/docs/oslib.tex
File deleted
/shark/branches/xen/oslib/docs/ref.txt
File deleted
/shark/branches/xen/oslib/docs/Makefile
File deleted
/shark/branches/xen/oslib/libcons/Makefile
File deleted
/shark/branches/xen/oslib/libcons/cons1.c
File deleted
/shark/branches/xen/oslib/libcons/message.c
File deleted
/shark/branches/xen/oslib/libcons/cons2.c
File deleted
/shark/branches/xen/oslib/libcons/cprintf.c
File deleted
/shark/branches/xen/oslib/config.mk
File deleted
/shark/branches/xen/oslib/Makefile
File deleted
/shark/branches/xen/oslib/examples/vmdemo.c
File deleted
/shark/branches/xen/oslib/examples/eventdem.c
File deleted
/shark/branches/xen/oslib/examples/asdemo.c
File deleted
/shark/branches/xen/oslib/examples/cpudemo.c
File deleted
/shark/branches/xen/oslib/examples/Makefile
File deleted
/shark/branches/xen/oslib/examples/scheddem.c
File deleted
/shark/branches/xen/oslib/examples/syscalls.c
File deleted
/shark/branches/xen/oslib/examples/bugs.txt
File deleted
/shark/branches/xen/oslib/examples/timetest.c
File deleted
/shark/branches/xen/oslib/examples/ctxswdem.c
File deleted
/shark/branches/xen/oslib/examples/biosdemo.c
File deleted
/shark/branches/xen/oslib/examples/mbdemo.c
File deleted
/shark/branches/xen/oslib/examples/pitsdemo.c
File deleted
/shark/branches/xen/oslib/examples/pushdem.c
File deleted
/shark/branches/xen/oslib/xlib/idtinit.c
File deleted
/shark/branches/xen/oslib/xlib/xsys0.s
File deleted
/shark/branches/xen/oslib/xlib/x0.s
File deleted
/shark/branches/xen/oslib/xlib/ctxsw.c
File deleted
/shark/branches/xen/oslib/xlib/ctx.s
File deleted
/shark/branches/xen/oslib/xlib/xinfo.c
File deleted
/shark/branches/xen/oslib/xlib/xdosf.c
File deleted
/shark/branches/xen/oslib/xlib/xbios.c
File deleted
/shark/branches/xen/oslib/xlib/x1.c
File deleted
/shark/branches/xen/oslib/xlib/cpu2.s
File deleted
/shark/branches/xen/oslib/xlib/xdosm.c
File deleted
/shark/branches/xen/oslib/xlib/ccpu.c
File deleted
/shark/branches/xen/oslib/xlib/fpu.c
File deleted
/shark/branches/xen/oslib/xlib/xinit.c
File deleted
/shark/branches/xen/oslib/xlib/irq.c
File deleted
/shark/branches/xen/oslib/xlib/Makefile
File deleted
/shark/branches/xen/oslib/xlib/xconv.c
File deleted
/shark/branches/xen/oslib/xlib/xsystab.c
File deleted
/shark/branches/xen/oslib/xlib/mem.s
File deleted
/shark/branches/xen/oslib/xlib/exc.s
File deleted
/shark/branches/xen/oslib/xlib/vm86.c
File deleted
/shark/branches/xen/oslib/GPL.txt
File deleted
/shark/branches/xen/oslib/tools/binfin.c
File deleted
/shark/branches/xen/oslib/tools/checksymbols.c
File deleted
/shark/branches/xen/oslib/todo.txt
File deleted
/shark/branches/xen/Makefile
477,9 → 477,9
 
include-dirs:= \
-I$(srctree)/include -I$(srctree)/modules \
-I$(srctree)/arch/$(ARCH)/include/arch \
-I$(srctree)/libc/arch/$(ARCH)/include \
-I$(srctree)/tracer/include \
-I$(srctree)/oslib
-I$(srctree)/tracer/include
 
config:= -D__LINUX__ \
$(cpp-tsc-$(TSC)) $(cpp-apic-$(APIC)) $(cpp-bios-$(BIOS)) \
501,7 → 501,7
fs-YES:= fs/
 
targets:= libgkern.a drivers/ libc/ ports/ tracer/ $(fs-$(SHARK_FS))
libgkern.a-objs:= oslib/ kernel/ modules/
libgkern.a-objs:= arch/$(ARCH)/ kernel/ modules/
 
# Let the good times roll...
$(eval $(call recurse-templ,$(srctree)))
/shark/branches/xen/arch/x86/mem.s
0,0 → 1,63
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Memcopy to other address spaces */
 
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
 
.data
 
ASMFILE(Mem-ASM)
 
.text
 
.globl SYMBOL_NAME(fmemcpy)
 
/* void fmemcpy(unsigned short ds,unsigned long do,
unsigned short ss,unsigned long so,unsigned n) */
SYMBOL_NAME_LABEL(fmemcpy)
/* Build the standard stack frame */
pushl %ebp
movl %esp,%ebp
pushl %esi
pushl %edi
pushw %ds
pushw %es
/* Get parms into register */
movl 8(%ebp),%eax
movw %ax,%es
movl 12(%ebp),%edi
movl 16(%ebp),%eax
movw %ax,%ds
movl 20(%ebp),%esi
movl 24(%ebp),%ecx
cld
rep
movsb
popw %es
popw %ds
popl %edi
popl %esi
leave
ret
/shark/branches/xen/arch/x86/init.c
0,0 → 1,242
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* KL initialization code */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/x-bios.h>
#include <ll/i386/mem.h>
#include <ll/i386/cons.h>
#include <ll/i386/mb-info.h>
#include <ll/i386/error.h>
#include <ll/i386/pit.h>
#include <ll/i386/pic.h>
#include <ll/i386/advtimer.h>
 
#include <ll/i386/tss-ctx.h>
#include <ll/i386/hw-arch.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/ll-mem.h>
#include <ll/sys/ll/ll-instr.h>
#include <ll/sys/ll/event.h> /* for irq_bind() & irq_init() */
#include <ll/sys/ll/exc.h> /* These are the HW exceptions */
 
FILE(LL-Init);
 
/* These are declared in llCx32b.C */
TSS TSS_table[TSSMax];
WORD TSS_control[TSSMax];
BYTE ll_FPU_stdctx[FPU_CONTEXT_SIZE];
 
void debug_info(void) {
static DWORD fault_ip;
static DWORD fault_cs;
static DWORD error_code;
static DWORD fault_eflag;
static DWORD sp;
static DWORD fault_sp;
static DWORD data0;
static DWORD data1;
static DWORD data2;
static DWORD sdata4;
static DWORD sdata8;
 
asm (" movl %%esp,%0\n\t":"=r"(sp));
asm (" movl -8(%%ebp),%0\n\t":"=r"(sdata8));
asm (" movl -4(%%ebp),%0\n\t":"=r"(sdata4));
asm (" movl 0(%%ebp),%0\n\t":"=r"(data0));
asm (" movl 4(%%ebp),%0\n\t":"=r"(error_code));
asm (" movl 8(%%ebp),%0\n\t":"=r"(fault_ip));
asm (" movl 12(%%ebp),%0\n\t":"=r"(fault_cs));
asm (" movl 16(%%ebp),%0\n\t":"=r"(fault_eflag));
asm (" movl 20(%%ebp),%0\n\t":"=r"(fault_sp));
asm (" movl 24(%%ebp),%0\n\t":"=r"(data1));
message(":F -8: %lx:", sdata8);
message(":F -4: %lx:", sdata4);
message(":F 0: %lx:", data0);
message(":F ec/4: %lx:", error_code);
message(":F ip/8: %lx:", fault_ip);
message(":F cs/12 : %lx:", fault_cs);
message(":F eflag/16 : %lx:", fault_eflag);
message(":F sp/20 : %lx:", fault_sp);
message(":F 24 : %lx:", data1);
 
}
 
 
void ll_exc_hook(int i)
{
 
static char *exc_mess[] = {
"#Division by 0",
"#Debug fault",
"#NMI detected",
"#Breakpoint trap",
"#Overflow detected on INTO",
"#BOUND limit exceeded",
"*Unvalid opcode",
"1FPU context switch", /* Handled in the llCtx.Asm/S File */
"*Double defect",
"#INTEL reserved",
"*Unvalid TSS",
"*Segment not present",
"*Stack exception",
"*General protection fault",
"#Page fault",
"#INTEL reserved",
"2Coprocessor error"
};
 
static int exc_code[] = {
DIV_BY_0, NMI_EXC, DEBUG_EXC, BREAKPOINT_EXC,
HW_FAULT, HW_FAULT, HW_FAULT,
0, /* This is the FPU ctx Switch */
HW_FAULT, HW_FAULT, HW_FAULT, HW_FAULT,
HW_FAULT, HW_FAULT, HW_FAULT, HW_FAULT,
MATH_EXC
};
 
char code = *exc_mess[i];
#ifdef __LL_DEBUG__
extern long int ndp_called,ndp_switched;
extern wu_called;
extern ai_called;
extern DWORD *smain;
#endif
 
 
/* Math error! FPU has to be acknowledgded */
if (code == '2') ll_out(0x0F0,0);
message("Exception %d occurred\n", i);
message("%s\n", &exc_mess[i][1]);
#ifdef __LL_DEBUG__
if (code == '*') {
/* Dump additional info */
message("DS:%nx CS:%nx\n",get_DS(),get_CS());
/* message("WU : %d AI : %d\n",wu_called,ai_called); */
message("Actual stack : %x\n",get_SP());
/* message("Main stack : %p\n",smain); */
dump_TSS(get_TR());
}
#endif
/* halt(); */
 
message("Actual stack : %x\n",get_SP());
 
dump_TSS(get_TR());
 
ll_abort(exc_code[i]);
}
 
void *ll_init(void)
{
void *p;
int i;
LIN_ADDR b;
/*
DWORD s;
BYTE *base;
*/
TSS dummy_tss; /* Very dirty, but we need it, in order to
get an initial value for the FPU
context...
*/
p = l1_init();
/* First of all, init the exc and irq tables... */
irq_init();
for(i = 0; i < 32; i++) {
 
/* Warning!!! The hw exceptions should be 32.... Fix it!!! */
/*
ll_irq_table[i] = (DWORD)act_int;
ll_exc_table[i] = (DWORD)ll_exc_hook;
*/
l1_exc_bind(i, ll_exc_hook);
}
for(i = 0; i < 16; i++) {
void act_int(int i);
l1_irq_bind(i, act_int);
}
 
 
/* Init TSS table & put the corrispondent selectors into GDT */
TSS_control[TSSMain] |= TSS_USED;
for (i = 0; i < TSSMax; i++) {
/* b = appl2linear(&TSS_table[i]); */
b = (LIN_ADDR)(&TSS_table[i]);
GDT_place(TSSindex2sel(i),(DWORD)b,sizeof(TSS),FREE_TSS386, GRAN_16);
}
 
#if 0
ll_FPU_save();
memcpy(ll_FPU_stdctx,ll_FPU_savearea,FPU_CONTEXT_SIZE);
#else
save_fpu(&dummy_tss); /* OK???*/
memcpy(ll_FPU_stdctx, dummy_tss.ctx_FPU, FPU_CONTEXT_SIZE);
#endif
init_fpu();
 
/* ll_mem_init must be explicitelly called by program... */
#if 0
/* Get info about extended memory! We suppose that X has loaded */
/* there the application; if you switch to DOS memory, then you */
/* have to change the stuff in order it works; check X_... for */
/* details. */
X_meminfo(&b,&s,NULL,NULL);
base = (BYTE *)b;
#ifdef __MEM_DEBUG__
message("PM Free Mem Base : %lx\n",b);
message("PM null addr (0L) : %lx\n",appl2linear((void *)0L));
message("PM Free Mem Base (Cnvrtd): %lp\n",base);
#endif
ll_mem_init(base,s);
#ifdef __MEM_DEBUG__
ll_mem_dump();
#endif
#endif
 
 
return p;
}
 
void abort_tail(int code)
{
message("ABORT %d !!!",code);
ll_restore_adv();
l1_end();
sti();
l1_exit(1);
}
 
void ll_end(void)
{
ll_restore_adv();
l1_end();
}
 
/shark/branches/xen/arch/x86/idtinit.c
0,0 → 1,544
 
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-func.h>
 
/* ll hardware interrupt hooks */
extern void h0(void);
extern void h1(void);
extern void h2(void);
extern void h3(void);
extern void h4(void);
extern void h5(void);
extern void h6(void);
extern void exc7(void);
extern void h8(void);
extern void h9(void);
extern void h10(void);
extern void h11(void);
extern void h12(void);
extern void h13(void);
extern void h14(void);
extern void h15(void);
extern void h16(void);
extern void h17(void);
extern void h18(void);
extern void h19(void);
extern void h20(void);
extern void h21(void);
extern void h22(void);
extern void h23(void);
extern void h24(void);
extern void h25(void);
extern void h26(void);
extern void h27(void);
extern void h28(void);
extern void h29(void);
extern void h30(void);
extern void h31(void);
extern void h32(void);
extern void h33(void);
extern void h34(void);
extern void h35(void);
extern void h36(void);
extern void h37(void);
extern void h38(void);
extern void h39(void);
extern void h40(void);
extern void h41(void);
extern void h42(void);
extern void h43(void);
extern void h44(void);
extern void h45(void);
extern void h46(void);
extern void h47(void);
extern void h48(void);
extern void h49(void);
extern void h50(void);
extern void h51(void);
extern void h52(void);
extern void h53(void);
extern void h54(void);
extern void h55(void);
extern void h56(void);
extern void h57(void);
extern void h58(void);
extern void h59(void);
extern void h60(void);
extern void h61(void);
extern void h62(void);
extern void h63(void);
extern void h64(void);
extern void h65(void);
extern void h66(void);
extern void h67(void);
extern void h68(void);
extern void h69(void);
extern void h70(void);
extern void h71(void);
extern void h72(void);
extern void h73(void);
extern void h74(void);
extern void h75(void);
extern void h76(void);
extern void h77(void);
extern void h78(void);
extern void h79(void);
extern void h80(void);
extern void h81(void);
extern void h82(void);
extern void h83(void);
extern void h84(void);
extern void h85(void);
extern void h86(void);
extern void h87(void);
extern void h88(void);
extern void h89(void);
extern void h90(void);
extern void h91(void);
extern void h92(void);
extern void h93(void);
extern void h94(void);
extern void h95(void);
extern void h96(void);
extern void h97(void);
extern void h98(void);
extern void h99(void);
extern void h100(void);
extern void h101(void);
extern void h102(void);
extern void h103(void);
extern void h104(void);
extern void h105(void);
extern void h106(void);
extern void h107(void);
extern void h108(void);
extern void h109(void);
extern void h110(void);
extern void h111(void);
extern void h112(void);
extern void h113(void);
extern void h114(void);
extern void h115(void);
extern void h116(void);
extern void h117(void);
extern void h118(void);
extern void h119(void);
extern void h120(void);
extern void h121(void);
extern void h122(void);
extern void h123(void);
extern void h124(void);
extern void h125(void);
extern void h126(void);
extern void h127(void);
extern void h128(void);
extern void h129(void);
extern void h130(void);
extern void h131(void);
extern void h132(void);
extern void h133(void);
extern void h134(void);
extern void h135(void);
extern void h136(void);
extern void h137(void);
extern void h138(void);
extern void h139(void);
extern void h140(void);
extern void h141(void);
extern void h142(void);
extern void h143(void);
extern void h144(void);
extern void h145(void);
extern void h146(void);
extern void h147(void);
extern void h148(void);
extern void h149(void);
extern void h150(void);
extern void h151(void);
extern void h152(void);
extern void h153(void);
extern void h154(void);
extern void h155(void);
extern void h156(void);
extern void h157(void);
extern void h158(void);
extern void h159(void);
extern void h160(void);
extern void h161(void);
extern void h162(void);
extern void h163(void);
extern void h164(void);
extern void h165(void);
extern void h166(void);
extern void h167(void);
extern void h168(void);
extern void h169(void);
extern void h170(void);
extern void h171(void);
extern void h172(void);
extern void h173(void);
extern void h174(void);
extern void h175(void);
extern void h176(void);
extern void h177(void);
extern void h178(void);
extern void h179(void);
extern void h180(void);
extern void h181(void);
extern void h182(void);
extern void h183(void);
extern void h184(void);
extern void h185(void);
extern void h186(void);
extern void h187(void);
extern void h188(void);
extern void h189(void);
extern void h190(void);
extern void h191(void);
extern void h192(void);
extern void h193(void);
extern void h194(void);
extern void h195(void);
extern void h196(void);
extern void h197(void);
extern void h198(void);
extern void h199(void);
extern void h200(void);
extern void h201(void);
extern void h202(void);
extern void h203(void);
extern void h204(void);
extern void h205(void);
extern void h206(void);
extern void h207(void);
extern void h208(void);
extern void h209(void);
extern void h210(void);
extern void h211(void);
extern void h212(void);
extern void h213(void);
extern void h214(void);
extern void h215(void);
extern void h216(void);
extern void h217(void);
extern void h218(void);
extern void h219(void);
extern void h220(void);
extern void h221(void);
extern void h222(void);
extern void h223(void);
extern void h224(void);
extern void h225(void);
extern void h226(void);
extern void h227(void);
extern void h228(void);
extern void h229(void);
extern void h230(void);
extern void h231(void);
extern void h232(void);
extern void h233(void);
extern void h234(void);
extern void h235(void);
extern void h236(void);
extern void h237(void);
extern void h238(void);
extern void h239(void);
extern void h240(void);
extern void h241(void);
extern void h242(void);
extern void h243(void);
extern void h244(void);
extern void h245(void);
extern void h246(void);
extern void h247(void);
extern void h248(void);
extern void h249(void);
extern void h250(void);
extern void h251(void);
extern void h252(void);
extern void h253(void);
extern void h254(void);
extern void h255(void);
 
void IDT_init(void)
{
/* Insert the Exceptions handler into IDT */
IDT_place(0x00, h0);
IDT_place(0x01, h1);
IDT_place(0x02, h2);
IDT_place(0x03, h3);
IDT_place(0x04, h4);
IDT_place(0x05, h5);
IDT_place(0x06, h6);
IDT_place(0x07, exc7);
IDT_place(0x08, h8);
IDT_place(0x09, h9);
IDT_place(0x0A, h10);
IDT_place(0x0B, h11);
IDT_place(0x0C, h12);
IDT_place(0x0D, h13);
IDT_place(0x0E, h14);
IDT_place(0x0F, h15);
IDT_place(0x10, h16);
IDT_place(0x11, h17);
IDT_place(0x12, h18);
IDT_place(0x13, h19);
IDT_place(0x14, h20);
IDT_place(0x15, h21);
IDT_place(0x16, h22);
IDT_place(0x17, h23);
IDT_place(0x18, h24);
IDT_place(0x19, h25);
IDT_place(0x1A, h26);
IDT_place(0x1B, h27);
IDT_place(0x1C, h28);
IDT_place(0x1D, h29);
IDT_place(0x1E, h30);
IDT_place(0x1F, h31);
IDT_place(0x20, h32);
IDT_place(0x21, h33);
IDT_place(0x22, h34);
IDT_place(0x23, h35);
IDT_place(0x24, h36);
IDT_place(0x25, h37);
IDT_place(0x26, h38);
IDT_place(0x27, h39);
IDT_place(0x28, h40);
IDT_place(0x29, h41);
IDT_place(0x2A, h42);
IDT_place(0x2B, h43);
IDT_place(0x2C, h44);
IDT_place(0x2D, h45);
IDT_place(0x2E, h46);
IDT_place(0x2F, h47);
IDT_place(0x30, h48);
IDT_place(0x31, h49);
IDT_place(0x32, h50);
IDT_place(0x33, h51);
IDT_place(0x34, h52);
IDT_place(0x35, h53);
IDT_place(0x36, h54);
IDT_place(0x37, h55);
IDT_place(0x38, h56);
IDT_place(0x39, h57);
IDT_place(0x3A, h58);
IDT_place(0x3B, h59);
IDT_place(0x3C, h60);
IDT_place(0x3D, h61);
IDT_place(0x3E, h62);
IDT_place(0x3F, h63);
IDT_place(0x40, h64);
IDT_place(0x41, h65);
IDT_place(0x42, h66);
IDT_place(0x43, h67);
IDT_place(0x44, h68);
IDT_place(0x45, h69);
IDT_place(0x46, h70);
IDT_place(0x47, h71);
 
IDT_place(0x48, h72);
IDT_place(0x49, h73);
IDT_place(0x4A, h74);
IDT_place(0x4B, h75);
IDT_place(0x4C, h76);
IDT_place(0x4D, h77);
IDT_place(0x4E, h78);
IDT_place(0x4F, h79);
IDT_place(0x50, h80);
IDT_place(0x51, h81);
IDT_place(0x52, h82);
IDT_place(0x53, h83);
IDT_place(0x54, h84);
IDT_place(0x55, h85);
IDT_place(0x56, h86);
IDT_place(0x57, h87);
IDT_place(0x58, h88);
IDT_place(0x59, h89);
IDT_place(0x5A, h90);
IDT_place(0x5B, h91);
IDT_place(0x5C, h92);
IDT_place(0x5D, h93);
IDT_place(0x5E, h94);
IDT_place(0x5F, h95);
IDT_place(0x60, h96);
IDT_place(0x61, h97);
IDT_place(0x62, h98);
IDT_place(0x63, h99);
IDT_place(0x64, h100);
IDT_place(0x65, h101);
IDT_place(0x66, h102);
IDT_place(0x67, h103);
IDT_place(0x68, h104);
IDT_place(0x69, h105);
IDT_place(0x6A, h106);
IDT_place(0x6B, h107);
IDT_place(0x6C, h108);
IDT_place(0x6D, h109);
IDT_place(0x6E, h110);
IDT_place(0x6F, h111);
 
IDT_place(0x70, h112);
IDT_place(0x71, h113);
IDT_place(0x72, h114);
IDT_place(0x73, h115);
IDT_place(0x74, h116);
IDT_place(0x75, h117);
IDT_place(0x76, h118);
IDT_place(0x77, h119);
IDT_place(0x78, h120);
IDT_place(0x79, h121);
IDT_place(0x7A, h122);
IDT_place(0x7B, h123);
IDT_place(0x7C, h124);
IDT_place(0x7D, h125);
IDT_place(0x7E, h127);
IDT_place(0x7F, h127);
IDT_place(0x80, h128);
IDT_place(0x81, h129);
IDT_place(0x82, h130);
IDT_place(0x83, h131);
IDT_place(0x84, h132);
IDT_place(0x85, h133);
IDT_place(0x86, h134);
IDT_place(0x87, h135);
IDT_place(0x88, h136);
IDT_place(0x89, h137);
IDT_place(0x8A, h138);
IDT_place(0x8B, h139);
IDT_place(0x8C, h140);
IDT_place(0x8D, h141);
IDT_place(0x8E, h142);
IDT_place(0x8F, h143);
IDT_place(0x90, h144);
IDT_place(0x91, h145);
IDT_place(0x92, h146);
IDT_place(0x93, h147);
IDT_place(0x94, h148);
IDT_place(0x95, h149);
IDT_place(0x96, h150);
IDT_place(0x97, h151);
IDT_place(0x98, h152);
IDT_place(0x99, h153);
IDT_place(0x9A, h154);
IDT_place(0x9B, h155);
IDT_place(0x9C, h156);
IDT_place(0x9D, h157);
IDT_place(0x9E, h158);
IDT_place(0x9F, h159);
IDT_place(0xA0, h160);
IDT_place(0xA1, h161);
IDT_place(0xA2, h162);
IDT_place(0xA3, h163);
IDT_place(0xA4, h164);
IDT_place(0xA5, h165);
IDT_place(0xA6, h166);
IDT_place(0xA7, h167);
IDT_place(0xA8, h168);
IDT_place(0xA9, h169);
IDT_place(0xAA, h170);
IDT_place(0xAB, h171);
IDT_place(0xAC, h172);
IDT_place(0xAD, h173);
IDT_place(0xAE, h174);
IDT_place(0xAF, h175);
IDT_place(0xB0, h176);
IDT_place(0xB1, h177);
IDT_place(0xB2, h178);
IDT_place(0xB3, h179);
IDT_place(0xB4, h180);
IDT_place(0xB5, h181);
IDT_place(0xB6, h182);
IDT_place(0xB7, h183);
IDT_place(0xB8, h184);
IDT_place(0xB9, h185);
IDT_place(0xBA, h186);
IDT_place(0xBB, h187);
IDT_place(0xBC, h188);
IDT_place(0xBD, h189);
IDT_place(0xBE, h190);
IDT_place(0xBF, h191);
IDT_place(0xC0, h192);
IDT_place(0xC1, h193);
IDT_place(0xC2, h194);
IDT_place(0xC3, h195);
IDT_place(0xC4, h196);
IDT_place(0xC5, h197);
IDT_place(0xC6, h198);
IDT_place(0xC7, h199);
IDT_place(0xC8, h200);
IDT_place(0xC9, h201);
IDT_place(0xCA, h202);
IDT_place(0xCB, h203);
IDT_place(0xCC, h204);
IDT_place(0xCD, h205);
IDT_place(0xCE, h206);
IDT_place(0xCF, h207);
IDT_place(0xD0, h208);
IDT_place(0xD1, h209);
IDT_place(0xD2, h210);
IDT_place(0xD3, h211);
IDT_place(0xD4, h212);
IDT_place(0xD5, h213);
IDT_place(0xD6, h214);
IDT_place(0xD7, h215);
IDT_place(0xD8, h216);
IDT_place(0xD9, h217);
IDT_place(0xDA, h218);
IDT_place(0xDB, h219);
IDT_place(0xDC, h220);
IDT_place(0xDD, h221);
IDT_place(0xDE, h222);
IDT_place(0xDF, h223);
IDT_place(0xE0, h224);
IDT_place(0xE1, h225);
IDT_place(0xE2, h226);
IDT_place(0xE3, h227);
IDT_place(0xE4, h228);
IDT_place(0xE5, h229);
IDT_place(0xE6, h230);
IDT_place(0xE7, h231);
IDT_place(0xE8, h232);
IDT_place(0xE9, h233);
IDT_place(0xEA, h234);
IDT_place(0xEB, h235);
IDT_place(0xEC, h236);
IDT_place(0xED, h237);
IDT_place(0xEE, h238);
IDT_place(0xEF, h239);
IDT_place(0xF0, h240);
IDT_place(0xF1, h241);
IDT_place(0xF2, h242);
IDT_place(0xF3, h243);
IDT_place(0xF4, h244);
IDT_place(0xF5, h245);
IDT_place(0xF6, h246);
IDT_place(0xF7, h247);
IDT_place(0xF8, h248);
IDT_place(0xF9, h249);
IDT_place(0xFA, h250);
IDT_place(0xFB, h251);
IDT_place(0xFC, h252);
IDT_place(0xFD, h253);
IDT_place(0xFE, h254);
IDT_place(0xFF, h255);
}
/shark/branches/xen/arch/x86/x0.s
0,0 → 1,237
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The first things to do when an OSLib application starts : */
/* Set up segment registers & stack; then execute startup code */
/* When the application returns the gate-jmp make us return to */
/* RM through X interface! */
 
/* Use X standard GDT selectors */
#include <ll/i386/sel.h>
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
#include <ll/i386/mb-hdr.h>
 
/* #define __DEBUG__ */
 
#ifdef __LINUX__ /* ELF mode */
#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO)
#else /* else it is COFF! */
#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE)
#endif
 
.extern SYMBOL_NAME(_startup)
.extern SYMBOL_NAME(_stkbase)
.extern SYMBOL_NAME(_stktop)
 
.extern SYMBOL_NAME(halt)
 
.data
 
ASMFILE(X0)
 
.globl SYMBOL_NAME(IDT)
.globl SYMBOL_NAME(GDT_base)
.globl SYMBOL_NAME(mb_signature)
.globl SYMBOL_NAME(mbi)
 
/* GDT Definition */
GDT:
.word 0,0,0,0 /* X_NULL_SEL */
.word 0,0,0,0 /* X_DATA16_SEL */
.word 0,0,0,0 /* X_CODE16_SEL */
.word 0,0,0,0 /* X_CODE32_SEL */
/* X_RM_BACK_GATE */
rmBckGateFix1: /* X_FLATCODE_SEL */
.word 0
.word X_FLATCODE_SEL
.word 0x8C00
rmBckGateFix2:
.word 0
 
.word 0,0,0,0 /* X_PM_BACK_GATE */
.word 0xFFFF /* X_FLATDATA_SEL */
.word 0
.word 0x9200
.word 0x00CF
.word 0xFFFF /* X_FLATCODE_SEL */
.word 0
.word 0x9A00
.word 0x00CF
.word 0,0,0,0 /* X_CALLBIOS_SEL */
.word 0,0,0,0 /* X_CALLBIOS_GATE */
.word 0,0,0,0 /* X_VM86_TSS */
.word 0,0,0,0 /* X_MAIN_TSS */
.fill 256 - 12,8,0
GDT_descr:
.word 256*8-1
SYMBOL_NAME_LABEL(GDT_base)
.long GDT
 
IDT_descr:
.word 256*8-1 # idt contains 256 entries
.long SYMBOL_NAME(IDT)
 
/* MultiBoot Data Stuff definition */
SYMBOL_NAME_LABEL(mb_signature) .long 0
SYMBOL_NAME_LABEL(mbi) .long 0
 
.bss /* This MUST be in the BSS !!! */
/* IDT definition */
SYMBOL_NAME_LABEL(IDT)
.fill 256,8,0 # idt is uninitialized
 
/* Protected mode stack */
base:
.space 8192,0
tos:
 
.text
.globl SYMBOL_NAME(_start)
.globl SYMBOL_NAME(__exit)
.globl SYMBOL_NAME(start)
.globl start
 
SYMBOL_NAME_LABEL(_start)
SYMBOL_NAME_LABEL(start)
start:
.align 8
/*start:*/
jmp boot_entry
/*
Here we go with the multiboot header...
---------------------------------------
*/
.align 8
boot_hdr:
.align 8
.long MULTIBOOT_MAGIC
.long MULTIBOOT_FLAGS
/* Checksum */
.long -(MULTIBOOT_MAGIC+MULTIBOOT_FLAGS)
#ifndef __LINUX__ /* COFF mode */
.long boot_hdr
/* .long SYMBOL_NAME(start)*/
.long start
.long _edata
.long _end
.long boot_entry
#endif
boot_entry: /* Just a brief debug check */
#ifdef __DEBUG__
/* A Brown 1 should appear... */
movl $0xB8000,%edi
addl $158,%edi
movb $'1',%gs:0(%edi)
incl %edi
movb $6,%gs:0(%edi)
#endif
/*
* Hopefully if it gets here, CS & DS are
* Correctly set for FLAT LINEAR mode
*/
/* Test if GDT is usable */
movl %gs:0(%ebx),%ecx
andl $0x0200,%ecx /* MB_INFO_BOOT_LOADER_NAME */
movl $0xB8000,%edi
addl $150,%edi
movb $'1',%gs:0(%edi)
incl %edi
movb $6,%gs:0(%edi)
jz GDT_is_not_OK
incl %edi
movb $'2',%gs:0(%edi)
incl %edi
movb $6,%gs:0(%edi)
 
movl %gs:64(%ebx), %ebp /* Name Address... */
cmpb $'X', %gs:0(%ebp)
je GDT_is_OK
GDT_is_not_OK:
/*
* Fix the X_RM_BACK_GATE with the address of halt()
*/
 
/* Now I test if the check mechanism is OK... */
movl $SYMBOL_NAME(halt),%eax
movw %ax,%gs:rmBckGateFix1
shrl $16,%eax
movw %ax,%gs:rmBckGateFix2
/* Load GDT, using the predefined assignment! */
lgdt GDT_descr
movl $0xB8000,%edi
addl $146,%edi
movb $'0',%gs:0(%edi)
incl %edi
movb $6,%gs:0(%edi)
GDT_is_OK: movw $(X_FLATDATA_SEL),%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%ss
movw %ax,%fs
movw %ax,%gs
movl $tos,%esp
movl $base,SYMBOL_NAME(_stkbase)
movl $tos,SYMBOL_NAME(_stktop)
/* Store the MULTIBOOT informations */
movl %eax,SYMBOL_NAME(mb_signature)
movl %ebx,SYMBOL_NAME(mbi)
/* Store the X passed GDT address!
* If GDT is not available is a dummy instruction!
*/
sgdt GDT_descr
 
/* Now probably is the case to load CS... */
ljmp $X_FLATCODE_SEL, $load_cs
 
load_cs:
/* Load IDT */
lidt IDT_descr
cld
call SYMBOL_NAME(_startup)
/* Well I hope when I reach this
The X_RM_BACK_GATE has been setup correctly
even if the kernel has not been loaded through X!
*/
.byte 0x0EA /* Direct gate jmp */
.long 0
.word X_RM_BACK_GATE
 
/* Simple function to terminate PM application */
 
/* void __exit(int code) */
 
SYMBOL_NAME_LABEL(__exit)
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
.byte 0x0ea /* Direct gate jmp */
.long 0
.word X_RM_BACK_GATE
/shark/branches/xen/arch/x86/intevt.c
0,0 → 1,118
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Interrupt Events */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/mem.h>
#include <ll/i386/error.h>
#include <ll/i386/hw-arch.h>
#include <ll/i386/pit.h>
#include <ll/i386/pic.h>
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/ll-instr.h>
#include <ll/sys/ll/time.h>
#include <ll/sys/ll/event.h>
 
FILE(IntEvent);
 
extern int activeInt;
void (*evt_prol) (void) = NULL;
void (*evt_epil) (void) = NULL;
 
struct intentry irqs[16];
 
void irq_init(void)
{
int i;
 
/* Initialize the interrupt handlers list!!! */
for (i = 0; i < 16; i++) {
irqs[i].status = INTSTAT_FREE;
irqs[i].index = i;
irqs[i].handler = NULL; /* Paranoia */
irqs[i].par = NULL; /* Paranoia */
}
activeInt = 0;
}
 
int ll_ActiveInt(void)
{
return activeInt;
}
 
int irq_bind(int irq, void (*handler) (void *p), DWORD flags)
{
 
if ((irqs[irq].status != INTSTAT_FREE) &&
((flags & INT_FORCE) != INT_FORCE)) {
return -1;
}
 
irqs[irq].status = INTSTAT_ASSIGNED;
 
if (handler != NULL) {
irqs[irq].handler = handler;
irqs[irq].par = &(irqs[irq].index);
irqs[irq].flags = flags;
} else {
irqs[irq].status = INTSTAT_FREE;
}
 
return 1;
}
 
void act_int(BYTE n)
{
static int ai_called = 0;
 
if ((n >= PIC1_BASE) && (n < PIC1_BASE + 8)) {
n = n - PIC1_BASE;
} else if ((n >= PIC2_BASE) && (n < PIC2_BASE + 8)) {
n = n - PIC2_BASE + 8;
} else {
/* Wow... Here, we are in error... Return? */
return;
}
 
activeInt++;
if (activeInt == 1 && evt_prol != NULL) {
evt_prol();
}
if (irqs[n].status == INTSTAT_ASSIGNED) {
irqs[n].status = INTSTAT_BUSY;
if (irqs[n].flags & INT_PREEMPTABLE) {
sti();
}
irqs[n].handler(irqs[n].par);
if (irqs[n].flags & INT_PREEMPTABLE) {
cli();
}
irqs[n].status = INTSTAT_ASSIGNED;
}
ai_called++;
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
}
 
 
/shark/branches/xen/arch/x86/advtimer.c
0,0 → 1,513
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Advanced Timer Managment
* Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
*/
 
#include <arch/i386/stdlib.h>
#include <ll/i386/error.h>
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/i386/pic.h>
#include <ll/i386/apic.h>
#include <ll/i386/64bit.h>
#include <ll/sys/ll/event.h>
#include <ll/sys/ll/time.h>
#include <ll/i386/advtimer.h>
 
#define CALIBRATE_USING_CMOS
 
unsigned long long init_tsc;
unsigned long long * ptr_init_tsc = &init_tsc;
 
struct timespec init_time;
struct timespec * ptr_init_time = &init_time;
 
unsigned int clk_per_msec = 0;
unsigned int apic_clk_per_msec = 0;
unsigned int apic_set_limit = 0;
 
/* Precalcolated const
used in ll_read_timer */
unsigned int clk_opt_0 = 0;
unsigned int clk_opt_1 = 0;
unsigned int clk_opt_2 = 0;
unsigned int clk_opt_3 = 0;
unsigned int clk_opt_4 = 0;
unsigned int clk_opt_5 = 0;
 
unsigned char save_CMOS_regA;
unsigned char save_CMOS_regB;
 
unsigned long msr_original_low, msr_original_high;
 
unsigned char X86_tsc = 0;
unsigned char X86_apic = 0;
unsigned char use_tsc = 0;
unsigned char use_apic = 0;
 
#ifdef CONFIG_MELAN
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
#else
# define CLOCK_TICK_RATE 1193182 /* Underlying HZ */
#endif
 
#define COUNTER_END 100
 
#define barrier() __asm__ __volatile__("" ::: "memory");
 
//TSC Calibration (idea from the linux kernel code)
void ll_calibrate_tsc(void)
{
 
unsigned long long start;
unsigned long long end;
unsigned long long dtsc;
unsigned int start_8253, end_8253, delta_8253;
 
outp(0x61, (inp(0x61) & ~0x02) | 0x01);
 
outp(0x43,0xB0); /* binary, mode 0, LSB/MSB, Ch 2 */
outp(0x42,0xFF); /* LSB of count */
outp(0x42,0xFF); /* MSB of count */
barrier();
rdtscll(start);
barrier();
outp(0x43,0x00);
start_8253 = inp(0x42);
start_8253 |= inp(0x42) << 8;
barrier();
rdtscll(start);
barrier();
do {
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
} while (end_8253 > COUNTER_END);
 
barrier();
rdtscll(end);
barrier();
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
barrier();
rdtscll(end);
barrier();
 
//Delta TSC
dtsc = end - start;
 
//Delta PIT
delta_8253 = start_8253 - end_8253;
 
if (delta_8253 > 0x20000) {
message("Error calculating Delta PIT\n");
ll_abort(10);
}
 
message("Delta TSC = %10d\n",(int)dtsc);
 
message("Delta PIT = %10d\n",delta_8253);
 
clk_per_msec = dtsc * CLOCK_TICK_RATE / delta_8253 / 1000;
message("Calibrated Clk_per_msec = %10d\n",clk_per_msec);
}
 
#define CMOS_INIT 0
#define CMOS_BEGIN 1
#define CMOS_START 2
#define CMOS_END 3
 
int cmos_calibrate_status = CMOS_INIT;
unsigned long long irq8_start;
unsigned long long irq8_end;
 
void calibrate_tsc_IRQ8(void *p)
{
unsigned char set;
 
CMOS_READ(0x0C,set);
 
barrier();
rdtscll(irq8_end);
barrier();
 
if (cmos_calibrate_status == CMOS_START) {
cmos_calibrate_status = CMOS_END;
}
 
if (cmos_calibrate_status == CMOS_BEGIN) {
irq8_start = irq8_end;
cmos_calibrate_status = CMOS_START;
}
 
if (cmos_calibrate_status == CMOS_INIT) {
cmos_calibrate_status = CMOS_BEGIN;
}
}
 
//TSC Calibration using RTC
void ll_calibrate_tsc_cmos(void)
{
unsigned long long dtsc;
 
irq_bind(8, calibrate_tsc_IRQ8, INT_FORCE);
 
CMOS_READ(0x0A,save_CMOS_regA);
CMOS_READ(0x0B,save_CMOS_regB);
CMOS_WRITE(0x0A,0x2F); // Set 2 Hz Periodic Interrupt
CMOS_WRITE(0x0B,0x42); // Enable Interrupt
 
irq_unmask(8);
sti();
 
while (cmos_calibrate_status != CMOS_END) {
barrier();
}
cli();
 
dtsc = irq8_end - irq8_start;
 
clk_per_msec = dtsc / 500;
clk_opt_0 = (unsigned int)(dtsc);
clk_opt_1 = (unsigned int)((unsigned long long)(dtsc << 1));
clk_opt_2 = (unsigned int)((unsigned long long)(dtsc << 33) / 1000000000L);
clk_opt_3 = (unsigned int)((unsigned long long)(dtsc << 32) / 1000000000L);
clk_opt_4 = (unsigned int)((unsigned long long)(dtsc << 31) / 1000000000L);
clk_opt_5 = (unsigned int)((unsigned long long)(dtsc << 30) / 1000000000L);
 
message("Calibrated CPU Clk/msec = %10u\n",clk_per_msec);
 
#ifdef __O1000__
if (clk_per_msec < 1000000) {
message("Timer Optimization CPU < 1 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
 
#ifdef __O2000__
if (clk_per_msec < 2000000 && clk_per_msec >= 1000000) {
message("Timer Optimization 1 GHz < CPU < 2 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
 
#ifdef __O4000__
if (clk_per_msec < 4000000 && clk_per_msec >= 2000000) {
message("Timer Optimization 2 GHz < CPU < 4 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
 
irq_mask(8);
 
CMOS_WRITE(0x0A,save_CMOS_regA);
CMOS_WRITE(0x0B,save_CMOS_regB);
}
 
int apic_get_maxlvt(void)
{
unsigned int v, ver, maxlvt;
 
v = apic_read(APIC_LVR);
ver = GET_APIC_VERSION(v);
/* 82489DXs do not report # of LVT entries. */
maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(v) : 2;
return maxlvt;
}
 
/* Clear local APIC, from Linux kernel */
void clear_local_APIC(void)
{
int maxlvt;
unsigned long v;
 
maxlvt = apic_get_maxlvt();
 
/*
* Masking an LVT entry on a P6 can trigger a local APIC error
* if the vector is zero. Mask LVTERR first to prevent this.
*/
if (maxlvt >= 3) {
v = 0xFF; /* any non-zero vector will do */
apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
}
/*
* Careful: we have to set masks only first to deassert
* any level-triggered sources.
*/
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
v = apic_read(APIC_LVT0);
apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
v = apic_read(APIC_LVT1);
apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
if (maxlvt >= 4) {
v = apic_read(APIC_LVTPC);
apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
}
 
/*
* Clean APIC state for other OSs:
*/
apic_write_around(APIC_LVTT, APIC_LVT_MASKED);
apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
apic_write_around(APIC_LVT1, APIC_LVT_MASKED);
if (maxlvt >= 3)
apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
if (maxlvt >= 4)
apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
v = GET_APIC_VERSION(apic_read(APIC_LVR));
if (APIC_INTEGRATED(v)) { /* !82489DX */
if (maxlvt > 3)
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
}
}
 
void disable_local_APIC(void)
{
unsigned long value;
 
clear_local_APIC();
 
/*
* Disable APIC (implies clearing of registers
* for 82489DX!).
*/
value = apic_read(APIC_SPIV);
value &= ~APIC_SPIV_APIC_ENABLED;
apic_write_around(APIC_SPIV, value);
}
 
#define SPURIOUS_APIC_VECTOR 0xFF
 
/*
* Setup the local APIC, minimal code to run P6 APIC
*/
void setup_local_APIC (void)
{
unsigned long value;
 
/* Pound the ESR really hard over the head with a big hammer - mbligh */
 
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
 
value = APIC_SPIV_FOCUS_DISABLED | APIC_SPIV_APIC_ENABLED | SPURIOUS_APIC_VECTOR;
apic_write_around(APIC_SPIV, value);
 
value = APIC_DM_EXTINT | APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT0, value);
 
value = APIC_DM_NMI;
apic_write_around(APIC_LVT1, value);
 
apic_write(APIC_ESR, 0);
}
 
void disable_APIC_timer(void)
{
unsigned long v;
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
}
void enable_APIC_timer(void)
{
unsigned long v;
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
}
 
#define LOCAL_TIMER_VECTOR 0x39
 
/* Set APIC Timer... from Linux kernel */
void setup_APIC_timer()
{
unsigned int lvtt1_value;
 
lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
apic_write_around(APIC_LVTT, lvtt1_value);
 
/*
* Divide PICLK by 1
*/
apic_write_around(APIC_TDCR, APIC_TDR_DIV_1);
 
apic_write_around(APIC_TMICT, MAX_DWORD);
 
disable_APIC_timer();
}
 
#define APIC_LIMIT 0xFF000000
#define APIC_SET_LIMIT 10
 
void ll_calibrate_apic(void)
{
unsigned int apic_start = 0, apic_end = 0, dapic;
unsigned long long tsc_start = 0, tsc_end = 0, dtsc;
unsigned int tmp_value;
 
tmp_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | LOCAL_TIMER_VECTOR;
apic_write_around(APIC_LVTT, tmp_value);
 
apic_write_around(APIC_TDCR, APIC_TDR_DIV_1);
 
apic_write(APIC_TMICT, MAX_DWORD);
 
enable_APIC_timer();
 
barrier();
rdtscll(tsc_start);
barrier();
apic_start = apic_read(APIC_TMCCT);
barrier();
 
while (apic_read(APIC_TMCCT) > APIC_LIMIT) {
barrier();
rdtscll(tsc_end);
}
 
barrier();
rdtscll(tsc_end);
barrier();
apic_end = apic_read(APIC_TMCCT);
barrier();
 
disable_APIC_timer();
 
dtsc = tsc_end - tsc_start;
dapic = apic_start - apic_end;
apic_clk_per_msec = (unsigned long long)(clk_per_msec) * (unsigned long long)(dapic) / dtsc;
apic_set_limit = ((apic_clk_per_msec / 100) != 0) ? (apic_clk_per_msec/100) : APIC_SET_LIMIT;
 
message("Calibrated APIC Clk/msec = %10d\n",apic_clk_per_msec);
}
 
void ll_init_advtimer()
{
 
#ifdef __TSC__
use_tsc = X86_tsc;
 
#ifdef __APIC__
use_apic = X86_apic;
#endif
 
#endif
 
if (use_tsc == 0) use_apic = 0;
 
if (use_tsc) {
#ifdef CALIBRATE_USING_CMOS
ll_calibrate_tsc_cmos();
#else
ll_calibrate_tsc();
#endif
 
rdtscll(init_tsc); // Read start TSC
init_time.tv_sec = 0;
init_time.tv_nsec = 0;
 
if (use_apic) {
rdmsr(APIC_BASE_MSR, msr_original_low, msr_original_high);
wrmsr(APIC_BASE_MSR, msr_original_low|(1<<11), 0);
 
clear_local_APIC();
 
ll_calibrate_apic();
 
setup_local_APIC();
setup_APIC_timer();
}
}
}
 
void ll_restore_adv()
{
SYS_FLAGS f;
 
/* Disable APIC */
if (use_apic) {
 
f = ll_fsave();
 
disable_APIC_timer();
 
wrmsr(APIC_BASE_MSR, msr_original_low, msr_original_high);
 
ll_frestore(f);
}
}
 
void ll_scale_advtimer(unsigned int old_f, unsigned int new_f)
{
unsigned long long dtsc;
unsigned long temp;
struct timespec temp_time;
SYS_FLAGS f;
 
if (use_tsc) {
f = ll_fsave();
 
__asm__("cpuid"::"a" (0), "b" (0), "c" (0), "d" (0));
ll_read_timespec(&temp_time); // Set new start TimeSpec
TIMESPEC_ASSIGN(&init_time,&temp_time);
rdtscll(init_tsc); // Set new start TSC
__asm__("cpuid"::"a" (0), "b" (0), "c" (0), "d" (0));
mul32div32to32(clk_per_msec,new_f,old_f,temp);
clk_per_msec = temp;
dtsc = (unsigned long long)(clk_per_msec) * 500;
clk_opt_0 = (unsigned int)(dtsc);
clk_opt_1 = (unsigned int)((unsigned long long)(dtsc << 1));
clk_opt_2 = (unsigned int)((unsigned long long)(dtsc << 33) / 1000000000L);
clk_opt_3 = (unsigned int)((unsigned long long)(dtsc << 32) / 1000000000L);
clk_opt_4 = (unsigned int)((unsigned long long)(dtsc << 31) / 1000000000L);
clk_opt_5 = (unsigned int)((unsigned long long)(dtsc << 30) / 1000000000L);
ll_frestore(f);
}
}
/shark/branches/xen/arch/x86/xinfo.c
0,0 → 1,102
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Access the info stucture */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/mb-info.h>
#include <ll/i386/x-bios.h>
 
FILE(X-Info);
 
/*
The x_bios is stored in the low memory area and contains all the
stuff necessary to perform a BIOS call from PM; it can be accessed
using a linear pointer, which is returned by the following call!
*/
 
X_CALLBIOS * x_bios_address(void)
{
X_CALLBIOS *a = (X_CALLBIOS *)GDT_read(X_CALLBIOS_SEL,NULL,NULL,NULL);
return (a);
}
 
/* Stuff information retrieving function */
 
WORD X_version(void)
{
X_CALLBIOS *x_bios = x_bios_address();
return(x_bios->_ver);
}
 
void X_meminfo(LIN_ADDR *b1,DWORD *s1,LIN_ADDR *b2,DWORD *s2)
{
struct multiboot_info *mbi = mbi_address();
int x = 0;
 
if (mbi->flags & MB_INFO_BOOT_LOADER_NAME) {
char *name;
 
name = (char *) mbi->boot_loader_name;
if (*name == 'X') {
x = 1;
}
}
if (x) {
if (b1 != NULL) *b1 = (LIN_ADDR)mbi->mem_upbase;
if (s1 != NULL) *s1 = mbi->mem_upper * 1024;
if (b2 != NULL) *b2 = (LIN_ADDR)mbi->mem_lowbase;
if (s2 != NULL) *s2 = mbi->mem_lower * 1024;
} else {
if (b1 != NULL) *b1 = (LIN_ADDR)0x100000;
if (s1 != NULL) *s1 = mbi->mem_upper * 1024;
if (b2 != NULL) *b2 = (LIN_ADDR)0x4000;
if (s2 != NULL) *s2 = mbi->mem_lower * 1024;
}
/*
#ifdef __OLD_MB__
if (b1 != NULL) *b1 = 0x100000;
if (s1 != NULL) *s1 = mbi->mem_upper;
if (b2 != NULL) *b2 = 0x4000;
if (s2 != NULL) *s2 = mbi->mem_lower;
#else
if (b1 != NULL) *b1 = mbi->mem_upbase;
if (s1 != NULL) *s1 = mbi->mem_upper;
if (b2 != NULL) *b2 = mbi->mem_lowbase;
if (s2 != NULL) *s2 = mbi->mem_lower;
#endif
*/
}
 
#ifdef CHECK
#include <cons.h>
/* Alert if a wrong addressing is intercepted */
/* Used only for debug purposes */
 
void check_addr(void *addr,char *caller)
{
extern DWORD _stktop;
if ((DWORD)(addr) < _stktop) {
cprintf("CRISIS! Addr : %lx(%lx) Caller was %s\n",(DWORD)(addr),_stktop,caller);
}
}
#endif
/shark/branches/xen/arch/x86/xdosf.c
0,0 → 1,234
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* DOS Interface toward disk */
 
#include <arch/string.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/i386/x-dos.h>
#include <ll/i386/x-dosmem.h>
 
FILE(X-Dos-File);
 
/* Basic DOS I/O Flag */
 
/*#define __DEBUG__*/
 
#define DOS_READ 0
#define DOS_WRITE 1
#define DOS_RW 2
 
#define DOS_BUFSIZE 1024 /* I/O auxiliary buffer */
#define DOS_MAXDESCR 16 /* Maximum number of DOS file */
 
static DOS_FILE DOS_descr[DOS_MAXDESCR];
/* I Hope this array is initialized with 0... */
static BYTE busy[DOS_MAXDESCR];
 
/* The Last DOS Error occurred! */
static unsigned _DOS_error = 0;
 
 
int DOS_init(void)
{
/* Init the DOS memory allocator */
DOS_mem_init();
 
/* TODO: Add a check if we are run through X */
return 1;
}
 
unsigned DOS_error(void)
{
unsigned v = _DOS_error;
_DOS_error = 0;
return(v);
}
 
DOS_FILE *DOS_fopen(char *name,char *mode)
{
X_REGS16 ir,or;
X_SREGS16 sr;
DOS_FILE *f;
register int i;
 
#ifdef __DEBUG__
char xname[80];
#endif
 
for (i = 0; busy[i] && i < DOS_MAXDESCR; i++);
/* Return NULL if no descriptor is available... */
if (i == DOS_MAXDESCR) return(NULL);
/* Otherwise, lock the descriptor & remember the index */
f = &DOS_descr[i]; busy[i] = 1; f->index = i;
/* Allocate a DOS buffer for the file name */
f->n1 = DOS_alloc(80);
strcpy(f->n2,name);
if (mode[0] == 'r') {
/* DOS Call: Intr 0x21
AH = 0x3D - Open existing file
AL = 0,1,2 - Read,Write, R/W
*/
f->mode = DOS_READ;
ir.h.ah = 0x3D;
ir.h.al = f->mode;
}
else if (mode[0] == 'w') {
/* DOS Call: Intr 0x21
AH = 0x3C - Create a file
AL = File attribute [0x20 = Standard,r/w,archive]
*/
f->mode = DOS_WRITE;
ir.h.ah = 0x3C;
ir.x.cx = 0x20;
}
f->offset = 0;
/* Copy th \0 also! */
memcpy(f->n1, name, strlen(name) + 1);
#ifdef __DEBUG__
memcpy(xname, f->n1, strlen(name) + 1);
message("Name is : %s -- Mode : %d\n",xname,f->mode);
#endif
 
/* Ask DOS to open File */
ir.x.dx = DOS_OFF(f->n1);
sr.ds = DOS_SEG(f->n1);
X_callBIOS(0x21,&ir,&or,&sr);
f->handle = (!(or.x.cflag) ? or.x.ax : -1);
 
if (f->handle == -1) {
/* DOS request failed! Release the used resources */
DOS_free(f->n1,80);
busy[i] = 0;
_DOS_error = or.x.ax;
return(NULL);
}
/* Allocate the DOS buffer for temporary I/O */
f->buf = DOS_alloc(DOS_BUFSIZE);
return(f);
}
 
void DOS_fclose(DOS_FILE *f)
{
X_REGS16 ir,or;
X_SREGS16 sr;
 
if (f == NULL || busy[f->index] == 0) return;
/* DOS Call: Intr 0x21
AH = 0x3E - Close a file
BX = File handle
*/
ir.h.ah = 0x3E;
ir.x.bx = f->handle;
X_callBIOS(0x21,&ir,&or,&sr);
DOS_free(f->buf,DOS_BUFSIZE);
DOS_free(f->n1,80);
busy[f->index] = 0;
}
 
DWORD DOS_fread(void *abuf,DWORD size,DWORD num,DOS_FILE *f)
{
X_REGS16 ir,or;
X_SREGS16 sr;
DWORD count = size*num,now = 0,chunk;
BYTE done = 0;
BYTE *buf = (BYTE *)(abuf);
while (done == 0) {
/* Fragment the read operation ... */
if (count > DOS_BUFSIZE) chunk = DOS_BUFSIZE;
else chunk = count;
/* DOS Call: Intr 0x21
AH = 0x3F - Read data using a file handle
BX = File handle
CX = Buffer size
DS:DX = Segment:Offset of the Buffer
*/
ir.h.ah = 0x3F;
ir.x.bx = f->handle;
ir.x.cx = chunk;
ir.x.dx = DOS_OFF(f->buf);
sr.ds = DOS_SEG(f->buf);
X_callBIOS(0x21,&ir,&or,&sr);
/* If it was OK ... */
if (!(or.x.cflag)) {
/* Copy data into application buffer */
memcpy(buf, f->buf, or.x.ax);
buf += or.x.ax;
now += or.x.ax;
f->offset += or.x.ax;
count -= or.x.ax;
/*
Finish if we have read all the data or
if we have read less data than how expected
*/
if (now == size*num || or.x.ax != chunk) done = 1;
} else {
done = -1;
_DOS_error = or.x.ax;
}
}
return(now);
}
 
DWORD DOS_fwrite(void *abuf,DWORD size,DWORD num,DOS_FILE *f)
{
X_REGS16 ir,or;
X_SREGS16 sr;
DWORD count = size*num,now = 0,chunk;
BYTE done = 0;
BYTE *buf = (BYTE *)(abuf);
while (done == 0) {
/* Fragment the write operation ... */
if (count > DOS_BUFSIZE) chunk = DOS_BUFSIZE;
else chunk = count;
/* Copy data from application buffer */
memcpy(f->buf, buf, chunk);
/* DOS Call: Intr 0x21
AH = 0x40 - Write data using a file handle
BX = File handle
CX = Buffer size
DS:DX = Segment:Offset of the Buffer
*/
ir.h.ah = 0x40;
ir.x.bx = f->handle;
ir.x.cx = chunk;
ir.x.dx = DOS_OFF(f->buf);
sr.ds = DOS_SEG(f->buf);
X_callBIOS(0x21,&ir,&or,&sr);
/* If it was OK ... */
if (!(or.x.cflag)) {
f->offset += or.x.ax;
count -= or.x.ax;
buf += or.x.ax;
now += or.x.ax;
if (now == size*num || or.x.ax != chunk) done = 1;
} else {
done = -1;
_DOS_error = or.x.ax;
}
}
return(now);
}
 
/shark/branches/xen/arch/x86/cxsw-2.c
0,0 → 1,169
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Routines that implements threads (creation, end, dump, and AS
assignment */
 
#include <arch/i386/stdio.h>
#include <ll/i386/mem.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
 
#include <ll/i386/tss-ctx.h>
#include <ll/sys/ll/ll-instr.h> /* Only for HW instr... */
#include <ll/sys/ll/ll-func.h>
 
FILE(KL-Context-Switch);
 
extern TSS TSS_table[TSSMax];
extern WORD TSS_control[TSSMax];
extern BYTE ll_FPU_stdctx[FPU_CONTEXT_SIZE];
 
#ifdef __VIRCSW__
extern unsigned short int currCtx;
extern int activeInt;
#endif
 
extern DWORD entrypoint;
 
/* Just a debugging function; it dumps the status of the TSS */
void dump_TSS(WORD sel)
{
BYTE acc,gran;
DWORD base,lim;
message("TR %x\n", sel);
sel = TSSsel2index(sel);
message("SS:SP %x:%lx\n", TSS_table[sel].ss, TSS_table[sel].esp);
message("Stack0 : %x:%lx\n", TSS_table[sel].ss0, TSS_table[sel].esp0);
message("Stack1 : %x:%lx\n", TSS_table[sel].ss1, TSS_table[sel].esp1);
message("Stack2 : %x:%lx\n", TSS_table[sel].ss2, TSS_table[sel].esp2);
message("CS : %x DS : %x\n", TSS_table[sel].cs, TSS_table[sel].ds);
sel = TSSindex2sel(sel);
message("Descriptor [%x] Info",sel);
base = GDT_read(sel,&lim,&acc,&gran);
message("Base : %lx Lim : %lx Acc : %x Gran %x\n", base, lim, (unsigned)(acc),(unsigned)(gran));
}
 
 
void ll_context_setspace(CONTEXT c, WORD as)
{
int index = TSSsel2index(c);
 
TSS_table[index].ss0 = as;
TSS_table[index].cs = as + 8;
TSS_table[index].es = as;
TSS_table[index].ds = as;
TSS_table[index].ss = as;
}
 
/* Initialize context -> TSS in 32 bit */
CONTEXT ll_context_create(void (*task)(void *p),BYTE *stack,
void *parm,void (*killer)(void),WORD control)
{
CONTEXT index = 0;
DWORD *stack_ptr = (DWORD *)stack;
 
/* Push onto stack the input parameter */
/* And the entry point to the task killer procedure */
stack_ptr--;
*stack_ptr = (DWORD)(parm);
stack_ptr--;
*stack_ptr = (DWORD)(killer);
/* Find a free TSS */
while ((TSS_control[index] & TSS_USED) && (index < TSSMain)) index++;
/* This exception would signal an error */
if (index >= TSSMain) {
message("No more Descriptors...\n");
return 0;
}
TSS_control[index] |= (TSS_USED | control);
/* Fill the TSS structure */
/* No explicit protection; use only one stack */
TSS_table[index].esp0 = (DWORD)(stack_ptr);
TSS_table[index].esp1 = 0;
TSS_table[index].esp2 = 0;
TSS_table[index].ss0 = get_DS();
TSS_table[index].ss1 = 0;
TSS_table[index].ss2 = 0;
/* No paging activated */
TSS_table[index].cr3 = 0;
/* Task entry point */
TSS_table[index].eip = (DWORD)(task);
/* Need only to unmask interrupts */
TSS_table[index].eflags = 0x00000200;
TSS_table[index].eax = 0;
TSS_table[index].ebx = 0;
TSS_table[index].ecx = 0;
TSS_table[index].edx = 0;
TSS_table[index].esi = 0;
TSS_table[index].edi = 0;
TSS_table[index].esp = (DWORD)(stack_ptr);
TSS_table[index].ebp = (DWORD)(stack_ptr);
TSS_table[index].cs = get_CS();
TSS_table[index].es = get_DS();
TSS_table[index].ds = get_DS();
TSS_table[index].ss = get_DS();
TSS_table[index].gs = X_FLATDATA_SEL;
TSS_table[index].fs = X_FLATDATA_SEL;
/* Use only the GDT */
TSS_table[index].ldt = 0;
TSS_table[index].trap = 0;
TSS_table[index].io_base = 0;
/* Fill in the coprocessor status */
memcpy(TSS_table[index].ctx_FPU,ll_FPU_stdctx,FPU_CONTEXT_SIZE);
/* Convert the index into a valid selector */
/* Which really represent CONTEXT */
return(TSSindex2sel(index));
}
 
 
/* Release the used TSS */
 
void ll_context_delete(CONTEXT c)
{
int index = TSSsel2index(c);
TSS_control[index] = 0;
}
 
#if 0 /* It does not work... Fix it!!! */
DWORD ll_push_func(void (*func)(void))
{
DWORD *p;
DWORD old;
 
p = (DWORD *)entrypoint;
old = *p;
 
*p = (DWORD)func;
return old;
}
#endif
 
/* Well this is used for debug purposes mainly; as the context is an */
/* abstract type, we must provide some function to convert in into a */
/* printable form; anyway this depend from the architecture as the context */
 
char *ll_context_sprintf(char *str, CONTEXT c)
{
ksprintf(str, "%x (Hex)", c);
return(str);
}
/shark/branches/xen/arch/x86/xbios.c
0,0 → 1,63
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* System calls for X extender */
/* BIOS Call from X (Basic Reflection Service) */
 
#include <ll/i386/hw-data.h>
#include <ll/i386/x-bios.h>
#include <ll/i386/mem.h>
 
#include <ll/i386/advtimer.h>
#include <ll/i386/apic.h>
 
FILE(X-BIOS);
 
/* The interface between X (and 32 bit PM) and BIOS (which runs at 16 bits */
/* It works as int86() standard library call */
 
void X_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s)
{
/* Assembler gate JMP instruction */
extern unsigned char use_apic;
extern void _x_callBIOS(void);
X_CALLBIOS *xbc = x_bios_address();
DWORD msr1 = 0,msr2 = 0;
 
/* Send interrupt request & register through the X_Info structure */
xbc->_irqno = service;
memcpy(&(xbc->_ir),in,sizeof(X_REGS16));
memcpy(&(xbc->_sr),s,sizeof(X_SREGS16));
if (use_apic) {
rdmsr(APIC_BASE_MSR,msr1,msr2);
disable_APIC_timer();
}
/* Back to RM to execute the BIOS routine */
_x_callBIOS();
 
/* Get the return register values */
if (use_apic) {
wrmsr(APIC_BASE_MSR,msr1,msr2);
enable_APIC_timer();
}
memcpy(out,&(xbc->_or),sizeof(X_REGS16));
memcpy(s,&(xbc->_sr),sizeof(X_SREGS16));
}
/shark/branches/xen/arch/x86/timeint.s
0,0 → 1,252
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Safe abort routine & timer asm handler */
 
.title "Timer.S"
 
#include <ll/i386/sel.h>
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
 
#include <ll/sys/ll/exc.h>
 
.data
 
ASMFILE(TimerHandler)
 
.extern JmpSel
.extern JmpZone
.globl SYMBOL_NAME(ll_clock)
.globl SYMBOL_NAME(last_handler)
/* Used as JMP entry point to check if a real */
/* context switch is necessary */
SYMBOL_NAME_LABEL(ll_clock) .int 0
SYMBOL_NAME_LABEL(last_handler) .long 0
 
.extern SYMBOL_NAME(periodic_wake_up)
.extern SYMBOL_NAME(oneshot_wake_up)
 
.text
.globl SYMBOL_NAME(ll_apic_timer)
/* APIC ll_timer */
 
SYMBOL_NAME_LABEL(ll_apic_timer)
pushal
pushw %ds
pushw %es
pushw %fs
pushw %gs
 
/* Send ACK to APIC */
movl $0xFEE000B0,%ebx
movl $0,(%ebx)
movw $(X_FLATDATA_SEL),%ax
movw %ax,%ds
movw %ax,%es
 
/* Call wake_up(actual_context) */
movl SYMBOL_NAME(ll_clock),%eax
incl %eax
movl %eax,SYMBOL_NAME(ll_clock)
/* The following could be optimized a little... */
xorl %ebx, %ebx
movw %ss, %bx
/* We must switch to a ``safe stack'' */
/*
* OK, this is the idea: in %esp we have the address of the
* stack pointer in the APPLICATION address space...
* We assume that address spaces are implemented through segments...
* What we have to do is to add the segment base to %esp:
* - Load the GDT base in a register
* - Add DS * 8 to that value
* - Read the corresponding GDT entry (the segment descriptor)
* - Compute the base...
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2)
*/
movl SYMBOL_NAME(GDT_base), %edi
addl %ebx, %edi
xorl %ebx, %ebx
movb 7(%edi), %bh
movb 4(%edi), %bl
shl $16, %ebx
movw 2(%edi), %bx
/* Is it correct? I think so... Test it!!! */
addl %ebx, %esp
/* Save EBX for returning to our stack... */
movw %ds, %cx
movw %ss, %dx
movw %cx, %ss
pushl %ebx
pushl %edx
cld
movl SYMBOL_NAME(timermode), %eax
cmpl $1, %eax
je apic_oneshot
call SYMBOL_NAME(periodic_wake_up)
jmp apic_Timer_OK
apic_oneshot: call SYMBOL_NAME(oneshot_wake_up)
apic_Timer_OK:
/* Restore ESP */
popl %edx
popl %ebx /* We must subtract it from ESP...*/
subl %ebx, %esp
movw %dx, %ss
#ifdef __VIRCSW__
 
movw SYMBOL_NAME(currCtx), %ax
cmpw %ax,JmpSel
je apic_NoPreempt2
movw %ax,JmpSel
ljmp *JmpZone /* DISPATCH! */
#endif
apic_NoPreempt2:
 
cmpl $0, SYMBOL_NAME(last_handler)
je apic_nohandler
movl SYMBOL_NAME(last_handler), %ebx
call *%ebx
apic_nohandler:
 
popw %gs
popw %fs
popw %es
popw %ds
popal
iret
 
.globl SYMBOL_NAME(ll_timer)
/* This is the timer handler; it reloads for safety the DS register; this */
/* prevents from mess when timer interrupts linear access to memory (not in */
/* ELF address space); then EOI is sent in order to detect timer overrun */
/* The high level kernel procedure wake_up() is called to perform the */
/* preeption at higher level (process descriptos); the resulting context */
/* if different from the old one is used to trigger the task activation. */
 
SYMBOL_NAME_LABEL(ll_timer)
pushal
pushw %ds
pushw %es
pushw %fs
pushw %gs
 
/* Send ACK to master PIC */
movb $0x20,%al
movl $0x20,%edx
outb %al,%dx
movw $(X_FLATDATA_SEL),%ax
movw %ax,%ds
movw %ax,%es
 
/* Call wake_up(actual_context) */
movl SYMBOL_NAME(ll_clock),%eax
incl %eax
movl %eax,SYMBOL_NAME(ll_clock)
/* The following could be optimized a little... */
xorl %ebx, %ebx
movw %ss, %bx
/* We must switch to a ``safe stack'' */
/*
* OK, this is the idea: in %esp we have the address of the
* stack pointer in the APPLICATION address space...
* We assume that address spaces are implemented through segments...
* What we have to do is to add the segment base to %esp:
* - Load the GDT base in a register
* - Add DS * 8 to that value
* - Read the corresponding GDT entry (the segment descriptor)
* - Compute the base...
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2)
*/
movl SYMBOL_NAME(GDT_base), %edi
addl %ebx, %edi
xorl %ebx, %ebx
movb 7(%edi), %bh
movb 4(%edi), %bl
shl $16, %ebx
movw 2(%edi), %bx
/* Is it correct? I think so... Test it!!! */
addl %ebx, %esp
/* Save EBX for returning to our stack... */
movw %ds, %cx
movw %ss, %dx
movw %cx, %ss
pushl %ebx
pushl %edx
cld
movl SYMBOL_NAME(timermode), %eax
cmpl $1, %eax
je oneshot
call SYMBOL_NAME(periodic_wake_up)
jmp goon
oneshot: call SYMBOL_NAME(oneshot_wake_up)
jmp Timer_OK
goon:
/* This is the overrun test */
/* Do it after sending EOI to master PIC */
 
movb $0x0A,%al
movl $0x020,%edx
outb %al,%dx
inb %dx,%al
testb $1,%al
jz Timer_OK
movl $(CLOCK_OVERRUN),%eax
pushl %eax
call SYMBOL_NAME(ll_abort)
 
Timer_OK:
/* Restore ESP */
popl %edx
popl %ebx /* We must subtract it from ESP...*/
subl %ebx, %esp
movw %dx, %ss
#ifdef __VIRCSW__
 
movw SYMBOL_NAME(currCtx), %ax
cmpw %ax,JmpSel
je NoPreempt2
movw %ax,JmpSel
ljmp *JmpZone /* DISPATCH! */
#endif
NoPreempt2:
 
cmpl $0, SYMBOL_NAME(last_handler)
je nohandler
movl SYMBOL_NAME(last_handler), %ebx
call *%ebx
nohandler:
 
popw %gs
popw %fs
popw %es
popw %ds
popal
iret
/shark/branches/xen/arch/x86/cpu2.s
0,0 → 1,257
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* CPU detection code */
 
.title "CPU2.S"
 
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
 
/*
* The following code has been extracted by Intel AP-485
* Application Note: Intel Processor Identification with CPUID instruction
*/
 
.data
 
ASMFILE(CPU2)
 
.globl SYMBOL_NAME(X86_fpu)
 
SYMBOL_NAME_LABEL(X86_fpu) .byte 0
SYMBOL_NAME_LABEL(X86_cpu) .byte 0
fpu_status: .word 0
 
/*
struct CPU {
DWORD X86_cpu; 0
DWORD X86_cpuIdFlag; 4
DWORD X86_vendor_1; 8
DWORD X86_vendor_2; 12
DWORD X86_vendor_3; 16
DWORD X86_signature; 20
DWORD X86_IntelFeature_1; 24
DWORD X86_IntelFeature_2; 28
DWORD X86_StandardFeature; 32
}
*/
 
.text
 
.globl SYMBOL_NAME(X86_get_CPU)
.globl SYMBOL_NAME(X86_get_FPU)
.globl SYMBOL_NAME(X86_is386)
.globl SYMBOL_NAME(X86_isCyrix)
.globl SYMBOL_NAME(X86_hasCPUID)
.globl SYMBOL_NAME(X86_enable_cyrix_cpuid)
 
SYMBOL_NAME_LABEL(X86_is386)
pushfl
popl %eax
movl %eax, %ecx
xorl $0x40000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmp %ecx, %eax
jz is386
pushl %ecx
popfl
movl $0, %eax
ret
is386:
movl $1, %eax
ret
 
SYMBOL_NAME_LABEL(X86_enable_cyrix_cpuid)
pushfl
cli
/* Get Cyrix reg c3h */
movb $0xc3,%al
outb %al,$0x22
inb $0x23,%al
/* Enable config access */
movb %al,%cl
movb %al,%bl
andb $0xf,%bl
orb $0x10,%bl
/* Set Cyrix reg c3h */
movb $0xc3,%al
outb %al,$0x22
movb %bl,%al
outb %al,$0x23
/* Get Cyrix reg e8 */
movb $0xe8,%al
outb %al,$0x22
inb $0x23,%al
/* Set "CPUID" bit */
orb $0x80,%al
movb %al,%bl
/* Set Cyrix reg e8 */
movb $0xe8,%al
outb %al,$0x22
movb %bl,%al
outb %al,$0x23
/* Get Cyrix reg fe */
movb $0xfe,%al
outb %al,$0x22
inb $0x23,%al
/* Is CPU a 6x86(L)? */
andb $0xf0,%al
cmpb $0x30,%al
jne not6x86
/* Get Cyrix reg e9 */
movb $0xe9,%al
outb %al,$0x22
inb $0x23,%al
/* Fix 6x86 SLOP bug */
andb $0xfd,%al
movb %al,%bl
/* Set Cyrix reg e9 */
movb $0xe9,%al
outb %al,$0x22
movb %bl,%al
outb %al,$0x23
not6x86:
/* Set Cyrix reg c3 */
movb $0xc3,%al
outb %al,$0x22
movb %cl,%al
outb %al,$0x23
/* Disable suspended mode */
movb $0xc2,%al
outb %al,$0x22
inb $0x23,%al
andb $0x7F,%al
movb %al,%bl
movb $0xc2,%al
outb %al,$0x22
movb %bl,%al
outb %al,$0x23
 
popfl
ret
 
SYMBOL_NAME_LABEL(X86_hasCPUID)
pushfl
popl %eax
movl %eax, %ecx
xorl $0x200000, %eax
pushl %eax
popfl
pushfl
popl %eax
xorl %ecx, %eax
je noCPUID
 
pushl %ecx /* Restore the old EFLAG value... */
popfl
movl $1, %eax
ret
noCPUID:
movl $0, %eax
ret
 
SYMBOL_NAME_LABEL(X86_isCyrix)
xorw %ax, %ax
sahf
mov $5, %ax
mov $2, %bx
divb %bl
lahf
cmpb $2, %ah
jne noCyrix
movl $1, %eax
ret
noCyrix:
movl $0, %eax
ret
 
SYMBOL_NAME_LABEL(X86_get_FPU)
/* First of all, set the FPU type to 0... */
movb $0, SYMBOL_NAME(X86_fpu)
fninit
/* Let's give some time to the FPU...
* We cannot use WAIT 'cause we don't know if an FPU is present...
*/
movl $2, %ecx
here:
loop here
movw $0x5a5a, fpu_status
fnstsw fpu_status
/* Guys, I really don't know when to wai and when not...
*/
movl $2, %ecx
here1:
loop here1
movw fpu_status, %ax
cmpb $0, %al
jne endFPUProc
 
chkCW:
/* OK, if we are here, we have some kind of FPU... */
fnstcw fpu_status
 
/* Guys, I really don't know when to wai and when not...
*/
movl $2, %ecx
here2:
loop here2
movw fpu_status, %ax
andw $0x103f, %ax
cmpw $0x03F, %ax
jne endFPUProc
/* ... Err... I was wrong :(. Here we are sure to have an FPU */
movb $1, SYMBOL_NAME(X86_fpu)
chkInf:
/* Well... I assume that if we arrive to X86_get_FPU, we are running on a
* 386+ processor... Hence, the following is a complete nonsense!!!
* I'm commenting it out, we will see...
*/
#if 0
/* Um... If we have a -386, end of the story! */
cmpb $3, SYMBOL_NAME(X86_cpu)
jle endFPUProc
movb $2, SYMBOL_NAME(X86_fpu)
fld1
fldz
fdivp
fld %st
fchs
fcompp
fstsw fpu_status
wait
sahf
jz endFPUProc
movb $3, SYMBOL_NAME(X86_fpu)
#else
movb $3, SYMBOL_NAME(X86_fpu)
#endif
endFPUProc:
ret
/shark/branches/xen/arch/x86/xdosm.c
0,0 → 1,125
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* This file contains the DOS memory allocator */
 
#include <ll/i386/mem.h>
#include <ll/i386/x-bios.h>
#include <ll/i386/x-dosmem.h>
#include <ll/i386/error.h>
 
FILE(X-Dos-Memory);
 
/*
We do not use the standard K&R pointer based memory allocator!
This is because we cannot do pointer tricks easily with the GCC
which only handles explicitely 32 bit non segmented address space.
So we cannot use far pointers, and we cannot chain buckets of memory
which are located in low memory area, beyond the accessibility
of the ELF address space.
A static allocation is so preferred; this should not give trouble
since DOS memory is only used for reflection related purposes
*/
 
#define MAX_PARTITION 50 /* Max available partition */
 
static struct {
BYTE used;
LIN_ADDR addr;
DWORD size;
} mem_table[MAX_PARTITION];
 
static int inited = 0;
 
void DOS_dump_mem(void)
{
register int i;
for (i = 0; i < MAX_PARTITION; i++) {
if (mem_table[i].used) message("(%d) Addr : %p Size : %lu/%lx\n",
i, mem_table[i].addr,
mem_table[i].size, mem_table[i].size);
}
}
 
__attribute__ ((weak)) void DOS_mem_init(void)
{
register int i;
 
if (inited == 0) {
mem_table[0].used = TRUE;
X_meminfo(NULL,NULL,&(mem_table[0].addr),&(mem_table[0].size));
for (i = 1; i < MAX_PARTITION; i++) mem_table[i].used = FALSE;
} else {
inited = 1;
}
}
 
/*__attribute__ ((weak)) LIN_ADDR DOS_alloc(DWORD s)
{
LIN_ADDR p = 0;
int i = 0;
 
while (i < MAX_PARTITION && p == NULL) {
if (mem_table[i].used && (mem_table[i].size >= s))
p = mem_table[i].addr;
else i++;
}
if (p != 0) {
if (mem_table[i].size > s) {
mem_table[i].size -= s;
mem_table[i].addr += s;
}
else mem_table[i].used = FALSE;
}
return(p);
}
 
__attribute__ ((weak)) int DOS_free(LIN_ADDR p,DWORD s)
{
register int i = 1;
unsigned i1 = 0, i2 = 0;
 
while (i < MAX_PARTITION && ((i1 == 0) || (i2 == 0)) ) {
if (mem_table[i].used) {
if (mem_table[i].addr + mem_table[i].size == p) i1 = i;
if (mem_table[i].addr == p + s) i2 = i;
}
i++;
}
if (i1 != 0 && i2 != 0) {
mem_table[i1].size += mem_table[i2].size + s;
mem_table[i2].used = FALSE;
}
else if (i1 == 0 && i2 != 0) {
mem_table[i2].addr = p;
mem_table[i2].size += s;
}
else if (i1 != 0 && i2 == 0) mem_table[i1].size += s;
else {
i = 0;
while (i < MAX_PARTITION && (mem_table[i].used == TRUE)) i++;
if (i == MAX_PARTITION) return(FALSE);
mem_table[i].addr = p;
mem_table[i].size = s;
mem_table[i].used = TRUE;
}
return(TRUE);
}*/
/shark/branches/xen/arch/x86/ccpu.c
0,0 → 1,97
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* CPU detection code */
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-arch.h>
#include <ll/i386/mem.h>
#include <ll/i386/advtimer.h>
#include <ll/i386/apic.h>
 
FILE(Cpu-C);
 
INLINE_OP void cpuid(DWORD a, DWORD *outa, DWORD *outb, DWORD *outc, DWORD *outd)
{
#ifdef __OLD_GNU__
__asm__ __volatile__ (".byte 0x0F,0xA2"
#else
__asm__ __volatile__ ("cpuid"
#endif
: "=a" (*outa),
"=b" (*outb),
"=c" (*outc),
"=d" (*outd)
: "a" (a));
}
 
void X86_get_CPU(struct ll_cpuInfo *p)
{
DWORD tmp;
 
memset(p, 0, sizeof(struct ll_cpuInfo));
if (X86_is386()) {
p->X86_cpu = 3;
return;
}
 
if (X86_isCyrix()) {
X86_enable_cyrix_cpuid();
}
 
if (X86_hasCPUID()) {
p->X86_cpuIdFlag = 1;
p->X86_cpu = 5;
cpuid(0, &tmp, &(p->X86_vendor_1),
&(p->X86_vendor_3),
&(p->X86_vendor_2));
if (tmp >= 1) {
 
cpuid(1, &(p->X86_signature),
&(p->X86_IntelFeature_1),
&(p->X86_IntelFeature_2),
&(p->X86_StandardFeature));
#ifdef __APIC__
if ((p->X86_StandardFeature >> 5) & 1) {
 
unsigned long msr_original_low, msr_original_high;
rdmsr(APIC_BASE_MSR, msr_original_low, msr_original_high);
wrmsr(APIC_BASE_MSR, msr_original_low|(1<<11), 0);
cpuid(1, &(p->X86_signature),
&(p->X86_IntelFeature_1),
&(p->X86_IntelFeature_2),
&(p->X86_StandardFeature));
 
wrmsr(APIC_BASE_MSR, msr_original_low, msr_original_high);
 
}
#endif
}
} else {
p->X86_cpu = 4;
if (X86_isCyrix()) {
p->X86_cpu = 11;
}
/* Need tests for AMD and others... */
}
}
/shark/branches/xen/arch/x86/fpu.c
0,0 → 1,90
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/*
FPU Context switch & management functions!
Generic 32 bit module
*/
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/mem.h>
 
#include <ll/i386/tss-ctx.h>
 
FILE(FPU);
 
extern TSS main_tss;
 
BYTE LL_FPU_savearea[FPU_CONTEXT_SIZE]; /* Global FPU scratch SaveArea */
#ifdef __FPU_DEBUG__
long int ndp_called = 0,ndp_switched = 0;
#endif
 
/* FPU context management */
static TSS *LL_has_FPU = &main_tss;
 
/* As the 8086 does not have an hardware mechanism to support task */
/* switch, also the FPU context switch is implemented via software. */
/* When a preemption occurs, if the task is marked as a MATH task, the */
/* preemption routine will save/restore the FPU context. */
/* The hook is called whenever a FPU context switch is necessarty */
 
void ll_FPU_hook(void)
{
CONTEXT current;
TSS *base;
 
current = get_TR();
base = (TSS *)GDT_read(current, NULL, NULL, NULL);
 
clts();
#ifdef __FPU_DEBUG__
ndp_called++;
#endif
if (LL_has_FPU == base) return;
#ifdef __FPU_DEBUG__
ndp_switched++;
#endif
 
#if 0
LL_FPU_save();
memcpy(TSS_table[LL_has_FPU].ctx_FPU,LL_FPU_savearea,FPU_CONTEXT_SIZE);
#else
save_fpu(LL_has_FPU);
#endif
 
LL_has_FPU = base;
 
#if 1
memcpy(LL_FPU_savearea, base->ctx_FPU, FPU_CONTEXT_SIZE);
LL_FPU_restore();
#else
restore_fpu(&(TSS_table[LL_has_FPU]));
#endif
return;
}
 
TSS *LL_FPU_get_task(void)
{
return(LL_has_FPU);
}
/shark/branches/xen/arch/x86/irq.c
0,0 → 1,121
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* PIC management code & data */
 
#include <ll/i386/hw-instr.h>
#include <ll/i386/pic.h>
 
FILE(IRQ);
 
#define ICW1_M 0x020 /* Master PIC (8259) register settings */
#define ICW2_M 0x021
#define ICW3_M 0x021
#define ICW4_M 0x021
#define OCW1_M 0x021
#define OCW2_M 0x020
#define OCW3_M 0x020
 
#define ICW1_S 0x0A0 /* Slave PIC register setting */
#define ICW2_S 0x0A1
#define ICW3_S 0x0A1
#define ICW4_S 0x0A1
#define OCW1_S 0x0A1
#define OCW2_S 0x0A0
#define OCW3_S 0x0A0
 
#define EOI 0x020 /* End Of Interrupt code for PIC! */
 
#define bit_on(v,b) ((v) |= (1 << (b)))
#define bit_off(v,b) ((v) &= ~(1 << (b)))
 
/* PIC interrupt mask */
BYTE ll_PIC_master_mask = 0xFF;
BYTE ll_PIC_slave_mask = 0xFF;
 
 
void PIC_init(void)
{
outp(ICW1_M,0x11);
outp(ICW2_M,PIC1_BASE);
outp(ICW3_M,0x04);
outp(ICW4_M,0x01);
outp(OCW1_M,0xFF);
 
outp(ICW1_S,0x11);
outp(ICW2_S,PIC2_BASE);
outp(ICW3_S,0x02);
outp(ICW4_S,0x01);
outp(OCW1_S,0xFF);
}
 
void PIC_end(void)
{
outp(ICW1_M,0x11);
outp(ICW2_M,0x08);
outp(ICW3_M,0x04);
outp(ICW4_M,0x01);
outp(OCW1_M,0xFF);
 
outp(ICW1_S,0x11);
outp(ICW2_S,0x70);
outp(ICW3_S,0x02);
outp(ICW4_S,0x01);
outp(OCW1_S,0xFF);
}
 
void irq_mask(WORD irqno)
{
/* Interrupt is on master PIC */
if (irqno < 8) {
bit_on(ll_PIC_master_mask,irqno);
outp(0x21,ll_PIC_master_mask);
} else if (irqno < 16) {
/* Interrupt on slave PIC */
bit_on(ll_PIC_slave_mask,irqno-8);
outp(0xA1,ll_PIC_slave_mask);
/* If the slave PIC is completely off */
/* Then turn off cascading line (Irq #2)*/
if (ll_PIC_slave_mask == 0xFF && !(ll_PIC_master_mask & 0x04)) {
bit_on(ll_PIC_master_mask,2);
outp(0x21,ll_PIC_master_mask);
}
}
}
 
void irq_unmask(WORD irqno)
{
/* Interrupt is on master PIC */
if (irqno < 8) {
bit_off(ll_PIC_master_mask,irqno);
outp(0x21,ll_PIC_master_mask);
} else if (irqno < 16) {
/* Interrupt on slave PIC */
bit_off(ll_PIC_slave_mask,irqno-8);
outp(0xA1,ll_PIC_slave_mask);
/* If the cascading irq line was off */
/* Then activate it also! */
if (ll_PIC_master_mask & 0x04) {
bit_off(ll_PIC_master_mask,2);
outp(0x21,ll_PIC_master_mask);
}
}
}
/shark/branches/xen/arch/x86/Makefile
0,0 → 1,30
targets:= \
cxsw-2.o \
init.o \
time.o \
aspace.o \
intevt.o \
event.o \
event1.o \
advtimer.o \
abort.o \
timeint.o \
libx0.a \
xinfo.o \
x1.o \
xsystab.o \
xconv.o \
xdosf.o \
xdosm.o \
ccpu.o \
fpu.o \
irq.o \
ctxsw.o \
xinit.o \
idtinit.o \
vm86.o \
xbios.o
 
libx0.a-objs:= x0.o
 
cppflags+= -I$(srctree)/libc/arch/$(ARCH)/include
/shark/branches/xen/arch/x86/xconv.c
0,0 → 1,62
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The OSLib (flat space) <-> Phisical address conversion */
 
#include <ll/i386/hw-func.h>
#include <ll/i386/mem.h>
 
FILE(X-Conv);
 
/* Conversion between PM address space & phisical address space */
/* If we do not support paging we need to relocate the .ELF executable */
/* using the segment register; however we also need to access all the */
/* phisical memory; for example if we allocate some memory (phisical) */
/* and we use a pointer to access that memory, the pointer will use */
/* the current DS to address the specified offset; but the phisical */
/* offset cannot be used because the base of DS is not zero as required */
/* to access phisical memory; the DS base is stored by X into the */
/* exec_base field of _X_info! This is the key to traslate ELF address */
/* into phisical address & viceversa */
 
/*
DWORD appl2linear(void *p)
{
unsigned long result;
result = (DWORD)(p) + _X_info->exec_base;
return(result);
}
 
void *linear2appl(DWORD a)
{
void *p;
if (a < _X_info->exec_base) p = NULL;
else p = (void *)(a-_X_info->exec_base);
return(p);
}
*/
 
LIN_ADDR addr2linear(unsigned short seg,unsigned long offset)
{
LIN_ADDR flatbase;
flatbase = (LIN_ADDR)GDT_read(seg,NULL,NULL,NULL);
return(flatbase + offset);
}
/shark/branches/xen/arch/x86/time.c
0,0 → 1,151
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Time management code: ll_getttime() */
 
/* Added Advanced Timer Code
*
* Date: 8.4.2003
* Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
*
*/
 
#include <arch/i386/stdlib.h>
#include <ll/i386/pit.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/i386/advtimer.h>
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/time.h>
 
/* These are for the EXECT and TICK modes */
extern DWORD ticksize; /* From init.c */
extern struct timespec actTime; /* From event.c */
extern WORD pit_time_const; /* From init.c */
extern DWORD timermode; /* From init.c */
 
/* These two are for the NEW algorithm */
extern WORD lastTime; /* From event.c */
extern struct pitspec globalCounter; /* From event.c */
extern BYTE frc;
extern int activeEvent;
extern unsigned char use_tsc;
 
FILE(Time);
 
TIME ll_gettime(int mode, struct timespec *tsres)
{
if (!use_tsc) {
 
DWORD res, tc;
BYTE isr;
struct timespec tmp;
 
#if 1
if (activeEvent) {
if (tsres != NULL) {
PITSPEC2TIMESPEC(&globalCounter, tsres);
} else {
struct timespec tmp;
 
PITSPEC2TIMESPEC(&globalCounter, &tmp);
return TIMESPEC2USEC(&tmp);
}
return TIMESPEC2USEC(tsres);
}
#endif
if (mode == TIME_PTICK) {
if (timermode != LL_PERIODIC) {
return 0;
}
res = TIMESPEC2USEC(&actTime);
if (tsres != NULL) {
memcpy(tsres, &actTime, sizeof(struct timespec));
}
return res;
}
 
if (mode == TIME_NEW) {
WORD tmp;
tmp = pit_read(frc);
ADDPITSPEC((WORD)(lastTime - tmp), &globalCounter);
lastTime = tmp;
if (tsres != NULL) {
PITSPEC2TIMESPEC(&globalCounter, tsres);
}
return (PITSPEC2USEC(&globalCounter));
}
 
if (mode == TIME_EXACT) {
if (timermode == LL_PERIODIC) {
memcpy(&tmp, &actTime, sizeof(struct timespec));
/* How much time has elapsed
* from the last Tick Boundary?
*/
tc = pit_read(0);
if (tc > pit_time_const) {
error("LL Time Panic!!!\n");
ll_abort(1);
}
res = pit_time_const - tc;
res *= ticksize;
res /= pit_time_const;
 
/* Detect tick boundary and adjust the time... */
outp(0x20, 0x0A);
isr = inp(0x20);
if ((isr & 1) && res < ((8*ticksize)/10)){
/*
res += ticksize;
ADDNANO2TIMESPEC(ticksize * 1000, &tmp);
*/
res = ticksize;
}
 
/* Sum the Tick time... */
ADDNANO2TIMESPEC(res * 1000, &tmp);
res += TIMESPEC2USEC(&actTime);
 
if (tsres != NULL) {
memcpy(tsres, &tmp, sizeof(struct timespec));
}
return res;
} else {
return 0;
}
}
return 0;
} else {
if (tsres != NULL) {
ll_read_timespec(tsres);
return TIMESPEC2USEC(tsres);
} else {
struct timespec tmp;
ll_read_timespec(&tmp);
return TIMESPEC2USEC(&tmp);
}
}
}
/shark/branches/xen/arch/x86/exc.s
0,0 → 1,652
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Exc/IRQ handlers (asm part) */
/* TODO: Unify the Exc/Int Mechanism... */
 
#include <ll/i386/sel.h>
#include <ll/i386/linkage.h>
#include <ll/i386/int.h>
#include <ll/i386/defs.h>
 
.extern SYMBOL_NAME(GDT_base)
.extern SYMBOL_NAME(global_regs)
.extern SYMBOL_NAME(VM86_ret_ctx)
 
.data
 
ASMFILE(Exc)
 
.globl SYMBOL_NAME(ll_irq_table)
SYMBOL_NAME_LABEL(ll_irq_table) .space 1024, 0
 
.text
 
.extern SYMBOL_NAME(ll_exc_hook)
.extern SYMBOL_NAME(ll_FPU_hook)
 
.globl SYMBOL_NAME(h13_bis)
.globl SYMBOL_NAME(exc7)
 
/* These are the hardware handlers; they all jump to ll_handler setting */
/* the interrupt number into EAX & save the registers on stack */
INT(0)
INT(1)
INT(2)
INT(3)
INT(4)
INT(5)
INT(6)
INT(8)
INT(9)
INT(10)
INT(11)
INT(12)
INT(13)
INT(14)
INT(15)
NONE(16)
INT(17)
INT(18)
INT(19)
INT(20)
INT(21)
INT(22)
INT(23)
INT(24)
INT(25)
INT(26)
INT(27)
INT(28)
INT(29)
INT(30)
INT(31)
 
INT(32)
INT(33)
INT(34)
INT(35)
INT(36)
INT(37)
INT(38)
INT(39)
INT(40)
INT(41)
INT(42)
INT(43)
INT(44)
INT(45)
INT(46)
INT(47)
INT(48)
INT(49)
INT(50)
INT(51)
INT(52)
INT(53)
INT(54)
INT(55)
INT(56)
INT(57)
INT(58)
INT(59)
INT(60)
INT(61)
INT(62)
INT(63)
 
/* Master PIC... (int 0x40, see ll/i386/pic.h)*/
INT_1(64)
INT_1(65)
INT_1(66)
INT_1(67)
INT_1(68)
INT_1(69)
INT_1(70)
INT_1(71)
 
VM86(72)
INT(73)
INT(74)
INT(75)
INT(76)
INT(77)
INT(78)
INT(79)
INT(80)
INT(81)
INT(82)
INT(83)
INT(84)
INT(85)
INT(86)
INT(87)
INT(88)
INT(89)
INT(90)
INT(91)
INT(92)
INT(93)
INT(94)
INT(95)
INT(96)
INT(97)
INT(98)
INT(99)
INT(100)
INT(101)
INT(102)
INT(103)
INT(104)
INT(105)
INT(106)
INT(107)
INT(108)
INT(109)
INT(110)
INT(111)
 
/* Slave PIC... (int 0x70, see ll/i386/pic.h)*/
INT_2(112)
INT_2(113)
INT_2(114)
INT_2(115)
INT_2(116)
INT_2(117)
INT_2(118)
INT_2(119)
 
INT(120)
INT(121)
INT(122)
INT(123)
INT(124)
INT(125)
INT(126)
INT(127)
INT(128)
INT(129)
INT(130)
INT(131)
INT(132)
INT(133)
INT(134)
INT(135)
INT(136)
INT(137)
INT(138)
INT(139)
INT(140)
INT(141)
INT(142)
INT(143)
INT(144)
INT(145)
INT(146)
INT(147)
INT(148)
INT(149)
INT(150)
INT(151)
INT(152)
INT(153)
INT(154)
INT(155)
INT(156)
INT(157)
INT(158)
INT(159)
INT(160)
INT(161)
INT(162)
INT(163)
INT(164)
INT(165)
INT(166)
INT(167)
INT(168)
INT(169)
INT(170)
INT(171)
INT(172)
INT(173)
INT(174)
INT(175)
INT(176)
INT(177)
INT(178)
INT(179)
INT(180)
INT(181)
INT(182)
INT(183)
INT(184)
INT(185)
INT(186)
INT(187)
INT(188)
INT(189)
INT(190)
INT(191)
INT(192)
INT(193)
INT(194)
INT(195)
INT(196)
INT(197)
INT(198)
INT(199)
INT(200)
INT(201)
INT(202)
INT(203)
INT(204)
INT(205)
INT(206)
INT(207)
INT(208)
INT(209)
INT(210)
INT(211)
INT(212)
INT(213)
INT(214)
INT(215)
INT(216)
INT(217)
INT(218)
INT(219)
INT(220)
INT(221)
INT(222)
INT(223)
INT(224)
INT(225)
INT(226)
INT(227)
INT(228)
INT(229)
INT(230)
INT(231)
INT(232)
INT(233)
INT(234)
INT(235)
INT(236)
INT(237)
INT(238)
INT(239)
INT(240)
INT(241)
INT(242)
INT(243)
INT(244)
INT(245)
INT(246)
INT(247)
INT(248)
INT(249)
INT(250)
INT(251)
INT(252)
INT(253)
INT(254)
INT(255)
 
/* The ll_handler process the request using the kernel function act_int() */
/* Then sends EOI & schedules any eventual new task! */
 
ll_handler:
/* We do not know what is the DS value */
/* Then we save it & set it correctly */
pushl %ds
pushl %ss
pushl %es
pushl %fs
pushl %gs
/* But we first transfer to the _act_int */
/* the interrupt number which is required */
/* as second argument */
pushl %eax
movw $(X_FLATDATA_SEL),%ax
movw %ax,%es
mov %ax,%ds
movw %ax, %fs
movw %ax, %gs
/* Now save the actual context on stack */
/* to pass it to _act_int (C caling convention) */
/* CLD is necessary when calling a C function */
cld
/* The following could be optimized a little... */
popl %eax
xorl %ebx, %ebx
movw %ss, %bx
/* We must switch to a ``safe stack'' */
/*
* OK, this is the idea: in %esp we have the address of the
* stack pointer in the APPLICATION address space...
* We assume that address spaces are implemented through segments...
* What we have to do is to add the segment base to %esp:
* - Load the GDT base in a register
* - Add DS * 8 to that value
* - Read the corresponding GDT entry (the segment descriptor)
* - Compute the base...
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2)
*/
movl SYMBOL_NAME(GDT_base), %edi
addl %ebx, %edi
xorl %ebx, %ebx
movb 7(%edi), %bh
movb 4(%edi), %bl
shl $16, %ebx
movw 2(%edi), %bx
/* Is it correct? I think so... Test it!!! */
addl %ebx, %esp
/* Save EBX for returning to our stack... */
movw %ss, %dx
movw %ds, %cx
movw %cx, %ss
pushl %ebx
pushl %edx
pushl %eax
 
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx
call *%ebx
popl %ebx /* Store in EBX the Int number */
popl %eax
popl %ecx /* We must subtract it from ESP...*/
subl %ecx, %esp
movw %ax, %ss
/* Resume the return value of _act_int */
/* & do the context switch if necessary! */
#ifdef __VIRCSW__
movw SYMBOL_NAME(currCtx), %ax
cmpw JmpSel,%ax
je NoPreempt3
movw %ax,JmpSel
ljmp *JmpZone
#endif
NoPreempt3: popl %gs
popl %fs
popl %es
popl %ss
popl %ds
popal
iret
 
ll_handler_master_pic:
/* We do not know what is the DS value */
/* Then we save it & set it correctly */
pushl %ds
pushl %ss
pushl %es
pushl %fs
pushl %gs
/* But we first transfer to the _act_int */
/* the interrupt number which is required */
/* as second argument */
pushl %eax
movw $(X_FLATDATA_SEL),%ax
movw %ax,%es
mov %ax,%ds
movw %ax, %fs
movw %ax, %gs
/* Now save the actual context on stack */
/* to pass it to _act_int (C caling convention) */
/* CLD is necessary when calling a C function */
cld
/* The following could be optimized a little... */
popl %eax
xorl %ebx, %ebx
movw %ss, %bx
/* We must switch to a ``safe stack'' */
/*
* OK, this is the idea: in %esp we have the address of the
* stack pointer in the APPLICATION address space...
* We assume that address spaces are implemented through segments...
* What we have to do is to add the segment base to %esp:
* - Load the GDT base in a register
* - Add DS * 8 to that value
* - Read the corresponding GDT entry (the segment descriptor)
* - Compute the base...
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2)
*/
movl SYMBOL_NAME(GDT_base), %edi
addl %ebx, %edi
xorl %ebx, %ebx
movb 7(%edi), %bh
movb 4(%edi), %bl
shl $16, %ebx
movw 2(%edi), %bx
/* Is it correct? I think so... Test it!!! */
addl %ebx, %esp
/* Save EBX for returning to our stack... */
movw %ss, %dx
movw %ds, %cx
movw %cx, %ss
pushl %ebx
pushl %edx
pushl %eax
 
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx
call *%ebx
popl %ebx /* Store in EBX the Int number */
popl %eax
popl %ecx /* We must subtract it from ESP...*/
subl %ecx, %esp
movw %ax, %ss
/* Send EOI to master PIC */
movb $0x20,%al
movl $0x20,%edx
outb %al,%dx
 
/* Resume the return value of _act_int */
/* & do the context switch if necessary! */
#ifdef __VIRCSW__
movw SYMBOL_NAME(currCtx), %ax
cmpw JmpSel,%ax
je NoPreempt4
movw %ax,JmpSel
ljmp *JmpZone
#endif
NoPreempt4: popl %gs
popl %fs
popl %es
popl %ss
popl %ds
popal
iret
 
ll_handler_slave_pic:
/* We do not know what is the DS value */
/* Then we save it & set it correctly */
pushl %ds
pushl %ss
pushl %es
pushl %fs
pushl %gs
/* But we first transfer to the _act_int */
/* the interrupt number which is required */
/* as second argument */
pushl %eax
movw $(X_FLATDATA_SEL),%ax
movw %ax,%es
mov %ax,%ds
movw %ax, %fs
movw %ax, %gs
/* Now save the actual context on stack */
/* to pass it to _act_int (C caling convention) */
/* CLD is necessary when calling a C function */
cld
/* The following could be optimized a little... */
popl %eax
xorl %ebx, %ebx
movw %ss, %bx
/* We must switch to a ``safe stack'' */
/*
* OK, this is the idea: in %esp we have the address of the
* stack pointer in the APPLICATION address space...
* We assume that address spaces are implemented through segments...
* What we have to do is to add the segment base to %esp:
* - Load the GDT base in a register
* - Add DS * 8 to that value
* - Read the corresponding GDT entry (the segment descriptor)
* - Compute the base...
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2)
*/
movl SYMBOL_NAME(GDT_base), %edi
addl %ebx, %edi
xorl %ebx, %ebx
movb 7(%edi), %bh
movb 4(%edi), %bl
shl $16, %ebx
movw 2(%edi), %bx
/* Is it correct? I think so... Test it!!! */
addl %ebx, %esp
/* Save EBX for returning to our stack... */
movw %ss, %dx
movw %ds, %cx
movw %cx, %ss
pushl %ebx
pushl %edx
pushl %eax
 
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx
call *%ebx
popl %ebx /* Store in EBX the Int number */
popl %eax
popl %ecx /* We must subtract it from ESP...*/
subl %ecx, %esp
movw %ax, %ss
/* Send EOI to master & slave PIC */
movb $0x20,%al
movl $0xA0,%edx
outb %al,%dx
movl $0x20,%edx
outb %al,%dx
 
/* Resume the return value of _act_int */
/* & do the context switch if necessary! */
#ifdef __VIRCSW__
movw SYMBOL_NAME(currCtx), %ax
cmpw JmpSel,%ax
je NoPreempt5
movw %ax,JmpSel
ljmp *JmpZone
#endif
NoPreempt5: popl %gs
popl %fs
popl %es
popl %ss
popl %ds
popal
iret
 
ll_handler_vm86:
pushl %ds
pushl %ss
pushl %es
pushl %fs
pushl %gs
 
pushl %eax
 
movw $(X_FLATDATA_SEL),%ax
movw %ax,%es
movw %ax,%ds
movw %ax,%fs
movw %ax,%gs
 
popl %eax
pushl %ebx
 
movl SYMBOL_NAME(global_regs),%ebx
movl %eax,56(%ebx)
movl %ecx,52(%ebx)
movl %edx,48(%ebx)
movl %edi,28(%ebx)
movl %esi,32(%ebx)
 
movl %ebx,%edi
popl %ebx
movl %ebx,44(%edi)
 
pushfl
popl %ebx
movl %ebx,68(%edi)
 
movw SYMBOL_NAME(VM86_ret_ctx), %ax
movw %ax,SYMBOL_NAME(currCtx)
movw %ax,JmpSel
ljmp *JmpZone
 
popl %gs
popl %fs
popl %es
popl %ss
popl %ds
popal
iret
 
 
/* OK, this is Exception 7, and it is generated when an ESC or WAIT
* intruction is reached, and the MP and TS bits are set... Basically,
* it means that the FPU context must be switched
*/
SYMBOL_NAME_LABEL(exc7) pushal
pushl %ds
pushl %ss
pushl %es
pushl %fs
pushl %gs
movw $(X_FLATDATA_SEL),%ax
movw %ax,%es
movw %ax,%ds
cld
call SYMBOL_NAME(ll_FPU_hook)
popl %gs
popl %fs
popl %es
popl %ss
popl %ds
popal
iret
 
/shark/branches/xen/arch/x86/vm86.c
0,0 → 1,336
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* File: Vm86.C
*
* VM86 mode switch routines!
* This is basically an alternative way of invoking the
* BIOS service routines; it is very useful to support
* native VBE compliant Video card, without writing an explicit driver
*/
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/mem.h>
#include <ll/i386/x-bios.h>
#include <ll/i386/x-dosmem.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <ll/i386/apic.h>
#include <ll/i386/advtimer.h>
 
FILE(VM-86);
 
/*
#define __LL_DEBUG__
#define __DUMB_CODE__
#define __CHK_IO__
*/
 
//#define __LL_DEBUG__
 
#define VM86_STACK_SIZE 8192
 
extern DWORD ll_irq_table[256];
extern unsigned char use_apic, use_tsc;
 
/* TSS optional section */
static BYTE vm86_stack0[VM86_STACK_SIZE];
 
static BYTE init = 0;
 
static struct {
TSS t;
DWORD io_map[2048];
} vm86_TSS;
static LIN_ADDR vm86_stack;
static LIN_ADDR vm86_iretAddress;
 
struct registers *global_regs;
WORD VM86_ret_ctx;
 
#ifdef __DUMB_CODE__
static LIN_ADDR vm86_code;
static BYTE prova86[] = {
0x1e, /* push ds */
0xb8,0x00,0xb8, /* mov ax,0xb800 */
0x8e,0xd8, /* mov ds,ax */
0xbf,0x9e,0x00, /* mov di,0x009e (158) */
0xb0,0x2a, /* mov ax,'*' */
0x88,0x05, /* mov ds:[di],al */
0x1f, /* pop ds */
0xcd, 0x40, /*???*/
#ifdef __CHK_IO__
0xb0, 0x00, /* movb $0x0,%al*/
0x66,0xba, 0x80, 0x00, /* movw $0x80,%dx */
0x66,0xef, /* outw %ax, (%dx) */
#endif
0xcf, /* iret */
0xf4, /* hlt */
0};
#endif
 
static BYTE vm86_retAddr[] = {0xcd, 0x48, /* int 48h */
0xf4,
0};
 
TSS *vm86_get_tss(void)
{
return &(vm86_TSS.t);
}
 
/* Just a debugging function; it dumps the status of the TSS */
void vm86_dump_TSS(void)
{
BYTE acc,gran;
DWORD base,lim;
message("vm86_TSS.t dump\n");
message("Flag: %lx\n",vm86_TSS.t.eflags);
message("SS: %hx SP:%lx\n", vm86_TSS.t.ss,vm86_TSS.t.esp);
message("Stack0: %hx:%lx\n",vm86_TSS.t.ss0,vm86_TSS.t.esp0);
message("Stack1: %hx:%lx\n",vm86_TSS.t.ss1,vm86_TSS.t.esp1);
message("Stack2: %hx:%lx\n",vm86_TSS.t.ss2,vm86_TSS.t.esp2);
message("CS: %hx IP: %lx",vm86_TSS.t.cs, vm86_TSS.t.eip);
message("DS: %hx\n",vm86_TSS.t.ds);
base = GDT_read(X_VM86_TSS,&lim,&acc,&gran);
message("Base : %lx Lim : %lx Acc : %x Gran %x\n",
base,lim,(unsigned)(acc),(unsigned)(gran));
}
 
void vm86_init(void)
{
int register i;
if (init != 0) return;
init = 1;
 
/* First of all, we need to setup a GDT entries to
* allow vm86 task execution. We just need a free 386 TSS, which
* will be used to store the execution context of the virtual 8086
* task
*/
GDT_place(X_VM86_TSS,(DWORD)(&vm86_TSS),
sizeof(vm86_TSS),FREE_TSS386,GRAN_16);
 
/* Return Registers */
global_regs = DOS_alloc(sizeof(struct registers));
 
/* Prepare a real-mode stack, obtaining it from the
* DOS memory allocator!
* 8K should be OK! Stack top is vm86_stack + SIZE!
*/
vm86_stack = DOS_alloc(VM86_STACK_SIZE*2);
vm86_stack += VM86_STACK_SIZE/2;
vm86_iretAddress = DOS_alloc(sizeof(vm86_retAddr));
memcpy(vm86_iretAddress,vm86_retAddr,sizeof(vm86_retAddr));
#ifdef __LL_DEBUG__
message("PM reentry linear address=0x%lx\n", (DWORD)vm86_iretAddress);
#endif
#ifdef __DUMB_CODE__
vm86_code = DOS_alloc(2048);
lmemcpy(vm86_code,prova86,sizeof(prova86));
#endif
/* Zero the PM/Ring[1,2] ss:esp; they're unused! */
vm86_TSS.t.esp1 = 0;
vm86_TSS.t.esp2 = 0;
vm86_TSS.t.ss1 = 0;
vm86_TSS.t.ss2 = 0;
/* Use only the GDT */
vm86_TSS.t.ldt = 0;
/* No paging activated */
vm86_TSS.t.cr3 = 0;
vm86_TSS.t.trap = 0;
/* Yeah, free access to any I/O port; we trust BIOS anyway! */
/* Here is the explanation: we have 65536 I/O ports... each bit
* in the io_map masks/unmasks the exception for the given I/O port
* If the bit is set, an exception is generated; otherwise, if the bit
* is clear, everythings works fine...
* Because of alignment problem, we need to add an extra byte all set
* to 1, according to Intel manuals
*/
vm86_TSS.t.io_base = (DWORD)(&(vm86_TSS.io_map)) -
(DWORD)(&(vm86_TSS));
for (i = 0; i < 2047; i++) vm86_TSS.io_map[i] = 0;
vm86_TSS.io_map[2047] = 0xFF000000;
}
 
int vm86_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s)
{
DWORD vm86_tmpAddr;
DWORD vm86_flags, vm86_cs,vm86_ip;
LIN_ADDR vm86_stackPtr;
DWORD *IRQTable_entry;
BYTE p1,p2;
DWORD msr1 = 0,msr2 = 0;
 
SYS_FLAGS f;
 
if (service < 0x10 || in == NULL) return -1;
f = ll_fsave();
 
/* Setup the stack frame */
vm86_tmpAddr = (DWORD)(vm86_stack);
vm86_TSS.t.ss = (vm86_tmpAddr & 0xFF000) >> 4;
vm86_TSS.t.ebp = vm86_TSS.t.esp = (vm86_tmpAddr & 0x0FFF)
+ VM86_STACK_SIZE - 6;
/* Build an iret stack frame which returns to vm86_iretAddress */
vm86_tmpAddr = (DWORD)(vm86_iretAddress);
vm86_cs = (vm86_tmpAddr & 0xFF000) >> 4;
vm86_ip = (vm86_tmpAddr & 0xFFF);
vm86_flags = 0;
vm86_stackPtr = vm86_stack + VM86_STACK_SIZE;
lmempokew(vm86_stackPtr-6,vm86_ip);
lmempokew(vm86_stackPtr-4,vm86_cs);
lmempokew(vm86_stackPtr-2,vm86_flags);
#ifdef __LL_DEBUG__
message("Stack: %lx SS: %lx SP: %lx\n",
vm86_tmpAddr + VM86_STACK_SIZE,(DWORD)vm86_TSS.t.ss,vm86_TSS.t.esp);
#endif
/* Wanted VM86 mode + IOPL = 3! */
vm86_TSS.t.eflags = CPU_FLAG_VM + CPU_FLAG_IOPL;
/* Preload some standard values into the registers */
vm86_TSS.t.ss0 = X_FLATDATA_SEL;
vm86_TSS.t.esp0 = (DWORD)&(vm86_stack0[VM86_STACK_SIZE-1]);
#ifdef __DUMB_CODE__
vm86_TSS.t.cs = ((DWORD)(vm86_code) & 0xFFFF0) >> 4;
vm86_TSS.t.eip = ((DWORD)(vm86_code) & 0x000F);
#ifdef __LL_DEBUG_
message("(DUMB CODE) CS:%x IP:%x/%x\n",
(DWORD)vm86_TSS.t.cs,vm86_TSS.t.eip,&prova86);
message("(DUMB CODE) Go...\n");
#endif
 
p1 = inp(0x21);
p2 = inp(0xA1);
outp(0x21,0xFF);
outp(0xA1,0xFF);
 
if (use_apic) {
rdmsr(APIC_BASE_MSR,msr1,msr2);
disable_APIC_timer();
}
 
vm86_TSS.t.back_link = ll_context_save();
VM86_ret_ctx = vm86_TSS.t.back_link
sti();
ll_context_load(X_VM86_TSS);
cli();
 
if (use_apic) {
wrmsr(APIC_BASE_MSR,msr1,msr2);
enable_APIC_timer();
}
 
outp(0x21,p1);
outp(0xA1,p2);
 
#ifdef __LL_DEBUG_
message("(DUMB CODE) I am back...\n");
#endif
#else
/* Copy the parms from the X_*REGS structures in the vm86 TSS */
vm86_TSS.t.eax = (DWORD)in->x.ax;
vm86_TSS.t.ebx = (DWORD)in->x.bx;
vm86_TSS.t.ecx = (DWORD)in->x.cx;
vm86_TSS.t.edx = (DWORD)in->x.dx;
vm86_TSS.t.esi = (DWORD)in->x.si;
vm86_TSS.t.edi = (DWORD)in->x.di;
/* IF Segment registers are required, copy them... */
if (s != NULL) {
vm86_TSS.t.es = (WORD)s->es;
vm86_TSS.t.ds = (WORD)s->ds;
} else {
vm86_TSS.t.ds = vm86_TSS.t.ss;
vm86_TSS.t.es = vm86_TSS.t.ss;
}
vm86_TSS.t.gs = vm86_TSS.t.ss;
vm86_TSS.t.fs = vm86_TSS.t.ss;
/* Execute the BIOS call, fetching the CS:IP of the real interrupt
* handler from 0:0 (DOS irq table!)
*/
IRQTable_entry = (void *)(0L);
vm86_TSS.t.cs= ((IRQTable_entry[service]) & 0xFFFF0000) >> 16;
vm86_TSS.t.eip = ((IRQTable_entry[service]) & 0x0000FFFF);
#ifdef __LL_DEBUG__
message("CS:%x IP:%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip);
#endif
/* Let's use the ll standard call... */
 
p1 = inp(0x21);
p2 = inp(0xA1);
outp(0x21,0xFF);
outp(0xA1,0xFF);
 
if (use_apic) {
rdmsr(APIC_BASE_MSR,msr1,msr2);
disable_APIC_timer();
}
 
vm86_TSS.t.back_link = ll_context_save();
VM86_ret_ctx = vm86_TSS.t.back_link;
sti();
ll_context_load(X_VM86_TSS);
cli();
 
if (use_apic) {
wrmsr(APIC_BASE_MSR,msr1,msr2);
enable_APIC_timer();
}
 
outp(0x21,p1);
outp(0xA1,p2);
 
#ifdef __LL_DEBUG__
message("I am back...\n");
message("TSS CS=%hx IP=%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip);
#endif
/* Send back in the X_*REGS structure the value obtained with
* the real-mode interrupt call
*/
if (out != NULL) {
out->x.ax = global_regs->eax;
out->x.bx = global_regs->ebx;
out->x.cx = global_regs->ecx;
out->x.dx = global_regs->edx;
out->x.si = global_regs->esi;
out->x.di = global_regs->edi;
out->x.cflag = global_regs->flags;
//message("ax = %d bx = %d cx = %d dx = %d\n",out->x.ax,out->x.bx,out->x.cx,out->x.dx);
//message("si = %d di = %d\n",out->x.si,out->x.di);
 
}
if (s != NULL) {
s->es = vm86_TSS.t.es;
s->ds = vm86_TSS.t.ds;
}
#endif
 
ll_frestore(f);
 
return 1;
 
}
/shark/branches/xen/arch/x86/event1.c
0,0 → 1,300
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Added Advanced Timer Code
*
* Date: 8.4.2003
* Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
*
*/
 
/* Time Event routines (one shot mode) */
 
#include <arch/i386/stdlib.h>
#include <arch/i386/limits.h>
#include <ll/i386/mem.h>
#include <ll/i386/pit.h>
#include <ll/i386/apic.h>
#include <ll/i386/advtimer.h>
#include <ll/i386/error.h>
#include <ll/i386/64bit.h>
 
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/time.h>
#include <ll/sys/ll/event.h>
 
#include <tracer.h>
extern unsigned short int currCtx;
 
FILE(EventOneShot);
 
extern int activeInt;
int activeEvent;
 
extern BYTE frc;
 
extern struct event eventlist[MAX_EVENT];
extern WORD lastTime;
extern struct pitspec globalCounter;
 
extern struct event *freeevents;
extern struct event *firstevent;
 
extern void (*evt_prol) (void);
extern void (*evt_epil) (void);
 
extern unsigned int apic_clk_per_msec;
extern unsigned char use_tsc, use_apic;
 
/* Switched to timespec */
int oneshot_event_post(struct timespec time, void (*handler) (void *p), void *par)
{
struct event *p;
struct event *p1, *t;
struct timespec now, tmp;
int done;
DWORD tnext;
 
TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0);
 
if (!freeevents) {
message("NO FREE EVENTS !\n");
ll_abort(20);
return -1;
}
/* Extract from the ``free events'' queue */
p = freeevents;
freeevents = p->next;
 
/* Fill the event fields */
p->handler = handler;
TIMESPEC_ASSIGN(&(p->time), &time);
p->par = par;
 
/* ...And insert it in the event queue!!! */
 
t = NULL;
done = 0;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; p1; p1 = t->next) {
if (TIMESPEC_A_GT_B((&time), (&p1->time))) {
t = p1;
} else
break;
}
 
/* adjust next entry */
if (t) {
t->next = p;
} else {
firstevent = p;
if (!activeEvent) {
if (!use_tsc) {
ll_gettime(TIME_NEW, &now);
} else {
ll_read_timespec(&now);
}
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&tmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &tmp);
}
tnext = TIMESPEC2USEC(&tmp);
if (!use_apic) {
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
} else {
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
}
}
}
p->next = p1;
 
return p->index;
}
 
void oneshot_wake_up(void)
{
/* CHANGE the NAME, please... */
struct event *p = NULL, *pp;
struct timespec now, ttmp;
WORD tmp;
DWORD tnext;
DWORD max_tnext;
 
 
 
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0);
 
if (!use_tsc) {
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
 
PITSPEC2TIMESPEC(&globalCounter, &now);
} else {
ll_read_timespec(&now);
}
 
if (firstevent != NULL) {
activeEvent = 1;
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
if (!activeInt && evt_prol != NULL) {
evt_prol();
}
activeInt++;
 
for (p = firstevent; p != NULL; p = pp) {
if ((p->time.tv_sec > now.tv_sec) ||
((p->time.tv_sec == now.tv_sec)
&& (p->time.tv_nsec > now.tv_nsec))) {
break;
}
pp = p->next;
p->next = freeevents;
freeevents = p;
firstevent = pp;
p->handler(p->par);
}
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
}
 
if (!use_tsc) {
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
PITSPEC2TIMESPEC(&globalCounter, &now);
} else {
ll_read_timespec(&now);
}
 
if (firstevent) {
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&ttmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
}
/* SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
tnext = TIMESPEC2USEC(&ttmp);
if (!use_apic) {
mul32div32to32(INT_MAX,1000000,1193182,max_tnext);
} else {
mul32div32to32(INT_MAX,1000,apic_clk_per_msec,max_tnext);
}
if (tnext>max_tnext) {
message("(************TIME IN THE FUTURE************)");
}
if (!use_apic) {
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
} else {
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
}
} else {
if (!use_apic)
pit_setconstant(0, 0xFFFF);
else
set_APIC_timer(0xFFFFFFFF);
}
activeEvent = 0;
} else {
if (!use_apic)
pit_setconstant(0, 0xFFFF);
else
set_APIC_timer(0xFFFFFFFF);
}
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
}
 
int oneshot_event_delete(int index)
{
struct event *p1, *t;
struct timespec tmp, now;
DWORD tnext;
int firstdeleted = FALSE;
 
TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
 
if (index == -1)
return -1;
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
t = p1;
}
if (p1 == NULL) {
return -1;
}
if (t == NULL) {
firstevent = p1->next;
firstdeleted = TRUE;
} else {
t->next = p1->next;
}
p1->next = freeevents;
freeevents = p1;
if (!activeEvent) {
if (firstevent == NULL) {
if (!use_apic)
pit_setconstant(0, 0xFFFF);
else
set_APIC_timer(0xFFFFFFFF);
} else {
if (firstdeleted) {
if (!use_tsc)
ll_gettime(TIME_NEW, &now);
else
ll_read_timespec(&now);
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&tmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &tmp);
}
/*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
tnext = TIMESPEC2USEC(&tmp);
if (!use_apic) {
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
} else {
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
}
}
}
}
return 1;
}
/shark/branches/xen/arch/x86/include/arch/ll/i386/x-bios.h
0,0 → 1,83
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* For accessing BIOS calls returning in Real Mode, or using VM86 */
 
#ifndef __LL_I386_X_BIOS_H__
#define __LL_I386_X_BIOS_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
 
#define DOS_OFF(x) ((DWORD)(x) & 0x000F)
#define DOS_SEG(x) (((DWORD)(x) & 0xFFFF0) >> 4)
 
typedef union x_regs16 {
struct {
WORD ax;
WORD bx;
WORD cx;
WORD dx;
WORD si;
WORD di;
WORD cflag;
WORD _pad;
} x;
struct {
BYTE al,ah;
BYTE bl,bh;
BYTE cl,ch;
BYTE dl,dh;
} h;
} X_REGS16;
 
typedef struct x_sregs16 {
WORD es;
WORD cs;
WORD ss;
WORD ds;
} X_SREGS16;
 
typedef struct {
/* The GDT linear address inheritable from X */
DWORD _GDT_base;
/* These are used for BIOS calling */
X_REGS16 _ir;
X_REGS16 _or;
X_SREGS16 _sr;
DWORD _irqno;
/* This is the X version */
DWORD _ver;
} X_CALLBIOS;
 
X_CALLBIOS * x_bios_address(void);
void X_meminfo(LIN_ADDR *b1,DWORD *s1,LIN_ADDR *b2,DWORD *s2);
void X_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s);
void vm86_init();
TSS *vm86_get_tss(void);
int vm86_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s);
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-data.h
0,0 → 1,233
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* As the name says... All the hardware-dependent data structures... */
 
#ifndef __LL_I386_HW_DATA_H__
#define __LL_I386_HW_DATA_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
/* DO WE NEED A SEPARATE INCL FILE FOR THIS? */
#if defined(__GNU__)
#define __LL_ARCH__ "32/DJGPP C/COFF"
#elif defined(__LINUX__)
#define __LL_ARCH__ "32/LINUX CrossCompiled/ELF"
#else
#error Architecture Undefined!
#endif
 
#include <ll/i386/sel.h>
 
/* Useful basic types */
 
#ifndef __BASIC_DATA__
#define __BASIC_DATA__
typedef void *LIN_ADDR;
typedef unsigned long long QWORD;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef unsigned long TIME;
typedef unsigned long SYS_FLAGS;
#define TRUE 1
#define FALSE 0
#define MAX_DWORD 0xFFFFFFFF
#define MAX_WORD 0xFFFF
#define MAX_BYTE 0xFF
#define MAX_TIME MAX_DWORD
#endif
 
typedef short CONTEXT;
 
/* Hardware based types (Self explanatory) */
 
typedef struct gate {
WORD offset_lo;
WORD sel;
BYTE dword_cnt;
BYTE access;
WORD offset_hi;
} GATE;
 
typedef struct descriptor {
WORD lim_lo;
WORD base_lo;
BYTE base_med;
BYTE access;
BYTE gran;
BYTE base_hi;
} DESCRIPTOR;
 
/* A LDT/GDT entry could be a gate or a selector */
/* An IDT entry could be a gate only */
 
union gdt_entry {
DESCRIPTOR d;
GATE g;
};
 
struct registers {
DWORD dummy1;
DWORD dummy2;
DWORD egs;
DWORD efs;
DWORD ees;
DWORD ess;
DWORD eds;
DWORD edi;
DWORD esi;
DWORD ebp;
DWORD esp;
DWORD ebx;
DWORD edx;
DWORD ecx;
DWORD eax;
DWORD eip;
DWORD ecs;
DWORD flags;
};
 
#define STACK_ACCESS 0x92 /* Basic Access bytes */
#define DATA_ACCESS 0x92
#define CODE_ACCESS 0x9A
 
/* At this level we just need to set up 2 gates to enter/exit PM */
/* The entry gate is a 386 32 bit call gate */
/* The exit (Back To Real Mode) gate is a 286 16 bit gate */
 
#define CALL_GATE286 0x84 /* Call & Int Gate Access bytes */
#define CALL_GATE386 0x8C
#define TASK_GATE 0x85
#define INT_GATE286 0x86
#define INT_GATE386 0x8E
#define TRAP_GATE286 0x87
#define TRAP_GATE386 0x8F
 
/* TSS selectors */
 
#define FREE_TSS386 0x89
#define BUSY_TSS386 0x8B
#define FREE_TSS286 0x81
#define BUSY_TSS286 0x83
 
#define GRAN_32B 0xC0 /* Granularity settings */
#define GRAN_32 0x40
#define GRAN_16 0x00
 
/* This is the TSS image for a 386 hardware task */
/* I added two other fields to the basic structure: */
/* 1) The CONTROL field which is used by system software to detect */
/* particular conditions; in this the first phase it is mainly used */
/* to mark the unused TSS & TSS which use math, altough thanks to */
/* the automatic FPU preemption supported in 386 this would be not */
/* necessary. */
/* 2) The ctx_FPU field used to store the FPU context if necessaary */
 
#define TSS_USED 0x8000
#define FPU_USED 0x4000
 
#define FPU_CONTEXT_SIZE 108
 
/* CPU flags definitions */
#define CPU_FLAG_TF 0x00000100
#define CPU_FLAG_IF 0x00000200
#define CPU_FLAG_IOPL 0x00003000
#define CPU_FLAG_NT 0x00004000
#define CPU_FLAG_VM 0x00020000
#define CPU_FLAG_AC 0x00040000
#define CPU_FLAG_VIF 0x00080000
#define CPU_FLAG_VIP 0x00100000
#define CPU_FLAG_ID 0x00200000
 
 
typedef struct tss {
WORD back_link;
WORD _fill0;
DWORD esp0;
WORD ss0;
WORD _fill1;
DWORD esp1;
WORD ss1;
WORD _fill2;
DWORD esp2;
WORD ss2;
WORD _fill3;
DWORD cr3;
DWORD eip;
DWORD eflags;
DWORD eax;
DWORD ecx;
DWORD edx;
DWORD ebx;
DWORD esp;
DWORD ebp;
DWORD esi;
DWORD edi;
WORD es;
WORD _fill5;
WORD cs;
WORD _fill6;
WORD ss;
WORD _fill7;
WORD ds;
WORD _fill8;
WORD fs;
WORD _fill9;
WORD gs;
WORD _fill10;
WORD ldt;
WORD _fill11;
WORD trap;
WORD io_base;
DWORD control;
BYTE ctx_FPU[FPU_CONTEXT_SIZE];
} TSS;
 
/* Irq services specifications */
 
#define TIMER_IRQ 0
#define KEYB_IRQ 1
#define COM2_IRQ 3
#define COM1_IRQ 4
#define COM4_IRQ 3
#define COM3_IRQ 4
#define SB_IRQ 5
#define FDC_IRQ 6
#define SB2_IRQ 7
#define RTC_IRQ 8
#define PS2MOUSE_IRQ 12
#define COPROC_IRQ 13
#define IDE0_IRQ 14
#define IDE1_IRQ 15
 
typedef void (*INTERRUPT)(void);
 
/* Any Kernel primitive is declared with the SYSCALL() modifier */
/* This is useful to add special purposes meaning to the function */
/* defclaration */
 
#define SYSCALL(x) x
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/int.h
0,0 → 1,64
 
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#ifndef __LL_I386_INT__
#define __LL_I386_INT__
 
#include <ll/i386/linkage.h>
 
#define INT(n) \
.globl SYMBOL_NAME(h##n) ; \
SYMBOL_NAME_LABEL(h##n) ; \
call debug_info ; \
pushal ; \
movl $##n, %eax ; \
jmp ll_handler
 
#define INT_1(n) \
.globl SYMBOL_NAME(h##n) ; \
SYMBOL_NAME_LABEL(h##n) ; \
pushal ; \
movl $##n, %eax ; \
jmp ll_handler_master_pic
 
#define INT_2(n) \
.globl SYMBOL_NAME(h##n) ; \
SYMBOL_NAME_LABEL(h##n) ; \
pushal ; \
movl $##n, %eax ; \
jmp ll_handler_slave_pic
 
#define VM86(n) \
.globl SYMBOL_NAME(h##n) ; \
SYMBOL_NAME_LABEL(h##n) ; \
pushal ; \
jmp ll_handler_vm86
 
#define EXC(n) \
.globl SYMBOL_NAME(exc##n) ; \
SYMBOL_NAME_LABEL(exc##n) ; \
movl $##n, %eax ; \
jmp ll_handler2
#endif
 
#define NONE(n) \
.globl SYMBOL_NAME(h##n) ; \
SYMBOL_NAME_LABEL(h##n) ; \
iret ; \
#endif
 
/shark/branches/xen/arch/x86/include/arch/ll/i386/apic.h
0,0 → 1,173
 
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#ifndef __APIC_H__
#define __APIC_H__
 
#define APIC_DEFAULT_PHYS_BASE 0xfee00000
#define APIC_ID 0x20
#define APIC_ID_MASK (0x0F<<24)
#define GET_APIC_ID(x) (((x)>>24)&0x0F)
#define APIC_LVR 0x30
#define APIC_LVR_MASK 0xFF00FF
#define GET_APIC_VERSION(x) ((x)&0xFF)
#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF)
#define APIC_INTEGRATED(x) ((x)&0xF0)
#define APIC_TASKPRI 0x80
#define APIC_TPRI_MASK 0xFF
#define APIC_ARBPRI 0x90
#define APIC_ARBPRI_MASK 0xFF
#define APIC_PROCPRI 0xA0
#define APIC_EOI 0xB0
#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */
#define APIC_RRR 0xC0
#define APIC_LDR 0xD0
#define APIC_LDR_MASK (0xFF<<24)
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
#define SET_APIC_LOGICAL_ID(x) (((x)<<24))
#define APIC_ALL_CPUS 0xFF
#define APIC_DFR 0xE0
#define APIC_DFR_CLUSTER 0x0FFFFFFFul /* Clustered */
#define APIC_DFR_FLAT 0xFFFFFFFFul /* Flat mode */
#define APIC_SPIV 0xF0
#define APIC_SPIV_FOCUS_DISABLED (1<<9)
#define APIC_SPIV_APIC_ENABLED (1<<8)
#define APIC_ISR 0x100
#define APIC_TMR 0x180
#define APIC_IRR 0x200
#define APIC_ESR 0x280
#define APIC_ESR_SEND_CS 0x00001
#define APIC_ESR_RECV_CS 0x00002
#define APIC_ESR_SEND_ACC 0x00004
#define APIC_ESR_RECV_ACC 0x00008
#define APIC_ESR_SENDILL 0x00020
#define APIC_ESR_RECVILL 0x00040
#define APIC_ESR_ILLREGA 0x00080
#define APIC_ICR 0x300
#define APIC_DEST_SELF 0x40000
#define APIC_DEST_ALLINC 0x80000
#define APIC_DEST_ALLBUT 0xC0000
#define APIC_ICR_RR_MASK 0x30000
#define APIC_ICR_RR_INVALID 0x00000
#define APIC_ICR_RR_INPROG 0x10000
#define APIC_ICR_RR_VALID 0x20000
#define APIC_INT_LEVELTRIG 0x08000
#define APIC_INT_ASSERT 0x04000
#define APIC_ICR_BUSY 0x01000
#define APIC_DEST_PHYSICAL 0x00000
#define APIC_DEST_LOGICAL 0x00800
#define APIC_DM_FIXED 0x00000
#define APIC_DM_LOWEST 0x00100
#define APIC_DM_SMI 0x00200
#define APIC_DM_REMRD 0x00300
#define APIC_DM_NMI 0x00400
#define APIC_DM_INIT 0x00500
#define APIC_DM_STARTUP 0x00600
#define APIC_DM_EXTINT 0x00700
#define APIC_VECTOR_MASK 0x000FF
#define APIC_ICR2 0x310
#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF)
#define SET_APIC_DEST_FIELD(x) ((x)<<24)
#define APIC_LVTT 0x320
#define APIC_LVTPC 0x340
#define APIC_LVT0 0x350
#define APIC_LVT_TIMER_BASE_MASK (0x3<<18)
#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3)
#define SET_APIC_TIMER_BASE(x) (((x)<<18))
#define APIC_TIMER_BASE_CLKIN 0x0
#define APIC_TIMER_BASE_TMBASE 0x1
#define APIC_TIMER_BASE_DIV 0x2
#define APIC_LVT_TIMER_PERIODIC (1<<17)
#define APIC_LVT_MASKED (1<<16)
#define APIC_LVT_LEVEL_TRIGGER (1<<15)
#define APIC_LVT_REMOTE_IRR (1<<14)
#define APIC_INPUT_POLARITY (1<<13)
#define APIC_SEND_PENDING (1<<12)
#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7)
#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8))
#define APIC_MODE_FIXED 0x0
#define APIC_MODE_NMI 0x4
#define APIC_MODE_EXINT 0x7
#define APIC_LVT1 0x360
#define APIC_LVTERR 0x370
#define APIC_TMICT 0x380
#define APIC_TMCCT 0x390
#define APIC_TDCR 0x3E0
#define APIC_TDR_DIV_TMBASE (1<<2)
#define APIC_TDR_DIV_1 0xB
#define APIC_TDR_DIV_2 0x0
#define APIC_TDR_DIV_4 0x1
#define APIC_TDR_DIV_8 0x2
#define APIC_TDR_DIV_16 0x3
#define APIC_TDR_DIV_32 0x8
#define APIC_TDR_DIV_64 0x9
#define APIC_TDR_DIV_128 0xA
 
#define APIC_BASE APIC_DEFAULT_PHYS_BASE
 
#define APIC_BASE_MSR 0x1B
 
/*
* Basic functions accessing APICs.
*/
 
static __inline__ void apic_write(unsigned long reg, unsigned long v)
{
*((volatile unsigned long *)(APIC_BASE+reg)) = v;
}
 
static __inline__ unsigned long apic_read(unsigned long reg)
{
return *((volatile unsigned long *)(APIC_BASE+reg));
}
 
static __inline__ void apic_wait_icr_idle(void)
{
do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
}
 
#define apic_read_around(x)
#define apic_write_around(x,y) apic_write((x),(y))
 
static __inline__ void set_APIC_timer(unsigned int clocks)
{
extern unsigned int apic_set_limit;
 
if (clocks < apic_set_limit) clocks = apic_set_limit;
 
apic_write_around(APIC_TMICT, clocks);
}
 
static __inline__ void ack_APIC_irq(void)
{
/*
* ack_APIC_irq() actually gets compiled as a single instruction:
* - a single rmw on Pentium/82489DX
* - a single write on P6+ cores (CONFIG_X86_GOOD_APIC)
* ... yummie.
*/
 
/* Docs say use 0 for future compatibility */
apic_write_around(APIC_EOI, 0);
}
 
extern void enable_APIC_timer(void);
extern void disable_APIC_timer (void);
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/mem.h
0,0 → 1,355
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Memory manipulation functions...
Some of them are derived from Linux */
 
#ifndef __LL_I386_MEM_H__
#define __LL_I386_MEM_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
/* Various string manipulation functions */
 
/* Assembler low level routines */
/* File: Mem.S */
 
#ifndef NULL
#define NULL 0L
#endif
 
#include <ll/sys/types.h>
#include <ll/i386/hw-data.h>
 
/*
#ifndef __HW_DEP_H__
#include "hw_dep.h"
#endif
*/
 
extern inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
"cld\n\t"
"rep ; movsl\n\t"
"testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
 
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
switch (n) {
case 0:
return to;
case 1:
*(unsigned char *)to = *(const unsigned char *)from;
return to;
case 2:
*(unsigned short *)to = *(const unsigned short *)from;
return to;
case 3:
*(unsigned short *)to = *(const unsigned short *)from;
*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
return to;
case 4:
*(unsigned long *)to = *(const unsigned long *)from;
return to;
case 6: /* for Ethernet addresses */
*(unsigned long *)to = *(const unsigned long *)from;
*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
return to;
case 8:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
return to;
case 12:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
return to;
case 16:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
return to;
case 20:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
return to;
}
#define COMMON(x) \
__asm__ __volatile__( \
"cld\n\t" \
"rep ; movsl" \
x \
: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
: "0" (n/4),"1" ((long) to),"2" ((long) from) \
: "memory");
{
int d0, d1, d2;
switch (n % 4) {
case 0: COMMON(""); return to;
case 1: COMMON("\n\tmovsb"); return to;
case 2: COMMON("\n\tmovsw"); return to;
default: COMMON("\n\tmovsw\n\tmovsb"); return to;
}
}
#undef COMMON
}
 
#define __HAVE_ARCH_MEMCPY
 
#define memcpy(t, f, n) \
(__builtin_constant_p(n) ? \
__constant_memcpy((t),(f),(n)) : \
__memcpy((t),(f),(n)))
 
extern inline void *lmemcpy(LIN_ADDR t, LIN_ADDR f, size_t n)
{
void *p1;
void *p2;
 
p1 = (void *)(t);
p2 = (void *)(f);
return memcpy(p1, p2, n);
}
 
#define __HAVE_ARCH_MEMMOVE
extern inline void * memmove(void * dest,const void * src, size_t n)
{
int d0, d1, d2;
if (dest<src)
__asm__ __volatile__(
"cld\n\t"
"rep\n\t"
"movsb"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),"1" (src),"2" (dest)
: "memory");
else
__asm__ __volatile__(
"std\n\t"
"rep\n\t"
"movsb\n\t"
"cld"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),
"1" (n-1+(const char *)src),
"2" (n-1+(char *)dest)
:"memory");
return dest;
}
 
#define memcmp __builtin_memcmp
 
#define __HAVE_ARCH_MEMCHR
extern inline void * memchr(const void * cs,int c,size_t count)
{
int d0;
register void * __res;
if (!count)
return NULL;
__asm__ __volatile__(
"cld\n\t"
"repne\n\t"
"scasb\n\t"
"je 1f\n\t"
"movl $1,%0\n"
"1:\tdecl %0"
:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
return __res;
}
 
extern inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
"cld\n\t"
"rep\n\t"
"stosb"
: "=&c" (d0), "=&D" (d1)
:"a" (c),"1" (s),"0" (count)
:"memory");
return s;
}
 
/* we might want to write optimized versions of these later */
#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
 
/*
* memset(x,0,y) is a reasonably common thing to do, so we want to fill
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
"cld\n\t"
"rep ; stosl\n\t"
"testb $2,%b3\n\t"
"je 1f\n\t"
"stosw\n"
"1:\ttestb $1,%b3\n\t"
"je 2f\n\t"
"stosb\n"
"2:"
: "=&c" (d0), "=&D" (d1)
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
:"memory");
return (s);
}
 
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
return s;
case 1:
*(unsigned char *)s = pattern;
return s;
case 2:
*(unsigned short *)s = pattern;
return s;
case 3:
*(unsigned short *)s = pattern;
*(2+(unsigned char *)s) = pattern;
return s;
case 4:
*(unsigned long *)s = pattern;
return s;
}
#define COMMON(x) \
__asm__ __volatile__("cld\n\t" \
"rep ; stosl" \
x \
: "=&c" (d0), "=&D" (d1) \
: "a" (pattern),"0" (count/4),"1" ((long) s) \
: "memory")
{
int d0, d1;
switch (count % 4) {
case 0: COMMON(""); return s;
case 1: COMMON("\n\tstosb"); return s;
case 2: COMMON("\n\tstosw"); return s;
default: COMMON("\n\tstosw\n\tstosb"); return s;
}
}
#undef COMMON
}
 
#define __constant_c_x_memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_c_and_count_memset((s),(c),(count)) : \
__constant_c_memset((s),(c),(count)))
 
#define __memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_count_memset((s),(c),(count)) : \
__memset_generic((s),(c),(count)))
 
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
__memset((s),(c),(count)))
 
/*
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#define __HAVE_ARCH_MEMSCAN
extern inline void * memscan(void * addr, int c, size_t size)
{
if (!size)
return addr;
__asm__("cld\n\t"
"repnz; scasb\n\t"
"jnz 1f\n\t"
"dec %%edi\n\t"
"1:\n\t"
: "=D" (addr), "=c" (size)
: "0" (addr), "1" (size), "a" (c));
return addr;
}
 
void fmemcpy(unsigned short ds,unsigned long dof,unsigned short ss,unsigned long sof,unsigned n);
#if 0
extern inline void fmemcpy(unsigned short ds,unsigned long dof,unsigned short ss,unsigned long sof,unsigned n)
{
/* Build the standard stack frame */
__asm__ __volatile__(
/* Get parms into register */
movl 8(%ebp),%eax
movw %ax,%es
movl 12(%ebp),%edi
movl 16(%ebp),%eax
movw %ax,%ds
movl 20(%ebp),%esi
movl 24(%ebp),%ecx
cld
rep
"movsb"
 
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
 
);
 
 
popw %es
popw %ds
popl %edi
popl %esi
leave
ret
 
#endif
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-arch.h
0,0 → 1,103
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Code & data fot CPU identification */
 
#ifndef __LL_I386_HW_ARCH_H__
#define __LL_I386_HW_ARCH_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
 
/* The following structure is filled up by the ll_init() and can be */
/* read by the kernel modules to know about the architecture */
/* Each time a new hardware CPU is added to the ll layer, you have to */
/* define a new XXX_ARCH structure, whose first field is a char *arch */
/* This is used to identify the architecture, then subsequent field */
/* can be decoded!! */
 
/* WARNING: I tried to use bitfields, but this caused am INTO error?!? */
/* only when using GNU-C!! So i preferred to use standard DWORD flags */
 
/* Capabilities */
#define LL_X86_HAS_INVLPG 0x01
#define LL_X86_HAS_CPUID 0x02
#define LL_X86_HAS_FPU 0x04
#define LL_X86_INTERNAL_FPU 0x08
#define LL_X86_HAS_TSTAMP 0x10
 
/* Bugs */
#define LL_X86_FDIV_BUG 0x01
#define LL_X86_F00F_BUG 0x02
 
typedef struct {
char *arch;
int cpu; /* 0,1,2,3,4,5,6 ->
8086/8,80186,80286,80386,80486,P5,PII o Overdrive */
int fpu; /* 0,1,2,3 -> None,8087,80287,80387 */
char *model; /* Dx, Dx2, ... */
char vendor[12]; /* Intel, Cyrix, AMD or unknown */
DWORD capabilities;
DWORD bugs;
/* BUGs!! Warning: Currently, no workaround is available!
*/
int f00f_bug;
int fdiv_bug;
} X86_ARCH;
 
struct ll_cpuInfo {
DWORD X86_cpu;
DWORD X86_cpuIdFlag;
DWORD X86_vendor_1;
DWORD X86_vendor_2;
DWORD X86_vendor_3;
DWORD X86_signature;
DWORD X86_IntelFeature_1;
DWORD X86_IntelFeature_2;
DWORD X86_StandardFeature;
};
 
typedef struct {
char *arch;
/* Tonino, fill up this stuff! */
} AXP_ARCH;
 
typedef union {
char *arch;
X86_ARCH x86;
AXP_ARCH axp;
} LL_ARCH;
 
void X86_get_CPU(struct ll_cpuInfo *p);
void X86_get_FPU(void);
int X86_is386(void);
int X86_isCyrix(void);
int X86_hasCPUID(void);
void X86_enable_cyrix_cpuid(void);
 
extern LL_ARCH ll_arch;
 
END_DEF
#endif /* __LL_I386_HW_ARCH_H__ */
/shark/branches/xen/arch/x86/include/arch/ll/i386/advtimer.h
0,0 → 1,235
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Advanced Timer
* Date: 8.4.2003
* Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
*
*/
 
#ifndef __ADVTIMER_H__
#define __ADVTIMER_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/sys/ll/time.h>
 
/* TSC */
 
#define rdtsc(low,high) \
__asm__ __volatile__("xorl %%eax,%%eax\n\t" \
"cpuid\n\t" \
"rdtsc\n\t" \
: "=a" (low), "=d" (high) \
:: "ebx", "ecx")
 
#define rdtscll(val) \
__asm__ __volatile__("xorl %%eax,%%eax\n\t" \
"cpuid\n\t" \
"rdtsc\n\t" \
: "=A" (val) \
:: "ebx","ecx")
 
#ifdef __O1000__
#define ll_read_timespec ll_read_timespec_1000
#else
#ifdef __02000__
#define ll_read_timespec ll_read_timespec_2000
#else
#ifdef __O4000__
#define ll_read_timespec ll_read_timespec_4000
#else
#define ll_read_timespec ll_read_timespec_8000
#endif
#endif
#endif
 
//Low level time read function: Optimized for CPU < 1 GHz
extern __inline__ void ll_read_timespec_1000(struct timespec *tspec)
{
extern unsigned int clk_opt_1,clk_opt_2;
extern unsigned long long *ptr_init_tsc;
extern struct timespec init_time;
if (clk_opt_1 == 0) {
NULL_TIMESPEC(tspec);
return;
}
__asm__("rdtsc\n\t"
"subl (%%edi),%%eax\n\t"
"sbbl 4(%%edi),%%edx\n\t"
"divl %%ebx\n\t"
"movl %%eax,%%ebx\n\t"
"xorl %%eax,%%eax\n\t"
"divl %%ecx\n\t"
: "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
: "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_2)
: "edx" );
if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
__asm__("divl %%ecx\n\t"
"addl %%ebx,%%eax\n\t"
:"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
:"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
};
}
 
//Low level time read function: Optimized for CPU < 2 GHz
extern __inline__ void ll_read_timespec_2000(struct timespec *tspec)
{
extern unsigned int clk_opt_1,clk_opt_3;
extern unsigned long long *ptr_init_tsc;
extern struct timespec init_time;
if (clk_opt_1 == 0) {
NULL_TIMESPEC(tspec);
return;
}
__asm__("rdtsc\n\t"
"subl (%%edi),%%eax\n\t"
"sbbl 4(%%edi),%%edx\n\t"
"divl %%ebx\n\t"
"movl %%eax,%%ebx\n\t"
"xorl %%eax,%%eax\n\t"
"shrdl $1,%%edx,%%eax\n\t"
"shrl %%edx\n\t"
"divl %%ecx\n\t"
: "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
: "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_3)
: "edx" );
if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
__asm__("divl %%ecx\n\t"
"addl %%ebx,%%eax\n\t"
:"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
:"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
};
}
 
//Low level time read function: Optimized for CPU < 4 GHz
extern __inline__ void ll_read_timespec_4000(struct timespec *tspec)
{
extern unsigned int clk_opt_1,clk_opt_4;
extern unsigned long long *ptr_init_tsc;
extern struct timespec init_time;
if (clk_opt_1 == 0) {
NULL_TIMESPEC(tspec);
return;
}
__asm__("rdtsc\n\t"
"subl (%%edi),%%eax\n\t"
"sbbl 4(%%edi),%%edx\n\t"
"divl %%ebx\n\t"
"movl %%eax,%%ebx\n\t"
"xorl %%eax,%%eax\n\t"
"shrdl $2,%%edx,%%eax\n\t"
"shrl $2,%%edx\n\t"
"divl %%ecx\n\t"
: "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
: "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_4)
: "edx" );
if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
__asm__("divl %%ecx\n\t"
"addl %%ebx,%%eax\n\t"
:"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
:"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
};
}
 
//Low level time read function
extern __inline__ void ll_read_timespec_8000(struct timespec *tspec)
{
extern unsigned int clk_opt_0,clk_opt_5;
extern unsigned long long *ptr_init_tsc;
extern struct timespec init_time;
if (clk_opt_0 == 0) {
NULL_TIMESPEC(tspec);
return;
}
 
__asm__("rdtsc\n\t"
"subl (%%edi),%%eax\n\t"
"sbbl 4(%%edi),%%edx\n\t"
"shrdl $1,%%edx,%%eax\n\t"
"shrl %%edx\n\t"
"divl %%ebx\n\t"
"movl %%eax,%%ebx\n\t"
"xorl %%eax,%%eax\n\t"
"shrdl $2,%%edx,%%eax\n\t"
"shrl $2,%%edx\n\t"
"divl %%ecx\n\t"
: "=b" (tspec->tv_sec), "=a" (tspec->tv_nsec)
: "D" (ptr_init_tsc), "b" (clk_opt_0), "c" (clk_opt_5)
: "edx");
if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
__asm__("divl %%ecx\n\t"
"addl %%ebx,%%eax\n\t"
:"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
:"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
};
}
 
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))
#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))
 
/* RTC */
 
#define RTC_PORT(x) (0x70 + (x))
 
#define CMOS_READ(addr,val) \
{ \
outp(RTC_PORT(0),(addr)); \
val = inp(RTC_PORT(1)); \
}
 
#define CMOS_WRITE(addr,val) \
{ \
outp(RTC_PORT(0),(addr)); \
outp(RTC_PORT(1),(val)); \
}
 
#define RTC_IRQ 8
 
void ll_init_advtimer(void);
void ll_restore_adv(void);
void ll_scale_advtimer(unsigned int old_f, unsigned int new_f);
 
END_DEF
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/64bit.h
0,0 → 1,39
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* 64 bit arithmetic */
 
#ifndef __LL_I386_64BIT__
#define __LL_I386_64BIT__
 
#define mul32div32to32(a,b,c,res) \
__asm__ __volatile__("mull %%ebx\n\t" \
"divl %%ecx\n\t" \
: "=a" ((res)) \
: "a" ((a)), "b" ((b)), "c" ((c)), "d" (0))
 
#define smul32div32to32(a,b,c,res) \
__asm__ __volatile__("imull %%ebx\n\t" \
"idivl %%ecx\n\t" \
: "=a" ((res)) \
: "a" ((a)), "b" ((b)), "c" ((c)), "d" (0))
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-instr.h
0,0 → 1,235
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* As the name says... All the hardware-dependent instructions
there is a 1->1 corrispondence with ASM instructions */
 
#ifndef __LL_I386_HW_INSTR_H__
#define __LL_I386_HW_INSTR_H__
 
#include <ll/i386/defs.h>
 
#define INLINE_OP __inline__ static
 
#include <ll/i386/hw-data.h>
 
/* Low Level I/O funcs are in a separate file (by Luca) */
#include <ll/i386/hw-io.h>
 
BEGIN_DEF
 
INLINE_OP WORD get_CS(void)
{WORD r; __asm__ __volatile__ ("movw %%cs,%0" : "=q" (r)); return(r);}
 
INLINE_OP WORD get_DS(void)
{WORD r; __asm__ __volatile__ ("movw %%ds,%0" : "=q" (r)); return(r);}
INLINE_OP WORD get_FS(void)
{WORD r; __asm__ __volatile__ ("movw %%fs,%0" : "=q" (r)); return(r);}
 
/*INLINE_OP DWORD get_SP(void)
{DWORD r; __asm__ __volatile__ ("movw %%esp,%0" : "=q" (r)); return(r);}*/
INLINE_OP DWORD get_SP(void)
{
DWORD rv;
__asm__ __volatile__ ("movl %%esp, %0"
: "=a" (rv));
return(rv);
}
 
INLINE_OP DWORD get_BP(void)
{
DWORD rv;
__asm__ __volatile__ ("movl %%ebp, %0"
: "=a" (rv));
return(rv);
}
 
INLINE_OP WORD get_TR(void)
{WORD r; __asm__ __volatile__ ("strw %0" : "=q" (r)); return(r); }
 
INLINE_OP void set_TR(WORD n)
{__asm__ __volatile__("ltr %%ax": /* no output */ :"a" (n)); }
 
INLINE_OP void set_LDTR(WORD addr)
{ __asm__ __volatile__("lldt %%ax": /* no output */ :"a" (addr)); }
 
 
/* Clear Task Switched Flag! Used for FPU preemtion */
INLINE_OP void clts(void)
{__asm__ __volatile__ ("clts"); }
 
/* Halt the processor! */
INLINE_OP void hlt(void)
{__asm__ __volatile__ ("hlt"); }
 
/* These functions are used to mask/unmask interrupts */
INLINE_OP void sti(void) {__asm__ __volatile__ ("sti"); }
INLINE_OP void cli(void) {__asm__ __volatile__ ("cli"); }
 
INLINE_OP SYS_FLAGS ll_fsave(void)
{
SYS_FLAGS result;
__asm__ __volatile__ ("pushfl");
__asm__ __volatile__ ("cli");
__asm__ __volatile__ ("popl %eax");
__asm__ __volatile__ ("movl %%eax,%0"
: "=r" (result)
:
: "eax" );
return(result);
}
 
INLINE_OP void ll_frestore(SYS_FLAGS f)
{
__asm__ __volatile__ ("mov %0,%%eax"
:
: "r" (f)
: "eax");
__asm__ __volatile__ ("pushl %eax");
__asm__ __volatile__ ("popfl");
}
 
/*
FPU context switch management functions!
FPU management exported at kernel layer to allow the use
of floating point in kernel primitives; this turns to be
useful for bandwidth reservation or guarantee!
*/
 
/* FPU lazy state save handling.. */
INLINE_OP void save_fpu(TSS *t)
{
__asm__ __volatile__("fnsave %0\n\tfwait":"=m" (t->ctx_FPU));
}
 
INLINE_OP void restore_fpu(TSS *t)
{
#if 1
__asm__ __volatile__("frstor %0": :"p" (t->ctx_FPU));
#else
__asm__ __volatile__("frstor %0\n\tfwait": :"p" (t->ctx_FPU));
#endif
/* __asm__ __volatile__("frstor _LL_FPU_savearea"); */
}
 
INLINE_OP void smartsave_fpu(TSS *t)
{
if (t->control & FPU_USED) save_fpu(t);
}
 
INLINE_OP void reset_fpu(void) { __asm__ __volatile__ ("fninit"); }
 
#if 0
/* OK, now everything is clear... We test the NE bit to see if the
* CPU is using the internal mechanism for reporting FPU errors or not...
*/
INLINE_OP int check_fpu(void)
{
int result;
__asm__ __volatile__ ("movl %cr0,%eax");
__asm__ __volatile__ ("movl %eax,%edi");
__asm__ __volatile__ ("andl $0x0FFFFFFEF,%eax");
__asm__ __volatile__ ("movl %eax,%cr0");
__asm__ __volatile__ ("movl %cr0,%eax");
__asm__ __volatile__ ("xchgl %edi,%eax");
__asm__ __volatile__ ("movl %eax,%cr0");
#if 0
__asm__ __volatile__ ("xorl %eax,%eax");
__asm__ __volatile__ ("movb %bl,%al");
#else
__asm__ __volatile__ ("movl %edi,%eax");
__asm__ __volatile__ ("andl $0x10,%eax");
#endif
__asm__ __volatile__ ("shrb $4,%al");
__asm__ __volatile__ ("movl %%eax,%0"
: "=r" (result)
:
: "eax" );
return(result);
}
#endif
 
INLINE_OP void init_fpu(void)
{
__asm__ __volatile__ ("movl %cr0,%eax");
__asm__ __volatile__ ("orl $34,%eax");
__asm__ __volatile__ ("movl %eax,%cr0");
__asm__ __volatile__ ("fninit");
}
 
 
extern BYTE LL_FPU_savearea[];
 
extern __inline__ void LL_FPU_save(void)
{
#ifdef __LINUX__
__asm__ __volatile__ ("fsave LL_FPU_savearea");
#else
__asm__ __volatile__ ("fsave _LL_FPU_savearea");
#endif
}
 
extern __inline__ void LL_FPU_restore(void)
{
#ifdef __LINUX__
__asm__ __volatile__ ("frstor LL_FPU_savearea");
#else
__asm__ __volatile__ ("frstor _LL_FPU_savearea");
#endif
}
 
 
 
 
INLINE_OP void lmempokeb(LIN_ADDR a, BYTE v)
{
*((BYTE *)a) = v;
}
INLINE_OP void lmempokew(LIN_ADDR a, WORD v)
{
*((WORD *)a) = v;
}
INLINE_OP void lmempoked(LIN_ADDR a, DWORD v)
{
*((DWORD *)a) = v;
}
 
INLINE_OP BYTE lmempeekb(LIN_ADDR a)
{
return *((BYTE *)a);
}
INLINE_OP WORD lmempeekw(LIN_ADDR a)
{
return *((WORD *)a);
}
INLINE_OP DWORD lmempeekd(LIN_ADDR a)
{
return *((DWORD *)a);
}
 
 
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/pit.h
0,0 → 1,188
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The Programmable Interrupt Timer management code */
 
#ifndef __PIT_H__
#define __PIT_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
 
#define MIN_INT 100
 
#define TMR_CTRL 0x43 /* PIT Control port*/
#define TMR_CNT0 0x40 /* Counter 0 port */
#define TMR_CNT1 0x41 /* Counter 1 port */
#define TMR_CNT2 0x42 /* Counter 2 port */
 
#define TMR_SC0 0x00 /* Select Channel 0 */
#define TMR_SC1 0x40 /* Select Channel 1 */
#define TMR_SC2 0x80 /* Select Channel 2 */
 
#define TMR_LSB 0x10 /* R/W Least Significative Byte */
#define TMR_MSB 0x20 /* R/W Most Significative Byte */
#define TMR_BOTH 0x30 /* R/W Both Bytes */
#define TMR_LATCH 0x00 /* Latch Command */
#define TMR_READ 0xF0 /* Read Command */
#define TMR_CNT 0x20 /* Read Counter */
#define TMR_STAT 0x10 /* Read Status */
#define TMR_CH2 0x08 /* Read Channel 2 Counter/Status */
#define TMR_CH1 0x04 /* Read Channel 1 Counter/Status */
#define TMR_CH0 0x02 /* Read Channel 0 Counter/Status */
 
 
#define TMR_MD0 0x00 /* Mode 0 */
#define TMR_MD1 0x02 /* Mode 1 */
#define TMR_MD2 0x04 /* Mode 2 */
#define TMR_MD3 0x06 /* Mode 3 */
#define TMR_MD4 0x08 /* Mode 4 */
#define TMR_MD5 0x0A /* Mode 5 */
 
 
INLINE_OP int pit_init(BYTE channel, BYTE mode, WORD tconst)
{
BYTE v, ch;
WORD cnt;
 
switch (channel) {
case 0:
cnt = TMR_CNT0;
ch = TMR_SC0;
break;
case 1:
cnt = TMR_CNT1;
ch = TMR_SC1;
break;
case 2:
cnt = TMR_CNT2;
ch = TMR_SC2;
break;
default:
return -1;
}
 
/* VM_out(TMR_CTRL, 0x34); */
outp(TMR_CTRL, ch | TMR_BOTH | mode);
/* Load Time_const with 2 access to CTR */
v = (BYTE)(tconst);
outp(cnt, v);
v = (BYTE)(tconst >> 8);
outp(cnt, v);
 
return 1;
}
 
INLINE_OP int pit_setconstant(BYTE channel, DWORD c)
{
BYTE v;
WORD cnt;
WORD tconst;
 
if (c > 0xF000) {
tconst = 0xF000;
} else {
if (c < MIN_INT) {
tconst = MIN_INT;
} else {
tconst = c;
}
}
 
switch (channel) {
case 0:
cnt = TMR_CNT0;
break;
case 1:
cnt = TMR_CNT1;
break;
case 2:
cnt = TMR_CNT2;
break;
default:
return -1;
}
 
/* Load Time_const with 2 access to CTR */
v = (BYTE)(tconst);
outp(cnt, v);
v = (BYTE)(tconst >> 8);
outp(cnt, v);
 
return 1;
}
 
 
INLINE_OP WORD pit_read(BYTE channel)
{
WORD result;
WORD cnt;
BYTE ch;
BYTE str_msb, str_lsb;
 
switch (channel) {
case 0:
cnt = TMR_CNT0;
ch = TMR_CH0;
break;
case 1:
cnt = TMR_CNT1;
ch = TMR_CH1;
break;
case 2:
cnt = TMR_CNT2;
ch = TMR_CH2;
break;
default:
return 0;
}
/* Read Back Command on counter 0 */
#if 0
outp(TMR_CTRL, ch | TMR_LATCH | TMR_BOTH);
#else
outp(TMR_CTRL, TMR_READ - TMR_CNT + ch /*0xD2*/);
#endif
/* Read the latched value from STR */
str_lsb = inp(cnt);
str_msb = inp(cnt);
/* Combine the byte values to obtain a word */
result = ((WORD)str_msb << 8) | (WORD)str_lsb;
return result;
}
 
struct pitspec {
long units;
long gigas;
};
 
#define ADDPITSPEC(n, t) ((t)->units += (n), \
(t)->gigas += (t)->units / 1423249, \
(t)->units %= 1423249)
#define NULLPITSPEC(t) (t)->units = 0, (t)->gigas = 0
#define PITSPEC2USEC(t) ((((t)->units * 1000) / 1193) \
+ (((t)->gigas * 1000) * 1193))
#define CPPITSPEC(a, b) (b)->units = (a)->units, (b)->gigas = (a)->gigas
 
#endif /* __PIT_H__ */
/shark/branches/xen/arch/x86/include/arch/ll/i386/pic.h
0,0 → 1,64
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The Programmable Interrupt Controller management code */
 
#ifndef __PIC_H__
#define __PIC_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
 
#define PIC1_BASE 0x040 /* Interrupt base for each PIC */
#define PIC2_BASE 0x070
 
void PIC_init(void);
void PIC_end(void);
void irq_mask(WORD irqno);
void irq_unmask(WORD irqno);
 
INLINE_OP void l1_exc_bind(int i, void (*f)(int n))
{
l1_int_bind(i, f);
}
 
INLINE_OP int l1_irq_bind(int irq, void *f)
{
int i;
if (irq < 8) {
i = irq + PIC1_BASE;
} else if (irq < 16) {
i = irq + PIC2_BASE - 8;
} else {
return -1;
}
l1_int_bind(i, f);
return 1;
}
 
END_DEF
#endif /* __PIC_H__ */
/shark/branches/xen/arch/x86/include/arch/ll/i386/x-dosmem.h
0,0 → 1,37
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Management functions for memory in the first MegaByte */
 
#ifndef __LL_I386_X_DOSMEM_H__
#define __LL_I386_X_DOSMEM_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
void DOS_dump_mem(void);
void DOS_mem_init(void);
LIN_ADDR DOS_alloc(DWORD s);
int DOS_free(LIN_ADDR p,DWORD s);
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/error.h
0,0 → 1,38
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The LL error dump function */
 
#ifndef __LL_I386_ERROR_H__
#define __LL_I386_ERROR_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/cons.h>
 
int message(char *fmt,...) __attribute__((format(printf,1,2)));
#define error(msg) \
message("Error! File:%s Line:%d %s", __FILE__, __LINE__, msg)
END_DEF
 
#endif
 
/shark/branches/xen/arch/x86/include/arch/ll/i386/x-dos.h
0,0 → 1,49
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Accessing a DOS filesystem from OSLib/X */
 
#ifndef __LL_I386_X_DOS_H__
#define __LL_I386_X_DOS_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/x-bios.h>
 
typedef struct {
LIN_ADDR buf;
LIN_ADDR n1;
char n2[80];
BYTE mode,index;
DWORD handle,offset;
} DOS_FILE;
int DOS_init(void);
DOS_FILE *DOS_fopen(char *name, char *mode);
void DOS_fclose(DOS_FILE *f);
DWORD DOS_fread(void *buf,DWORD size,DWORD num,DOS_FILE *f);
DWORD DOS_fwrite(void *buf,DWORD size,DWORD num,DOS_FILE *f);
unsigned DOS_error(void);
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/farptr.h
0,0 → 1,246
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* Copyright (c) 1995 DJ Delorie. Permission granted to use for any
purpose, provided this copyright remains attached and unmodified.
 
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º Far Pointer Simulation Functions º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
 
This file attempts to make up for the lack of a "far" keyword in GCC.
Although it doesn't provide access to far call APIs (like Windows), it
does allow you to do far pointer data access without the overhead of
movedata() or dosmemget/dosmemput().
 
You should *always* include this file when using these functions and
compile with optimization enabled. They don't exist as normal functions
in any library, and they compile down to only a few opcodes when used
this way. They are almost as fast as native pointer operations, and
about as fast as far pointers can get.
 
If you don't use optimization, this file becomes prototypes for
farptr.c, which generates real functions for these when not optimizing.
When optimizing, farptr.c compiles to nothing.
 
There are two types of functions here - standalone and invariant. The
standalone functions take a selector and offset. These are used when
you need only a few accesses, time isn't critical, or you don't know
what's in the %fs register. The invariant ones don't take a selector,
they only take an offset. These are used inside loops and in
time-critical accesses where the selector doesn't change. To specify
the selector, use the farsetsel() function. That selector is used for
all farns*() functions until changed. You can use _fargetsel() if you
want to temporary change the selector with _farsetsel() and restore
it afterwards.
 
The farpoke* and farpeek* take selectors.
 
The farnspoke* and farnspeek* don't (note the `ns' for `no selector').
 
Warning: These routines all use the %fs register for their accesses.
GCC normally uses only %ds and %es, and libc functions (movedata,
dosmemget, dosmemput) use %gs. Still, you should be careful about
assumptions concerning whether or not the value you put in %fs will be
preserved across calls to other functions. If you guess wrong, your
program will crash. Better safe than sorry.
 
*/
 
#ifndef __dj_include_sys_farptr_h_
#define __dj_include_sys_farptr_h_
#ifdef __cplusplus
extern "C" {
#endif
 
#ifndef __dj_ENFORCE_ANSI_FREESTANDING
 
#ifndef __STRICT_ANSI__
 
#ifndef _POSIX_SOURCE
 
void _farpokeb(unsigned short, unsigned long, unsigned char);
void _farpokew(unsigned short, unsigned long, unsigned short);
void _farpokel(unsigned short, unsigned long, unsigned long);
unsigned char _farpeekb(unsigned short, unsigned long);
unsigned short _farpeekw(unsigned short, unsigned long);
unsigned long _farpeekl(unsigned short, unsigned long);
void _farsetsel(unsigned short);
unsigned short _fargetsel(void);
void _farnspokeb(unsigned long, unsigned char);
void _farnspokew(unsigned long, unsigned short);
void _farnspokel(unsigned long, unsigned long);
unsigned char _farnspeekb(unsigned long);
unsigned short _farnspeekw(unsigned long);
unsigned long _farnspeekl(unsigned long);
 
extern __inline__ void
_farpokeb(unsigned short selector,
unsigned long offset,
unsigned char value)
{
__asm__ __volatile__ ("movw %w0,%%fs\n"
" .byte 0x64 \n"
" movb %b1,%%fs:(%k2)"
:
: "rm" (selector), "qi" (value), "r" (offset));
}
 
extern __inline__ void
_farpokew(unsigned short selector,
unsigned long offset,
unsigned short value)
{
__asm__ __volatile__ ("movw %w0,%%fs \n"
" .byte 0x64 \n"
" movw %w1,(%k2)"
:
: "rm" (selector), "ri" (value), "r" (offset));
}
 
extern __inline__ void
_farpokel(unsigned short selector,
unsigned long offset,
unsigned long value)
{
__asm__ __volatile__ ("movw %w0,%%fs \n"
" .byte 0x64 \n"
" movl %k1,(%k2)"
:
: "rm" (selector), "ri" (value), "r" (offset));
}
 
extern __inline__ unsigned char
_farpeekb(unsigned short selector,
unsigned long offset)
{
unsigned char result;
__asm__ __volatile__ ("movw %w1,%%fs \n"
" .byte 0x64 \n"
" movb (%k2),%b0"
: "=q" (result)
: "rm" (selector), "r" (offset));
return result;
}
 
extern __inline__ unsigned short
_farpeekw(unsigned short selector,
unsigned long offset)
{
unsigned short result;
__asm__ __volatile__ ("movw %w1, %%fs \n"
" .byte 0x64 \n"
" movw (%k2),%w0 \n"
: "=r" (result)
: "rm" (selector), "r" (offset));
return result;
}
 
extern __inline__ unsigned long
_farpeekl(unsigned short selector,
unsigned long offset)
{
unsigned long result;
__asm__ __volatile__ ("movw %w1,%%fs\n"
" .byte 0x64\n"
" movl (%k2),%k0"
: "=r" (result)
: "rm" (selector), "r" (offset));
return result;
}
 
extern __inline__ void
_farsetsel(unsigned short selector)
{
__asm__ __volatile__ ("movw %w0,%%fs"
:
: "rm" (selector));
}
 
extern __inline__ unsigned short
_fargetsel(void)
{
unsigned short selector;
__asm__ __volatile__ ("movw %%fs,%w0 \n"
: "=r" (selector)
: );
return selector;
}
 
extern __inline__ void
_farnspokeb(unsigned long offset,
unsigned char value)
{
__asm__ __volatile__ (".byte 0x64\n"
" movb %b0,(%k1)"
:
: "qi" (value), "r" (offset));
}
 
extern __inline__ void
_farnspokew(unsigned long offset,
unsigned short value)
{
__asm__ __volatile__ (".byte 0x64\n"
" movw %w0,(%k1)"
:
: "ri" (value), "r" (offset));
}
 
extern __inline__ void
_farnspokel(unsigned long offset,
unsigned long value)
{
__asm__ __volatile__ (".byte 0x64\n"
" movl %k0,(%k1)"
:
: "ri" (value), "r" (offset));
}
 
extern __inline__ unsigned char
_farnspeekb(unsigned long offset)
{
unsigned char result;
__asm__ __volatile__ (".byte 0x64\n"
" movb (%k1),%b0"
: "=q" (result)
: "r" (offset));
return result;
}
 
extern __inline__ unsigned short
_farnspeekw(unsigned long offset)
{
unsigned short result;
__asm__ __volatile__ (".byte 0x64\n"
" movw (%k1),%w0"
: "=r" (result)
: "r" (offset));
return result;
}
 
extern __inline__ unsigned long
_farnspeekl(unsigned long offset)
{
unsigned long result;
__asm__ __volatile__ (".byte 0x64\n"
" movl (%k1),%k0"
: "=r" (result)
: "r" (offset));
return result;
}
 
#endif /* !_POSIX_SOURCE */
#endif /* !__STRICT_ANSI__ */
#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
 
#ifndef __dj_ENFORCE_FUNCTION_CALLS
#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
 
#ifdef __cplusplus
}
#endif
 
#endif /* !__dj_include_sys_farptr_h_ */
/shark/branches/xen/arch/x86/include/arch/ll/i386/cons.h
0,0 → 1,97
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Console output functions */
 
#ifndef __LL_I386_CONS_H__
#define __LL_I386_CONS_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
/* for reference only */
extern int cons_columns; /* number of screen columns */
extern int cons_rows; /* number of screen rows */
 
 
/* X-dependent Console Output functions */
/* Rememeber that console functions are NOT REENTRANT */
/* The console must be considered a preemtable resource */
/* File : Cons.C */
 
void set_visual_page(int page);
void set_active_page(int page);
int get_visual_page(void);
int get_active_page(void);
void place(int x,int y);
void getcursorxy(int *x, int *y);
int get_attr(void);
void cursor(int start,int end);
void _clear(char c,char attr,int x1,int y1,int x2,int y2);
void clear(void);
void _scroll(char attr,int x1,int y1,int x2,int y2);
void scroll(void);
void bios_save(void);
void bios_restore(void);
void cputc(char c);
void cputs(char *s);
int cprintf(char *fmt,...) __attribute__((format(printf,1,2)));
 
/* These functions allow direct access to video RAM */
/* Hence you can use it without the explicit use of */
/* a resource manager */
/* File : Cons.C */
 
void putc_xy(int x,int y,char attr,char c);
char getc_xy(int x,int y,char *attr,char *c);
void puts_xy(int x,int y,char attr,char *s);
int printf_xy(int x,int y,char attr, char *fmt,...) __attribute__((format(printf,4,5)));
 
/* These are simple useful macro! */
#define HOME() place(0,0);
#define CRSR_BLOB() cursor(0,15);
#define CRSR_OFF() cursor(16,16);
#define CRSR_STD() cursor(14,15);
#define NL() cputc('\n');
 
/* Text mode color definitions */
 
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define LIGHTGRAY 7
#define DARKGRAY 8
#define LIGHTBLUE 9
#define LIGHTGREEN 10
#define LIGHTCYAN 11
#define LIGHTRED 12
#define LIGHTMAGENTA 13
#define YELLOW 14
#define WHITE 15
 
END_DEF
 
#endif
 
/shark/branches/xen/arch/x86/include/arch/ll/i386/tss-ctx.h
0,0 → 1,34
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Macros for CONTEXT <-> TSS Translation */
 
#ifndef __LL_I386_TSS_CTX_H__
#define __LL_I386_TSS_CTX_H__
 
#define TSSMax 155
#define TSSMain (TSSMax-1)
#define MAIN_SEL 0xF8
#define TSSBase 0x100
#define TSSsel2index(sel) ((sel-TSSBase)/8)
#define TSSindex2sel(i) (TSSBase + i*8)
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-func.h
0,0 → 1,82
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* As the name says...
All the hardware-dependent functions
IDT/GDT management
context switch
IRQ/Exc handling... */
 
#ifndef __LL_I386_HW_FUNC_H__
#define __LL_I386_HW_FUNC_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-instr.h>
 
/* Low level exit functions! It will halt, reboot or
* give back the control to X, depending on how YAMME started...
*/
void __exit(int code) __attribute__((noreturn));
void halt(void);
 
/* Functions to reboot the machine */
void cold_reboot(void);
void warm_reboot(void);
void reboot(int mode);
 
/* System tables management functions */
void IDT_place(BYTE num,void (*handler)(void));
void GDT_place(WORD sel,DWORD base,DWORD lim,BYTE acc,BYTE gran);
DWORD GDT_read(WORD sel,DWORD *lim,BYTE *acc,BYTE *gran);
LIN_ADDR addr2linear(unsigned short sel,unsigned long offset);
 
/* These 3 function realize the context switching. The context_save has */
/* to be the first call of a kernel primitive, and the context_change has */
/* to be the last call. */
/* The context_save disables the interrupt (a kernel primitive must be */
/* atomic) and return the context of the running task. */
/* The context_change take the context of the new task (or of the */
/* same task), switch to the new context and return restoring the flag */
/* register. */
/* The context_load is used when the task is going to be killed; then its */
/* context does not need to be saved; we only need to load the context of */
/* the new task; the effective implementation of this functions can vary */
/* greatly throughout different implementations as some of them are */
/* mapped to empty functions or mapped one onto another */
 
CONTEXT ll_context_save(void);
void ll_context_change(CONTEXT c);
void ll_context_load(CONTEXT c);
 
CONTEXT ll_context_from(void);
void ll_context_to(CONTEXT c);
 
 
 
void *l1_init(void);
void IDT_init(void);
void l1_end(void);
void l1_int_bind(int i, void *f);
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/mb-hdr.h
0,0 → 1,80
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1996 Erich Boleyn <erich@uruk.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
/*
* MultiBoot Header description
*
*
* struct multiboot_header
* {
* Must be MULTIBOOT_MAGIC - see below.
* unsigned magic;
*
* Feature flags - see below.
* unsigned flags;
*
*
* Checksum
*
* The above fields plus this one must equal 0 mod 2^32.
*
* unsigned checksum;
*
* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.
* unsigned header_addr;
* unsigned load_addr;
* unsigned load_end_addr;
* unsigned bss_end_addr;
* unsigned entry_addr;
* };
*/
/*
* The entire multiboot_header must be contained
* within the first MULTIBOOT_SEARCH bytes of the kernel image.
* #define MULTIBOOT_SEARCH 8192
* #define MULTIBOOT_FOUND(addr, len) \
* (!((addr) & 0x3) && ((len) >= 12) && (*((int *)(addr)) == MULTIBOOT_MAGIC) \
* && !(*((unsigned *)(addr)) + *((unsigned *)(addr+4)) \
* + *((unsigned *)(addr+8))) \
* && (!(MULTIBOOT_AOUT_KLUDGE & *((int *)(addr+4))) || ((len) >= 32)))
*/
 
/* Magic value identifying the multiboot_header. */
#define MULTIBOOT_MAGIC 0x1BADB002
 
/*
* Features flags for 'flags'.
* If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set
* and it doesn't understand it, it must fail.
*/
#define MULTIBOOT_MUSTKNOW 0x0000FFFF
 
/* currently unsupported flags... this is a kind of version number. */
#define MULTIBOOT_UNSUPPORTED 0x0000FFFC
 
/* Align all boot modules on i386 page (4KB) boundaries. */
#define MULTIBOOT_PAGE_ALIGN 0x00000001
 
/* Must pass memory information to OS. */
#define MULTIBOOT_MEMORY_INFO 0x00000002
 
/* This flag indicates the use of the other fields in the header. */
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
 
/shark/branches/xen/arch/x86/include/arch/ll/i386/linkage.h
0,0 → 1,44
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* This file derives from linux/linkage.h. It allows a transparent naming
* between COFF and ELF executable models. We use ELF when we cross-compile
* OSLib from Linux with Linux GCC
*/
 
#ifdef __LINUX__
#define SYMBOL_NAME_STR(X) #X
#define SYMBOL_NAME(X) X
#ifdef __STDC__
#define SYMBOL_NAME_LABEL(X) X##:
#else
#define SYMBOL_NAME_LABEL(X) X/**/:
#endif
#else
#define SYMBOL_NAME_STR(X) "_"#X
#ifdef __STDC__
#define SYMBOL_NAME(X) _##X
#define SYMBOL_NAME_LABEL(X) _##X##:
#else
#define SYMBOL_NAME(X) _/**/X
#define SYMBOL_NAME_LABEL(X) _/**/X/**/:
#endif
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/defs.h
0,0 → 1,46
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Definitions to be used in all .h and .c files */
 
#ifndef __LL_I386_DEFS_H__
#define __LL_I386_DEFS_H__
 
#ifdef __cplusplus
#define BEGIN_DEF extern "C" {
#else
#define BEGIN_DEF
#endif
 
#ifdef __cplusplus
#define END_DEF }
#else
#define END_DEF
#endif
 
#ifdef PROFILE
#define FILE(a) static char FileName[] = "Profile:"#a
#define ASMFILE(a) FileName: .string "Profile:"#a
#else
#define FILE(a)
#define ASMFILE(a)
#endif
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/sel.h
0,0 → 1,43
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Hardware selectors used by OSLib */
 
#ifndef __LL_I386_SEL_H__
#define __LL_I386_SEL_H__
 
#define NULL_SEL 0x00
#define X_DATA16_SEL 0x08
#define X_CODE16_SEL 0x10
#define X_CODE32_SEL 0x18
#define X_RM_BACK_GATE 0x20
#define X_PM_ENTRY_GATE 0x28
#define X_FLATDATA_SEL 0x30
#define X_FLATCODE_SEL 0x38
#define X_CALLBIOS_SEL 0x40
#define X_CALLBIOS_GATE 0x48
 
#define X_VM86_TSS 0x50
#define X_MAIN_TSS 0x58
#define X_FLATDATA3_SEL 0x60
#define X_FLATCODE3_SEL 0x68
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-io.h
0,0 → 1,94
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The hw I/O instructions
Never include this file!!! Include hw-instr.h instead!!! */
#ifndef __LL_I386_HW_IO_H__
#define __LL_I386_HW_IO_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
 
/*
The code for inp, outp, inpw, outpw, inpd & outpd is from
standard GNU C distribution!
The full source code for the GNU-C distribution is available
from www.delorie.com
 
The following code is ...
copyright (C) 1995 DJ Delorie, see COPYING.DJ for details
*/
 
INLINE_OP unsigned char inp(unsigned short _port)
{
unsigned char rv;
__asm__ __volatile__ ("inb %1, %0"
: "=a" (rv)
: "d" (_port));
return(rv);
}
 
INLINE_OP unsigned short inpw (unsigned short _port)
{
unsigned short rv;
__asm__ __volatile__ ("inw %1, %0"
: "=a" (rv)
: "d" (_port));
return(rv);
}
 
INLINE_OP unsigned long inpd(unsigned short _port)
{
unsigned long rv;
__asm__ __volatile__ ("inl %1, %0"
: "=a" (rv)
: "d" (_port));
return(rv);
}
 
INLINE_OP void outp(unsigned short _port, unsigned char _data)
{
__asm__ __volatile__ ("outb %1, %0"
:
: "d" (_port),
"a" (_data));
}
 
INLINE_OP void outpw(unsigned short _port, unsigned short _data)
{
__asm__ __volatile__ ("outw %1, %0"
:
: "d" (_port),
"a" (_data));
}
 
INLINE_OP void outpd(unsigned short _port, unsigned long _data)
{
__asm__ __volatile__ ("outl %1, %0"
:
: "d" (_port),
"a" (_data));
}
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/i386/mb-info.h
0,0 → 1,228
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1996 Erich Boleyn <erich@uruk.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
#ifndef __LL_I386_MB_INFO_H__
#define __LL_I386_MB_INFO_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
 
/*
* The structure type "mod_list" is used by the "multiboot_info" structure.
*/
 
struct mod_list
{
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
unsigned long mod_start;
unsigned long mod_end;
 
/* Module command line */
unsigned long cmdline;
 
/* padding to take it to 16 bytes (must be zero) */
unsigned long pad;
};
 
 
/*
* INT-15, AX=E820 style "AddressRangeDescriptor"
* ...with a "size" parameter on the front which is the structure size - 4,
* pointing to the next one, up until the full buffer length of the memory
* map has been reached.
*/
 
struct AddrRangeDesc
{
unsigned long size;
unsigned long BaseAddrLow;
unsigned long BaseAddrHigh;
unsigned long LengthLow;
unsigned long LengthHigh;
unsigned long Type;
 
/* unspecified optional padding... */
};
 
/* usable memory "Type", all others are reserved. */
#define MB_ARD_MEMORY 1
 
/*
* MultiBoot Info description
*
* This is the struct passed to the boot image. This is done by placing
* its address in the EAX register.
*/
 
struct multiboot_info
{
/* MultiBoot info version number */
unsigned long flags;
 
/* Available memory from BIOS */
unsigned long mem_lower;
unsigned long mem_upper;
/* "root" partition */
unsigned long boot_device;
 
/* Kernel command line */
unsigned long cmdline;
 
/* Boot-Module list */
unsigned long mods_count;
unsigned long mods_addr;
 
union
{
struct
{
/* (a.out) Kernel symbol table info */
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long pad;
} a;
 
struct
{
/* (ELF) Kernel section header table */
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
} e;
} syms;
 
/* Memory Mapping buffer */
unsigned long mmap_length;
unsigned long mmap_addr;
 
/* Drive Info buffer */
unsigned long drives_length;
unsigned long drives_addr;
/* ROM configuration table */
unsigned long config_table;
/* Boot Loader Name */
unsigned long boot_loader_name;
 
/* APM table */
unsigned long apm_table;
 
/* Video */
unsigned long vbe_control_info;
unsigned long vbe_mode_info;
unsigned short vbe_mode;
unsigned short vbe_interface_seg;
unsigned short vbe_interface_off;
unsigned short vbe_interface_len;
#ifndef __OLD_MB__
/*
Gerardo: I need to add also the phisical address base for
both low ( < 1MB) & upper ( > 1MB) memory, as X starts from DOS
which could have preallocated some of this memory...
For example, GRUB assumes that mem_lowbase = 0x0 &
mem_upbase = 0x100000
*/
unsigned long mem_lowbase;
unsigned long mem_upbase;
#endif /* __OLD_MB__ */
};
 
/*
* Flags to be set in the 'flags' parameter above
*/
 
/* is there basic lower/upper memory information? */
#define MB_INFO_MEMORY 0x1
/* is there a boot device set? */
#define MB_INFO_BOOTDEV 0x2
/* is the command-line defined? */
#define MB_INFO_CMDLINE 0x4
/* are there modules to do something with? */
#define MB_INFO_MODS 0x8
 
/* These next two are mutually exclusive */
 
/* is there a symbol table loaded? */
#define MB_INFO_AOUT_SYMS 0x10
/* is there an ELF section header table? */
#define MB_INFO_ELF_SHDR 0x20
 
/* is there a full memory map? */
#define MB_INFO_MEM_MAP 0x40
 
/* Is there drive info? */
#define MB_INFO_DRIVE_INFO 0x00000080
 
/* Is there a config table? */
#define MB_INFO_CONFIG_TABLE 0x00000100
 
/* Is there a boot loader name? */
#define MB_INFO_BOOT_LOADER_NAME 0x00000200
 
/* Is there a APM table? */
#define MB_INFO_APM_TABLE 0x00000400
 
/* Is there video information? */
#define MB_INFO_VIDEO_INFO 0x00000800
 
#if 0
/* Gerardo: Added this!
--------------------
The idea is that the BootLoader provides an interface
to return back to it; this is useful to implement a DOS
boot-loader, in order to use DOS as development environment.
*/
#define MB_INFO_USEGDT 0x80
#endif
/*
* The following value must be present in the EAX register.
*/
 
#define MULTIBOOT_VALID 0x2BADB002
 
struct multiboot_info * mbi_address(void);
 
END_DEF
 
#endif
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/time.h
0,0 → 1,162
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Inline functions for managing timespec structures.
All timespec values are pointers!!!
This file defines these functions:
TIMESPEC2NANOSEC(t)
converts a timespec value to a nanosec value, and return
it, no checks
TIMESPEC2USEC(t)
converts a timespec value to a nanosec value, and return
it, no checks
NULL_TIMESPEC(t)
the timespec value is set to the Epoch (=0)
ADDNANO2TIMESPEC(n, t)
t = t + n
ADDUSEC2TIMESPEC(m, t)
t = t + m
SUBTIMESPEC(s1, s2, d) Works well only if s1 >= s2
d = s1 - s2
ADDTIMESPEC(s1, s2, d)
d = s1 + s2
TIMESPEC_A_LT_B(a,b)
a < b
TIMESPEC_A_GT_B(a,b)
a > b
TIMESPEC_A_EQ_B(a,b)
a == b
TIMESPEC_A_NEQ_B(a,b)
a != b
TIMESPEC_ASSIGN(t1,t2)
t1 = t2 */
 
#ifndef __LL_SYS_LL_TIME_H__
#define __LL_SYS_LL_TIME_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
 
struct timespec {
long tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
};
 
#endif
 
/*
* these macros come from the Utah Flux oskit...
*/
 
#define TIMESPEC2NANOSEC(t) ((t)->tv_sec * 1000000000 + (t)->tv_nsec)
#define TIMESPEC2USEC(t) ((t)->tv_sec * 1000000 + (t)->tv_nsec / 1000)
#define NULL_TIMESPEC(t) ((t)->tv_sec = (t)->tv_nsec = 0)
#define ADDNANO2TIMESPEC(n, t) ((t)->tv_nsec += (n), \
(t)->tv_sec += (t)->tv_nsec / 1000000000, \
(t)->tv_nsec %= 1000000000)
 
#define SUBTIMESPEC(s1, s2, d) \
((d)->tv_nsec = ((s1)->tv_nsec >= (s2)->tv_nsec) ? \
(((d)->tv_sec = (s1)->tv_sec - (s2)->tv_sec), \
(s1)->tv_nsec - (s2)->tv_nsec) \
: \
(((d)->tv_sec = (s1)->tv_sec - (s2)->tv_sec - 1), \
(1000000000 + (s1)->tv_nsec - (s2)->tv_nsec)))
 
/*
* ...and these not!
*/
 
extern __inline__ void ADDTIMESPEC(const struct timespec *s1,
const struct timespec *s2,
struct timespec *d)
{
d->tv_sec = s1->tv_sec + s2->tv_sec;
d->tv_nsec = s1->tv_nsec + s2->tv_nsec;
 
if (d->tv_nsec < 0) {
d->tv_sec--;
d->tv_nsec += 1000000000;
} else if (d->tv_nsec >= 1000000000) {
d->tv_sec++;
d->tv_nsec -= 1000000000;
}
}
 
 
#define ADDUSEC2TIMESPEC(m, t) ((t)->tv_nsec += (m%1000000)*1000, \
(t)->tv_sec += ((t)->tv_nsec / 1000000000) + (m/1000000), \
(t)->tv_nsec %= 1000000000)
 
#define TIMESPEC_A_LT_B(a,b) \
( \
((a)->tv_sec < (b)->tv_sec) || \
((a)->tv_sec == (b)->tv_sec && (a)->tv_nsec < (b)->tv_nsec) \
)
 
#define TIMESPEC_A_GT_B(a,b) \
( \
((a)->tv_sec > (b)->tv_sec) || \
((a)->tv_sec == (b)->tv_sec && (a)->tv_nsec > (b)->tv_nsec) \
)
 
#define TIMESPEC_A_EQ_B(a,b) \
((a)->tv_sec == (b)->tv_sec && (a)->tv_nsec == (b)->tv_nsec)
 
#define TIMESPEC_A_NEQ_B(a,b) \
((a)->tv_sec != (b)->tv_sec || (a)->tv_nsec != (b)->tv_nsec)
 
#define TIMESPEC_ASSIGN(t1,t2) \
((t1)->tv_sec = (t2)->tv_sec, (t1)->tv_nsec = (t2)->tv_nsec)
 
#if 0
#define PITSPEC2TIMESPEC(a,b) \
((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197) * 1000, \
(b)->tv_sec = ((a)->gigas * 1197) / 1000) /*, \
(b)->tv_sec += (b)->tv_nsec / 1000000000, \
(b)->tv_nsec %= 1000000000) */
#else
/*#define PITSPEC2TIMESPEC(a,b) \
((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197) * 1000, \
(b)->tv_nsec += (((a)->gigas * 1197) % 1000) * 1000000, \
(b)->tv_sec = ((a)->gigas * 1197) / 1000 , \
(b)->tv_sec += (b)->tv_nsec / 1000000000, \
(b)->tv_nsec %= 1000000000)*/
#define PITSPEC2TIMESPEC(a,b) \
((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1193), \
(b)->tv_nsec += (((a)->gigas * 1193) % 1000) * 1000, \
(b)->tv_sec = ((a)->gigas * 1193) / 1000 , \
(b)->tv_sec += (b)->tv_nsec / 1000000, \
(b)->tv_nsec %= 1000000, \
(b)->tv_nsec *= 1000)
#endif
 
TIME ll_gettime(int mode, struct timespec *tsres);
 
#define TIME_PTICK 1
#define TIME_EXACT 2
#define TIME_NEW 3
 
END_DEF
#endif
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/event.h
0,0 → 1,85
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Time event management functions */
 
#ifndef __LL_SYS_LL_EVENT_H__
#define __LL_SYS_LL_EVENT_H__
 
#include <ll/i386/defs.h>
#include <ll/sys/ll/time.h>
#include <ll/sys/ll/ll-data.h>
 
BEGIN_DEF
 
#define MAX_EVENT 250
 
struct event {
struct event *next; /* Next event in an event queue */
void *par; /* Handler's parameter */
void (*handler)(void *p); /* Event Handler */
struct timespec time; /* Time at which the event
will raise */
int index; /* Event ID */
};
 
/* Event management functions... */
 
void event_setprologue(void *p);
void event_setepilogue(void *p);
 
void event_setlasthandler(void *p);
 
int (*event_post)(struct timespec time, void (*handler)(void *p), void *par);
int (*event_delete)(int index);
 
int oneshot_event_post(struct timespec time, void (*handler)(void *p), void *par);
int oneshot_event_delete(int index);
int periodic_event_post(struct timespec time, void (*handler)(void *p), void *par);
int periodic_event_delete(int index);
void event_init(struct ll_initparms *l);
 
/* Interrupt handler entry */
struct intentry {
void *par; /* Handler's parameter */
void (*handler)(void *p); /* Interrupt Handler */
int index; /* Interrupt number */
DWORD status; /* Interrupt status
no handler --> FREE
handler --> ASSIGNED
being served --> BUSY
*/
DWORD flags;
};
 
#define INT_PREEMPTABLE 1
#define INT_FORCE 2
 
#define INTSTAT_FREE 1
#define INTSTAT_ASSIGNED 2
#define INTSTAT_BUSY 3
 
void irq_init(void);
int irq_bind(int irq, void (*handler)(void *p), DWORD flags);
int ll_ActiveInt();
 
END_DEF
#endif
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/aspace.h
0,0 → 1,66
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Address spaces code & data */
 
#ifndef __LL_SYS_LL_ASPACE_H__
#define __LL_SYS_LL_ASPACE_H__
 
#include <ll/i386/defs.h>
 
/* I dont't know if we really need all these things... */
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/tss-ctx.h>
 
BEGIN_DEF
 
struct as {
DWORD base;
DWORD limit;
WORD status;
};
/* An Address Space descriptor is a Segment descriptor... so it is a WORD... */
#define AS WORD
 
#define AS_FREE 0
#define AS_BUSY 1
 
#define ASMax 60
 
#if 0
#define ASBase 0x300 /* Is it correct? TSSBase + 64 *8... */
#endif
 
#define ASBase (TSSBase + TSSMax * 8)
#define ASsel2index(sel) ((sel-ASBase) / 16)
#define ASindex2sel(i) (ASBase + i * 16)
 
 
void as_init(void);
AS as_create(void);
int as_bind(AS as, DWORD ph_addr, DWORD l_addr, DWORD size);
 
 
END_DEF
 
#endif /* __LL_SYS_LL_ASPACE_H__ */
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-func.h
0,0 → 1,56
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Kernel Library functions interfaces */
 
#ifndef __LL_SYS_LL_LL_FUNC_H_
#define __LL_SYS_LL_LL_FUNC_H_
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
 
#include <ll/sys/ll/ll-data.h>
 
void ll_context_setspace(CONTEXT c, WORD as);
CONTEXT ll_context_create(void (*task)(void *p),BYTE *stack,
void *parm,void (*killer)(void),WORD ctrl);
 
/* Release a used task context */
void ll_context_delete(CONTEXT c);
 
/* Put the context value into human readable form; used for debug! */
char *ll_context_sprintf(char *str,CONTEXT c);
 
/* These functions start-up & close the ll layer */
 
void *ll_init(void);
void ll_end(void);
 
/* This functions acts as safety place where to go when any error */
/* occurs and we do not know what context is active */
void ll_abort(int code);
 
END_DEF
#endif /* __LL_SYS_LL_LL_MEM_H_ */
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-data.h
0,0 → 1,44
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Kernel Library data structures definitions */
 
#ifndef __LL_SYS_LL_LL_DATA_H__
#define __LL_SYS_LL_LL_DATA_H__
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
 
/* These are used by the ll_init function... */
#define LL_PERIODIC 0
#define LL_ONESHOT 1
 
struct ll_initparms {
DWORD mode;
TIME tick;
};
 
END_DEF
#endif /* __LL_SYS_LL_LL_DATA_H__ */
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/exc.h
0,0 → 1,40
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Hardware exceptions */
 
#ifndef __LL_SYS_LL_HW_EXC_H__
#define __LL_SYS_LL_HW_EXC_H__
 
#define DIV_BY_0 0 /* These are the ll... exceptions */
#define MATH_EXC 1
#define NMI_EXC 2
#define DEBUG_EXC 3
#define BREAKPOINT_EXC 4
#define HW_FAULT 5
#define NO_MORE_HW_DESC 6
#define VM86_PANIC 7
/* Please, do not confuse them with the HW exception!!! */
 
#define CLOCK_OVERRUN 64 /* Warning this is used in vm1.asm */
 
#endif /* __LL_SYS_LL_HW_EXC_H__ */
 
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-mem.h
0,0 → 1,38
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Some memory management code */
 
#ifndef __LL_SYS_LL_LL_MEM_H_
#define __LL_SYS_LL_LL_MEM_H_
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
/* These function are used to manage memory at ll layer */
 
void * ll_alloc(DWORD size);
WORD ll_free(void *ptr,DWORD size);
void ll_mem_init(void *base,DWORD size);
void ll_mem_dump(void);
 
END_DEF
#endif /* __LL_SYS_LL_LL_MEM_H_ */
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-instr.h
0,0 → 1,57
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
#ifndef __LL_SYS_LL_LL_INSTR_H_
#define __LL_SYS_LL_LL_INSTR_H_
 
#include <ll/i386/defs.h>
BEGIN_DEF
 
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-func.h>
/*
Well, these are simple macros... to map the HARTIK names
onto the standard names!
*/
#define ll_in(port) inp(port)
#define ll_out(port,v) outp(port,v)
#define ll_inw(port) inpw(port)
#define ll_outw(port,v) outpw(port,v)
#define ll_ind(port) inpd(port)
#define ll_outd(port,v) outpd(port,v)
 
 
 
/* These functions are used to mask/unmask selectively interrupts */
/* The irq services are also #defined to allow more generic inteface */
/* This is done into hw... files! */
 
void ll_irq_mask(WORD irqno);
void ll_irq_unmask(WORD irqno);
 
/* These functions provide direct access to interrupt table */
/* We can write the HARTIK interrupt table but only read */
/* the host OS interrupt table! */
void ll_irq_set(WORD irqno,INTERRUPT handler);
INTERRUPT ll_irq_get(WORD irqno);
 
END_DEF
#endif
/shark/branches/xen/arch/x86/include/arch/ll/sys/types.h
0,0 → 1,45
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
#ifndef __LL_SYS_TYPES_H__
#define __LL_SYS_TYPES_H__
 
#include <ll/i386/hw-data.h>
 
#define size_t DWORD
#define ssize_t long int
#define va_list void*
 
#define u_int unsigned int
#define u_char BYTE
#define u_short WORD
#define u_long DWORD
 
/* unsigned integers */
typedef BYTE u_int8_t;
typedef WORD u_int16_t;
typedef DWORD u_int32_t;
 
/* signed integers */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
#endif
/shark/branches/xen/arch/x86/include/arch/ll/ll.h
0,0 → 1,51
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* The abominious: an ``include all'' header!!! */
 
#ifndef __LL_LL_H__
 
#define __LL_LL_H__
 
#include <ll/sys/ll/aspace.h>
#include <ll/sys/ll/event.h>
#include <ll/sys/ll/exc.h>
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/time.h>
#include <ll/sys/ll/ll-instr.h>
#include <ll/sys/ll/ll-mem.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-io.h>
#include <ll/i386/linkage.h>
#include <ll/i386/mb-hdr.h>
#include <ll/i386/mb-info.h>
#include <ll/i386/mem.h>
#include <ll/i386/sel.h>
#include <ll/i386/tss-ctx.h>
#include <ll/i386/x-bios.h>
#include <ll/i386/x-dos.h>
 
#endif
/shark/branches/xen/arch/x86/xsys0.s
0,0 → 1,102
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Provides the _exit function for escaping from PM!!! */
 
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
#include <ll/i386/sel.h>
#include <ll/i386/defs.h>
 
.data
 
ASMFILE(X0-Sys)
 
.text
 
.globl SYMBOL_NAME(_x_callBIOS)
 
#ifdef __NO_INLINE_PORT__
.globl SYMBOL_NAME(outp)
.globl SYMBOL_NAME(inp)
.globl SYMBOL_NAME(outpw)
.globl SYMBOL_NAME(inpw)
.globl SYMBOL_NAME(outpd)
.globl SYMBOL_NAME(inpd)
#endif
 
/* Invoke 16 bit BIOS function from PM application */
 
/* void _x_callBIOS(void) */
 
SYMBOL_NAME_LABEL(_x_callBIOS)
.byte 0x09a /* Direct gate call */
.long 0
.word X_CALLBIOS_GATE
ret
 
#ifdef __NO_INLINE_PORT__
/* void outp(int port,char value) */
 
SYMBOL_NAME_LABEL(outp)
movl 4(%esp),%edx
movl 8(%esp),%eax
outb %al,%dx
ret
 
/* char inp(int port) */
 
SYMBOL_NAME_LABEL(inp)
movl 4(%esp),%edx
inb %dx,%al
movzb %al,%eax
ret
 
/* void outpw(int port,unsigned short value) */
 
SYMBOL_NAME_LABEL(outpw)
movl 4(%esp),%edx
movl 8(%esp),%eax
outw %ax,%dx
ret
 
/* unsigned short inpw(int port) */
 
SYMBOL_NAME_LABEL(inpw)
movl 4(%esp),%edx
inw %dx,%ax
movzwl %ax,%eax
ret
/* void outpd(int port,unsigned long value) */
 
SYMBOL_NAME_LABEL(outpd)
movl 4(%esp),%edx
movl 8(%esp),%eax
outl %eax,%dx
ret
 
/* unsigned long inpd(int port) */
 
SYMBOL_NAME_LABEL(inpd)
movl 4(%esp),%edx
inl %dx,%eax
ret
#endif /* __NO_INLINE_PORTS__ */
/shark/branches/xen/arch/x86/ctxsw.c
0,0 → 1,71
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Context switch code */
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/tss-ctx.h>
 
#include <tracer.h>
 
FILE(Context-Switch);
 
extern unsigned short int currCtx;
#ifdef __VIRCSW__
extern int activeInt;
#endif
 
extern void context_load(CONTEXT c);
 
void ll_context_to(CONTEXT c)
{
#ifdef __VIRCSW__
currCtx = c;
if (activeInt == 0) {
TRACER_LOGEVENT(FTrace_EVT_context_switch, (unsigned short int)c, 0);
context_load(c);
}
#else
currCtx = c;
context_load(c);
#endif
}
CONTEXT ll_context_from(void)
{
#ifdef __VIRCSW__
return currCtx;
#else
return context_save();
#endif
}
 
CONTEXT ll_context_save(void)
{
return currCtx;
}
 
void ll_context_load(CONTEXT c)
{
currCtx = c;
TRACER_LOGEVENT(FTrace_EVT_context_switch, (unsigned short int)c, 0);
context_load(c);
}
/shark/branches/xen/arch/x86/ctx.s
0,0 → 1,94
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Context switch code */
 
#include <ll/i386/sel.h>
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
 
.data
 
ASMFILE(Context)
 
.globl SYMBOL_NAME(currCtx)
.globl JmpSel
.globl JmpZone
 
SYMBOL_NAME_LABEL(currCtx) .word 0
 
JmpZone:
JmpOffset:
.word 0
.word 0
JmpSel:
.word 0
 
.text
 
.globl SYMBOL_NAME(context_save)
.globl SYMBOL_NAME(context_change)
.globl SYMBOL_NAME(context_load)
.globl SYMBOL_NAME(init_TR)
 
/* This function assign a value to the TASK register of 386 architecture */
/* We MUST do this BEFORE we use the HW multitask */
 
SYMBOL_NAME_LABEL(init_TR)
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
ltrw %ax
movw %ax,JmpSel
movw %ax,SYMBOL_NAME(currCtx)
popl %ebp
ret
/* CONTEXT __cdecl context_save(void); */
/* The context is returned into AX; Interrupts are also cleared as we are */
/* entering into kernel primitives */
 
SYMBOL_NAME_LABEL(context_save)
xorl %eax,%eax
strw %ax
ret
 
/* void __cdecl context_change(CONTEXT c) */
/* Use 386 task switch ability. This is the last call of any preemption */
/* generating primitive; when the original task is re-activated the */
/* interrupt flag is restored with STI */
/* In 32 bit systems, context_load is an alias for context_change!*/
 
SYMBOL_NAME_LABEL(context_load)
SYMBOL_NAME_LABEL(context_change)
pushl %ebp
movl %esp,%ebp
movw $(X_FLATDATA_SEL),%ax
movw %ax,%ds
movw %ax,%es
movl 8(%ebp),%eax
cmpw JmpSel,%ax
je NoPreempt
movw %ax,JmpSel
ljmp *JmpZone
NoPreempt: popl %ebp
ret
 
/shark/branches/xen/arch/x86/event.c
0,0 → 1,330
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Added Advanced Timer Code
*
* Date: 8.4.2003
* Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
*
*/
 
/* Time Event routines */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/mem.h>
#include <ll/i386/error.h>
#include <ll/i386/hw-arch.h>
#include <ll/i386/pic.h>
#include <ll/i386/pit.h>
#include <ll/i386/apic.h>
#include <ll/i386/advtimer.h>
#include <ll/i386/64bit.h>
 
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/ll-instr.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/time.h>
#include <ll/sys/ll/event.h>
 
#include <tracer.h>
extern unsigned short int currCtx;
 
FILE(Event);
 
extern LL_ARCH ll_arch;
 
BYTE frc;
 
/* Timer 0 usec base tick */
DWORD ticksize;
 
/* Timer 0 loaded time constant (= ticksize * 1.197) */
WORD pit_time_const;
DWORD timermode;
 
static DWORD nts; /* System tick in nanoSeconds... */
struct timespec actTime; /* Time (in nanosecs)... */
extern int activeInt;
 
WORD lastTime;
struct pitspec globalCounter;
 
struct event eventlist[MAX_EVENT];
 
struct event *freeevents;
struct event *firstevent;
 
extern void *last_handler;
extern void (*evt_prol) (void);
extern void (*evt_epil) (void);
 
extern unsigned int apic_clk_per_msec;
extern unsigned char use_apic, use_tsc;
 
void event_setlasthandler(void *p)
{
last_handler = p;
}
 
void event_setprologue(void *p)
{
evt_prol = p;
}
 
void event_setepilogue(void *p)
{
evt_epil = p;
}
 
/* Switched to timespec */
int periodic_event_post(struct timespec time, void (*handler) (void *p), void *par)
{
struct event *p;
struct event *p1, *t;
 
TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0);
 
if (!freeevents) {
message("NO FREE EVENTS !\n");
ll_abort(20);
return -1;
}
 
/* Extract from the ``free events'' queue */
p = freeevents;
freeevents = p->next;
 
/* Fill the event fields */
p->handler = handler;
TIMESPEC_ASSIGN(&(p->time), &time);
p->par = par;
 
/* ...And insert it in the event queue!!! */
 
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; p1; p1 = t->next) {
/*
SUBTIMESPEC(&time, &(p1->time), &tmp);
if ((tmp.tv_sec > 0) && (tmp.tv_nsec > 0)) {
*/
if (TIMESPEC_A_GT_B(&time, &p1->time))
t = p1;
else
break;
}
 
/* adjust next entry */
if (t) {
t->next = p;
} else {
firstevent = p;
}
p->next = p1;
 
return p->index;
}
 
int periodic_event_delete(int index)
{
struct event *p1, *t;
 
TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
 
if (index == -1)
return -1;
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
t = p1;
}
 
if (p1 == NULL) {
return -1;
}
 
if (t == NULL) {
firstevent = p1->next;
} else {
t->next = p1->next;
}
p1->next = freeevents;
freeevents = p1;
 
return 1;
}
 
void periodic_wake_up(void)
{
/* CHANGE the NAME, please... */
struct event *p, *pp;
WORD tmp;
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0);
 
if (!use_tsc) {
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
}
 
activeInt++;
if (activeInt == 1 && evt_prol != NULL) {
evt_prol();
}
 
if (use_tsc)
ll_read_timespec(&actTime);
else
ADDNANO2TIMESPEC(nts, &actTime);
for (p = firstevent; p != NULL; p = pp) {
/*
SUBTIMESPEC(&(p->time), &actTime, &tmp);
if ((tmp.tv_sec > 0) && (tmp.tv_nsec > 0)) {
break;
} */
if ((p->time.tv_sec > actTime.tv_sec) ||
((p->time.tv_sec == actTime.tv_sec)
&& (p->time.tv_nsec > actTime.tv_nsec))) {
break;
}
pp = p->next;
p->next = freeevents;
freeevents = p;
firstevent = pp;
p->handler(p->par);
}
 
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
}
 
void event_init(struct ll_initparms *l)
{
extern void ll_timer(void);
extern void ll_apic_timer(void);
int i;
BYTE mask;
TIME t;
DWORD apic_clk;
 
ll_init_advtimer();
 
if (use_apic)
IDT_place(0x39,ll_apic_timer);
else
IDT_place(0x40,ll_timer);
 
if (l->mode != LL_PERIODIC) {
message("One-shot mode\n");
t = 0;
if (use_apic) {
set_APIC_timer(0xFFFFFFFF);
enable_APIC_timer();
} else {
/* Mode: Binary/Mode 4/16 bit Time_const/Counter 0 */
pit_init(0, TMR_MD4, 0xFFFF); /* Timer 0, Mode 4, constant 0xFFFF */
}
} else {
t = l->tick;
/* Translate the tick value in usec into a suitable time constant */
/* for 8254 timer chip; the chip is driven with a 1.19718 MHz */
/* frequency; then the effective frequency is given by the base */
/* frequency divided for the time constant; the tick is the inverse */
/* of this effective frequency (in usec!) */
/* Time-Constant = f_base (MHz) * tick (usec) */
/* If T-C == 0 -> T-C = 65536 (Max available) */
ticksize = t;
 
if (use_apic) {
mul32div32to32(t,apic_clk_per_msec,1000,apic_clk);
set_APIC_timer(apic_clk);
enable_APIC_timer();
} else {
mul32div32to32(t,1193182,1000000,t);
 
/* Only for security! This should cause timer overrun */
/* While 0 would set maximum period on timer */
if (t == 0)
t = 1;
pit_time_const = (WORD) (t & 0xFFFF);
/* Mode: Binary/Mode 2/16 bit Time_const/Counter 0 */
pit_init(0, TMR_MD2, t); /* Timer 0, Mode 2, Time constant t */
}
}
timermode = l->mode;
if (!use_apic) {
if (ll_arch.x86.cpu > 4) {
/* Timer1: mode 0, time const 0... */
pit_init(1, TMR_MD0, 0);
frc = 1;
} else {
frc = 2;
pit_init(2, TMR_MD0, 0);
outp(0x61, 3);
}
}
 
mask = ll_in(0x21);
mask &= 0xFE; /* 0xFE = ~0x01 */
ll_out(0x21, mask);
 
/* Init the event list... */
for (i = 0; i < MAX_EVENT; i++) {
if (i < MAX_EVENT - 1) {
eventlist[i].next = &(eventlist[i + 1]);
}
eventlist[i].index = i;
}
eventlist[MAX_EVENT - 1].next = NULL;
freeevents = &(eventlist[0]);
 
evt_prol = NULL;
evt_epil = NULL;
 
/* Initialization of the time variables for periodic mode */
nts = ticksize * 1000;
NULL_TIMESPEC(&actTime);
/* Initialization of the general time variables */
NULLPITSPEC(&globalCounter);
lastTime = 0;
 
if (timermode == LL_PERIODIC) {
event_post = periodic_event_post;
event_delete = periodic_event_delete;
} else {
event_post = oneshot_event_post;
event_delete = oneshot_event_delete;
}
 
/* Last but not least... */
if (!use_apic)
irq_unmask(0);
}
/shark/branches/xen/arch/x86/estub.c
0,0 → 1,108
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
#include <stdlib.h>
#include <stdio.h>
#include <hw-data.h>
#include "event.h"
 
FILE(Event-Stub);
 
extern struct event *freeevents;
extern struct event *firstevent;
extern TIME actTime;
 
 
void called(void)
{
printf("Called...\n");
}
 
void event_printqueue(struct event *q)
{
struct event *p;
 
for (p = q; p; p = p->next) {
printf("Entry %d: Time %d...\n", p->index, p->time);
}
}
 
main()
{
int i, rem;
event_init();
 
printf("Free event queue:\n");
event_printqueue(freeevents);
printf("Pending events queue:\n");
event_printqueue(firstevent);
i = event_post(10, called, NULL);
printf("Inserted Event %d\n", i);
printf("Free event queue:\n");
event_printqueue(freeevents);
printf("Pending events queue:\n");
event_printqueue(firstevent);
i = event_post(100, called, NULL);
printf("Inserted Event %d\n", i);
 
i = event_post(5, called, NULL);
printf("Inserted Event %d\n", i);
i = event_post(50, called, NULL);
printf("Inserted Event %d\n", i);
i = event_post(1, called, NULL);
printf("Inserted Event %d\n", i);
i = event_post(110, called, NULL);
printf("Inserted Event %d\n", i);
 
printf("Pending events queue:\n");
event_printqueue(firstevent);
 
printf("Now, Wakin' up...\n");
 
actTime = 1;
wake_up(10);
printf("Pending events queue:\n");
event_printqueue(firstevent);
 
actTime = 70;
wake_up(10);
i = event_post(45, called, NULL);
i = event_post(80, called, NULL);
i = event_post(20, called, NULL);
rem = event_post(90, called, NULL);
i = event_post(105, called, NULL);
i = event_post(150, called, NULL);
printf("Pending events queue:\n");
event_printqueue(firstevent);
i = event_delete(rem);
printf("EVT %d removed...OK=%d Pending events queue:\n", rem, i);
event_printqueue(firstevent);
i = event_delete(6);
printf("EVT 6 removed...OK=%d Pending events queue:\n", i);
i = event_delete(2);
printf("EVT 2 removed...OK=%d Pending events queue:\n", i);
i = event_delete(8);
printf("EVT 8 removed...OK=%d Pending events queue:\n", i);
event_printqueue(firstevent);
}
/shark/branches/xen/arch/x86/abort.s
0,0 → 1,61
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Safe abort routine & timer asm handler */
 
.title "Abort.S"
 
#include <ll/i386/sel.h>
#include <ll/i386/linkage.h>
#include <ll/i386/defs.h>
 
#include <ll/sys/ll/exc.h>
 
.data
 
ASMFILE(Abort)
 
#define SAFESTACKSIZE 4096
 
.bss
/* Safe stack area for aborts */
.space 4096,0
SafeStack:
 
.extern SYMBOL_NAME(act_int)
.extern SYMBOL_NAME(abort_tail)
 
.text
 
.globl SYMBOL_NAME(ll_abort)
 
SYMBOL_NAME_LABEL(ll_abort)
/* As we are terminating we cannnot handle */
/* any other interrupt! */
cli
/* Get argument */
movl 4(%esp),%eax
/* Switch to safe stack */
movl $(SafeStack),%esp
/* Push argument */
pushl %eax
/* Call sys_abort(code) */
call SYMBOL_NAME(abort_tail)
/shark/branches/xen/arch/x86/x1.c
0,0 → 1,147
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* File: X1.C */
/* Startup code: */
/* Build parameters list & make info accessible */
 
#include <arch/stdlib.h>
#include <ll/i386/hw-func.h>
#include <ll/i386/cons.h>
#include <ll/i386/mb-info.h>
 
#include <ll/i386/mem.h>
 
FILE(X1);
 
/* #define __DUMP_MEM__ */
 
/* We need to copy from X address space to the application space */
/* the info structure to allow pointer access using flat model */
/* Remember that flat model is similar to small model also if we */
/* can see the whole memory, because it has no explicit far */
/* pointers; then if we pass into _args[] the address of the */
/* string of the n-th argument it could not be correctly accessed */
/* because it lies in a memory zone unseen from PM application. */
/* This is due to the ELF format which has no relocation info */
/* since the file is already relocated starting from address 0! */
/* Then the PM application cannot see a real flat memory (segment */
/* with 0 base) but CS,DS & SS MUST have the base correctly set. */
/* Refer to this figure: */
/* */
/* DOS Memory <- X is there */
/* */
/* EXTENDED Memory -----[ */
/* [ */
/* Address xxxx [ <- Application code is here! */
/* [ */
/* Address yyyy [ <- Application Data & Stack! */
/* */
/* Then CS has xxxx base while DS & SS have yyyy base! */
 
/* Stack base address; use this to check stack overflow! */
/* With Flat model I do not think we can use 386 protection */
/* to detect a stack overflow; anyway Watcom C use a standard */
/* function __CHK to detect it! The compiler place it whenever */
/* it calls a function to detect overflow */
 
DWORD _stkbase;
DWORD _stktop;
 
/* This is some extra stuff we need to compile with argument */
/* passing and math extensions */
DWORD _argc = 0;
typedef char *charp;
charp _argv[100];
 
#ifndef MAIN
#define MAIN main
#endif
 
extern void MAIN(int argc,char *argv[]);
extern void bios_save(void);
extern void bios_restore(void);
 
/* This is used in GNU-C to implement C++ constructors/destructors */
/* See the lib sources for more details */
void __main(int argc, char **argv)
{
}
 
 
struct multiboot_info * mbi_address(void)
{
/* This is declared in [wc32/gnu]\x0.[asm/s] */
extern struct multiboot_info *mbi;
 
return (mbi);
}
 
void _startup(void)
{
register int i = 0;
char temp[1000];
struct multiboot_info *mbi = mbi_address();
char *cmdline = (char *)(mbi->cmdline);
 
if (!(mbi->flags & MB_INFO_MEMORY)) {
cputs("X/Runtime library error!!! Unable to find memory information!\n");
l1_exit(-1);
}
 
if (mbi->flags & MB_INFO_CMDLINE) {
/* Build parameter list, up to 100 parms... */
while (cmdline[i] != 0 && i < 1000) {
temp[i] = cmdline[i];
_argv[_argc] = &(temp[i]);
while (cmdline[i] != ' ' && cmdline[i] != 0 && i < 1000) {
temp[i] = cmdline[i];
i++;
}
if (cmdline[i] == ' ') {
temp[i] = 0; i++; _argc++;
}
}
temp[i] = 0;
_argc++;
}
bios_save();
/* Call main procedure using standard C convention */
/* Remember you cannot call any console I/O function */
/* if you do not call bios_save() */
 
 
#ifdef __DUMP_MEM__
message("X/MEM : %u\n",mbi->mem_upper);
message("DOS/MEM : %u\n",mbi->mem_lower);
message("x_bios Size : %u\n",sizeof(X_BIOSCALL));
message("mbi Size : %u\n",sizeof(struct multiboot_info));
message("Cmdline : %s\n",mbi->cmdline);
message("Argc : %u\n",_argc);
message("Argv[0] : %s\n",_argv[0]);
message("Argv[1] : %s\n",_argv[1]);
message("Argv[2] : %s\n",_argv[2]);
message("Argv[3] : %s\n",_argv[3]);
#endif
MAIN(_argc,_argv);
bios_restore();
}
/shark/branches/xen/arch/x86/xinit.c
0,0 → 1,154
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Xlib initialization code */
 
#include <ll/i386/mem.h>
#include <ll/i386/cons.h>
#include <ll/i386/mb-info.h>
#include <ll/i386/error.h>
#include <ll/i386/pit.h>
#include <ll/i386/pic.h>
 
#include <ll/i386/tss-ctx.h>
#include <ll/i386/hw-arch.h>
 
FILE(X-Init);
 
extern DWORD ll_irq_table[256];
 
#ifdef __VIRCSW__
int activeInt = 0;
#endif
 
/* Assembly external routines! */
/* Setup the TR register of the 80386, to initialize context switch */
 
extern void init_TR(WORD v);
TSS main_tss;
 
/* Architecture definition */
LL_ARCH ll_arch;
 
/* The following stuff is in llCxA.Asm/S */
 
static void dummyfun(int i)
{
#if 0
if (i < 32) {
cputs("Unhandled Exc occured!!!\n");
} else {
cputs("Unhandled Int occured!!!\n");
}
#else
message("Unhandled Exc or Int %d occured!!!\n", i);
#endif
halt();
}
 
void l1_int_bind(int i, void *f)
{
ll_irq_table[i] = (DWORD)f;
}
 
void *l1_init(void)
{
register int i;
struct ll_cpuInfo cpuInfo;
extern unsigned char X86_apic;
extern unsigned char X86_tsc;
extern BYTE X86_fpu;
LIN_ADDR b;
for(i = 0; i < 256; i++) {
ll_irq_table[i] = (DWORD)dummyfun;
}
X86_get_CPU(&cpuInfo);
X86_get_FPU();
ll_arch.x86.arch = __LL_ARCH__;
ll_arch.x86.cpu = cpuInfo.X86_cpu;
ll_arch.x86.fpu = X86_fpu;
memcpy(&(ll_arch.x86.vendor), &(cpuInfo.X86_vendor_1), 12);
X86_apic = (cpuInfo.X86_StandardFeature>>9) & 1;
X86_tsc = (cpuInfo.X86_StandardFeature>>4) & 1;
/* TODO! Need to map featuresXXX & Signature onto ll_arch! */
/* TODO! Need to check for CPU bugs!! */
#ifdef __LL_DEBUG__
message("LL Architecture: %s\n", __LL_ARCH__);
message("CPU : %u\nFPU : %u\n", cpuInfo.X86_cpu, X86_fpu);
message("Signature : 0x%lx\nVendor: %s\n", cpuInfo.X86_signature,
ll_arch.x86.vendor);
message("Features #1: 0x%lx\n", cpuInfo.X86_IntelFeature_1);
message("Features #2: 0x%lx\n", cpuInfo.X86_IntelFeature_2);
message("Features #3: 0x%lx\n", cpuInfo.X86_StandardFeature);
message("Has APIC: %s\n", X86_apic);
message("Has TSC: %s\n", X86_tsc);
#endif /* __LL_DEBUG__ */
IDT_init();
 
/* Init coprocessor & assign it to main() */
/* OK... Now I know the sense of all this... :
We need a initial value for the FPU context (to be used for creating
new FPU contexts, as init value)...
... And we get it in this strange way!!!!
*/
reset_fpu();
init_fpu();
/* Init PIC controllers & unmask timer */
PIC_init();
/* Set the TR initial value */
b = (LIN_ADDR)(&main_tss);
GDT_place(MAIN_SEL, (DWORD)b, sizeof(TSS), FREE_TSS386, GRAN_16);
init_TR(MAIN_SEL);
return mbi_address();
}
 
 
void l1_end(void)
{
outp(0x21,0xFF);
outp(0xA1,0xFF);
/* Back to DOS settings */
PIC_end();
/* Reset the timer chip according DOS specification */
/* Mode: Binary/Mode 3/16 bit Time_const/Counter 0 */
#if 0
outp(0x43,0x36);
/* Time_const = 65536; write 0 in CTR */
outp(0x40,0);
outp(0x40,0);
#endif
pit_init(0, TMR_MD3, 0); /* Timer 0, Mode 3, Time constant 0 */
if(ll_arch.x86.cpu > 4) {
pit_init(1, TMR_MD2, 18);
} else {
pit_init(2, TMR_MD0, 0);
outp(0x61, 0); /* Stop channel 2 */
}
}
/shark/branches/xen/arch/x86/aspace.c
0,0 → 1,84
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* Routines to create address spaces and bind physical memory to them */
 
#include <ll/sys/ll/ll-data.h>
#include <ll/sys/ll/aspace.h>
 
FILE(Address-Space);
 
struct as AS_table[ASMax];
 
void as_init(void)
{
int i;
 
for (i = 0; i < ASMax; i++) {
AS_table[i].status = AS_FREE;
}
}
 
AS as_create(void)
{
int i;
 
i = 0;
while((i < ASMax) && (AS_table[i].status & AS_BUSY)) {
i++;
}
if (i == ASMax) {
return 0;
}
AS_table[i].status = AS_BUSY; /* Empty address space... */
AS_table[i].base = 0;
AS_table[i].limit= 0;
 
GDT_place(ASindex2sel(i), AS_table[i].base, AS_table[i].limit,
DATA_ACCESS, GRAN_32B);
GDT_place(ASindex2sel(i) + 8, AS_table[i].base, AS_table[i].limit,
CODE_ACCESS, GRAN_32B);
/* We also need a code segment... */
 
return ASindex2sel(i);
}
 
int as_bind(AS as, DWORD ph_addr, DWORD l_addr, DWORD size)
{
int i = ASsel2index(as);
 
/* We have not paging... So l_addr must be 0 */
if (l_addr != 0)
return -1;
 
AS_table[i].base = ph_addr;
AS_table[i].limit= size;
 
GDT_place(as, AS_table[i].base, AS_table[i].limit,
DATA_ACCESS, GRAN_32B);
GDT_place(as + 8, AS_table[i].base, AS_table[i].limit,
CODE_ACCESS, GRAN_32B);
/* We also need a code segment... */
 
return 1;
}
/shark/branches/xen/arch/x86/xsystab.c
0,0 → 1,92
/* Project: OSLib
* Description: The OS Construction Kit
* Date: 1.6.2000
* Idea by: Luca Abeni & Gerardo Lamastra
*
* OSLib is an SO project aimed at developing a common, easy-to-use
* low-level infrastructure for developing OS kernels and Embedded
* Applications; it partially derives from the HARTIK project but it
* currently is independently developed.
*
* OSLib is distributed under GPL License, and some of its code has
* been derived from the Linux kernel source; also some important
* ideas come from studying the DJGPP go32 extender.
*
* We acknowledge the Linux Community, Free Software Foundation,
* D.J. Delorie and all the other developers who believe in the
* freedom of software and ideas.
*
* For legalese, check out the included GPL license.
*/
 
/* These function provide access to hardware structutes GDT/IDT */
 
#include <ll/i386/cons.h>
#include <ll/i386/mem.h>
 
FILE(X-SysTab);
 
extern GATE IDT[256];
 
/* We usually need to set-up an interrupt handler; to do this we have */
/* to fill a GATE structure & copy it into the Interrupt Descriptor */
/* Table or IDT; its phisical address is given by IDT_base */
 
void IDT_place(BYTE num,void (*handler)(void))
{
DWORD offset = (DWORD)(handler);
IDT[num].sel = X_FLATCODE_SEL;
/* Set DPL = 3, to allow execution of the gate from any ring */
IDT[num].access = INT_GATE386 | 0x60;
IDT[num].dword_cnt = 0;
IDT[num].offset_lo = offset & 0xFFFF;
offset >>= 16;
IDT[num].offset_hi = offset & 0xFFFF;
}
 
/* Ok; the GDT is managed in the same way as the IDT */
/* When a descriptor is cleared using it will cause a SEGMENT FAULT */
/* to refer such descriptor */
 
void GDT_place(WORD sel,DWORD base,DWORD lim,BYTE acc,BYTE gran)
{
union gdt_entry x;
/* This is declared in [wc32/gnu]\x0.[asm/s] */
extern LIN_ADDR GDT_base;
/* DWORD offset = appl2linear(&x); */
x.d.base_lo = (base & 0x0000FFFF);
x.d.base_med = ((base & 0x00FF0000) >> 16);
x.d.base_hi = ((base & 0xFF000000) >> 24);
x.d.access = acc;
x.d.lim_lo = (lim & 0xFFFF);
x.d.gran = (gran | ((lim >> 16) & 0x0F) | 0x40);
memcpy(GDT_base+(sel & ~3),&x,sizeof(union gdt_entry));
}
 
/* This function is used to read & format the descriptor data */
/* Anyway is better to use the hw 386 instruction to modify */
/* a descriptor rather than reading,modifying & updating with */
/* this high level functions! */
 
DWORD GDT_read(WORD sel,DWORD *lim,BYTE *acc,BYTE *gran)
{
union gdt_entry x;
/* This is declared in [wc32/gnu]\x0.[asm/s] */
extern LIN_ADDR GDT_base;
/*DWORD offset = appl2linear(&x);*/
DWORD base;
memcpy(&x,GDT_base+sel,sizeof(union gdt_entry));
base = x.d.base_hi;
base <<= 8;
base |= x.d.base_med;
base <<= 16;
base |= x.d.base_lo;
if (lim != NULL) {
*lim = (x.d.gran & 0x0F);
*lim <<= 16;
*lim |= x.d.lim_lo;
}
if (acc != NULL) *acc = x.d.access;
if (gran != NULL) *gran = x.d.gran & 0xF0;
return(base);
}