Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1683 → Rev 1682

/shark/branches/xen/arch/x86/x1.c
File deleted
/shark/branches/xen/arch/x86/xinit.c
File deleted
/shark/branches/xen/arch/x86/aspace.c
File deleted
/shark/branches/xen/arch/x86/xsystab.c
File deleted
/shark/branches/xen/arch/x86/mem.s
File deleted
/shark/branches/xen/arch/x86/init.c
File deleted
/shark/branches/xen/arch/x86/idtinit.c
File deleted
/shark/branches/xen/arch/x86/x0.s
File deleted
/shark/branches/xen/arch/x86/intevt.c
File deleted
/shark/branches/xen/arch/x86/advtimer.c
File deleted
/shark/branches/xen/arch/x86/cxsw-2.c
File deleted
/shark/branches/xen/arch/x86/xdosf.c
File deleted
/shark/branches/xen/arch/x86/xinfo.c
File deleted
/shark/branches/xen/arch/x86/xbios.c
File deleted
/shark/branches/xen/arch/x86/timeint.s
File deleted
/shark/branches/xen/arch/x86/cpu2.s
File deleted
/shark/branches/xen/arch/x86/ccpu.c
File deleted
/shark/branches/xen/arch/x86/fpu.c
File deleted
/shark/branches/xen/arch/x86/xdosm.c
File deleted
/shark/branches/xen/arch/x86/irq.c
File deleted
/shark/branches/xen/arch/x86/Makefile
File deleted
/shark/branches/xen/arch/x86/xconv.c
File deleted
/shark/branches/xen/arch/x86/time.c
File deleted
/shark/branches/xen/arch/x86/exc.s
File deleted
/shark/branches/xen/arch/x86/vm86.c
File deleted
/shark/branches/xen/arch/x86/event1.c
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/farptr.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/x-bios.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/cons.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/tss-ctx.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-func.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/mb-hdr.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/linkage.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/advtimer.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/pic.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-instr.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/apic.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/mem.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/defs.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-io.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/sel.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-data.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/mb-info.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/64bit.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/hw-arch.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/error.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/x-dosmem.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/int.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/x-dos.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/i386/pit.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/ll.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/aspace.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/time.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-data.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/exc.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-func.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/event.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-mem.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/ll/ll-instr.h
File deleted
/shark/branches/xen/arch/x86/include/arch/ll/sys/types.h
File deleted
/shark/branches/xen/arch/x86/xsys0.s
File deleted
/shark/branches/xen/arch/x86/ctxsw.c
File deleted
/shark/branches/xen/arch/x86/ctx.s
File deleted
/shark/branches/xen/arch/x86/event.c
File deleted
/shark/branches/xen/arch/x86/estub.c
File deleted
/shark/branches/xen/arch/x86/abort.s
File deleted
/shark/branches/xen/oslib/kl/Makefile
0,0 → 1,13
targets:= \
mem.o \
cxsw-2.o \
init.o \
time.o \
aspace.o \
intevt.o \
event.o \
event1.o \
advtimer.o \
abort.o \
timeint.o
 
/shark/branches/xen/oslib/kl/mem.c
0,0 → 1,114
/* 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.
*/
 
/* Basic Memory Manager Functions:
A classic fixed partition allocator! */
 
#include <arch/i386/stdlib.h>
#include <arch/i386/string.h>
#include <ll/i386/mem.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
 
#include <ll/sys/ll/ll-mem.h>
 
FILE(Memory);
 
#define MAX_PARTITION 50 /* Max available partition */
 
static struct {
BYTE used;
#ifdef __WC16__
BYTE __huge *addr;
#else
BYTE *addr;
#endif
DWORD size;
} mem_table[MAX_PARTITION];
 
void ll_mem_init(void *base, DWORD size)
{
register int i;
mem_table[0].used = 1;
mem_table[0].addr = base;
mem_table[0].size = size;
for (i = 1; i < MAX_PARTITION; i++) mem_table[i].used = 0;
}
 
void *ll_alloc(DWORD s)
{
void *p = NULL;
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 != NULL) {
if (mem_table[i].size > s) {
mem_table[i].size -= s;
mem_table[i].addr += s;
}
else mem_table[i].used = FALSE;
}
return(p);
}
 
WORD ll_free(void *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 == (BYTE *)(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);
}
 
void ll_mem_dump(void)
{
register int i;
for (i = 0; i < MAX_PARTITION; i++) {
if (mem_table[i].used) message("Entry : [%d] Addr : %p Size : %ld\n",i,mem_table[i].addr,mem_table[i].size);
}
}
/shark/branches/xen/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/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/oslib/kl/todo.txt
0,0 → 1,43
1) Check save_fpu & c... It works, but the code is not very clean...
Clean it.
VERY LOW PRIORITY
 
2) Test the interrupt mechanism... DONE
Clean the act_int interface... (remove context? Like wake_up...)
At least, look at it...
MEDIUM PRIORITY
 
3) Time: clean up the time-exact code... Implement the Pentium timestamp
code...
MEDIUM PRIORITY
 
4) Interface:
init(...) look at the parameters
event_post(time, handler, parameters)
It returns a pointer to an event structure, allocated from
a static array... Why not passing the pointer to an event
structure (allocated by the user) as a parameter?
irq_bind(irq, handler, flags) OK.
context_create(task, stack, arg, killer, ctrl)
As for event_post... Why not passing a pointer to the
context as a parameter?
context_delete(c) OK.
get_time() Define something like TIME_HIGHRES, for the pentium
timestamp...
context_save() OK.
context_load(c) OK.
as_create()
OK?
as_bind(as, ph_addr, l_addr, size)
Interface is OK. It currently provides only half of the
functionalities (no paging)...
HIGH PRIORITY
 
5) More tests on ASs...
HIGH PRIORITY
 
6) X: more MultiBoot compliance...
MEDIUM PRIORITY
 
7) Provide a mechanism for system calls (invoked through interrupts?)
 
/shark/branches/xen/oslib/kl/oq.txt
0,0 → 1,5
1) Who calls the ll entries??? If only the OS code can do this,
the lowlevel doesn't need to protect the mutex regions (this is
done by the OS). If we want that everyone can call the lowlevel,
the lowlevel functions must protect the mutex regions by cli/sti
(warning... save_flags can be needed...)
/shark/branches/xen/oslib/kl/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/oslib/lib/Makefile
0,0 → 1,18
#
# Standard path
#
 
ifndef BASE
BASE = ..
BASEDOS = ..
endif
 
include $(BASE)/config.mk
.PHONY : all allclean
 
all:
 
allclean:
$(RM) lib*.a
$(RM) x0.o
/shark/branches/xen/oslib/lib/readme
0,0 → 1,0
This file is to force CVS to export the oslib/lib directory
/shark/branches/xen/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/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/oslib/docs/Makefile
0,0 → 1,19
all: man.ps
 
oslib.dvi: oslib.tex
latex oslib
latex oslib
 
man.ps: oslib.dvi
dvips oslib -o man.ps
 
clean :
rm -f *.log
rm -f *~
rm -f *.aux
rm -f *.dvi
rm -f man.ps
rm -f *.ind
rm -f *.idx
rm -f *.ilg
rm -f *.toc
/shark/branches/xen/oslib/docs/todo.txt
0,0 → 1,0
- Write at least the ``xlib'' section in oslib.tex...
/shark/branches/xen/oslib/docs/oslib.tex
0,0 → 1,992
\documentclass[a4paper]{report}
\usepackage{epsfig}
\usepackage{latexsym}
\usepackage[english]{babel}
\selectlanguage{english}
\textheight=8.4 truein
\textwidth=6.1 truein
\oddsidemargin=0.2 truein
 
\newenvironment{proof}
{\vspace{12pt} \noindent {\bf Proof.} \\
\noindent}{$\Box$ \vspace{12pt}}
 
\title{The OSLib Manual}
 
\author{Luca Abeni
\and
Gerardo Lamastra
}
 
\begin{document}
\setlength{\baselineskip}{1.5\baselineskip}
\maketitle
\begin{abstract}
This is the manual of OSLib, a collection of low level functions aimed
to help programmers in developing system software, ranging from small
programs for embedded systems to complex Operating System
kernels. Using OSLib, the system programmer can focus on the software
itself, without caring about the interaction with the hardware. In
this sense, OSLib is similar to the Flux OS Toolkit.
 
From another point of view, OSLib provides an ``easy'' access to the
hardware, without introducing any useless abstraction, and can be seen
as a generic support layer for any operating system service. In this
sense, it is similar to the MIT ExoKernel . Note that OSLib does not
force to use any particular OS structure, but can support any
conventional or innovative structure, such as the monolithic one, the
microkernel-based one, or the vertical structured one.
\end{abstract}
 
\chapter{Introduction}
The OSLib is a collection of routines and data structures developed to
help system programmers in implementing an OS or an application that
directly accesses the hardware. In this sense it is
similar to the Windows NT Hardware Abstraction Layer (HAL), the
$\mu$Choices NanoKernel, or the HARTIK Virtual Machine (VM) Layer. On
the other hand, the aim of the OSLib is not to abstract the
hardware resources (like the cited works do). In fact, hardware
resources abstraction can result in poor efficiency and flexibility,
as stated by Engler et others (ExoKernel). The OSLib code, instead of
abstracting hardware, provides a secure and easy access to it hiding
implementation details (for example, the PIC or PIT programming, or the
CPU tables management)
and leaving to the OS developers the hi-level and conceptual part of
the work.
%%%%% RIVEDERE!!!! CHIARIRE UN PO'
%%% Add reference to Flux and ExoKernels...
% These are the ideas: Flux is too complex (COM... What an orror!!!),
% ExoKernel exterminates too much abstractions :) ... And bound to a specific
% system structure (vertical structured system)!!!
 
\section{Library Structure}
OSLib is composed of some libraries, that can be compiled using
the standard GNU tools (gcc, GNU binutils and GNU make) either under
MSDOS or Linux (DJGPP for DOS and
gcc for Linux have been successfully tested; gcc for other Unix
systems or Cygnus gcc for Windows have not been tested yet, but
will probably work too). The resulting GNUCoff or ELF MultiBoot compliant
images can be loaded using a custom provided DOS eXtender (X) or
using the GNU Grand Unified Boot Loader (GRUB).
 
The code is organized in three parts: \begin{itemize}
\item the hardware support library ({\tt xlib}), used to access the PC
hardware;
\item a subset of the OS independent part of the standard C library
({\tt libc1});
\item the Kernel support library ({\tt kl}), that is the component to
use for writing OS code.
\end{itemize}
 
The hardware support library contains the boot code for starting up
the system when a MultiBoot compliant loader is used, the code to
access hardware structures such as the GDT, IDT, the interrupt
controller, the code to detect the CPU, and some data structures
containing informations about the system.
%%%% ALLUNGARE LA DESCRIZIONE, SPIEGARE BENE... FARE RIFERIMENTO AI FILE .h
 
The OS independent part of the C library provides all the functions
from libc that can be implemented without invoking system calls
(typically the string management functions, the memory
copy/move/compare, the math functions and similar). An important
exception to this rule is represented by the {\tt cprintf} function:
it is similar to the standard {\tt printf} function (with the
difference that {\tt cprintf} directly writes to the screen), and,
since it needs to access the video memory, it depends by the OS (in
particular, {\tt cprintf} depends on how the OS remaps the video
memory). In any case, since the OS code needs to output some
informations for debugging or other purposes, this function is
provided by {\tt libc1}. {\tt libc1} does not provide any input
function.
 
The Kernel support library provides: \begin{itemize}
\item the code for interrupt/exception handling;
\item the code for thread management (thread creation/deletion,
context switch...);
\item the code for address space management
\item the code for time management
\end{itemize}
 
\section{Compiling and Using}
The OSLib code is distributed as source code in a ZIP or tarball
archive. The tarball contains the source to be compiled in a Unix
system (only {\tt chr(10)} at the end of each line), while the ZIP
archive can be decompressed in MSDOS ({\tt chr(13)+chr(10)}) or Unix
source using the -a option of UNZIP.
 
In order to decompress the source tree, use {\tt tar -xvzf llxxx.tgz}
or {\tt unzip -La llxxx.zip}; this command will create the tree shown in
Figure \ref{fig:tree}.
 
\begin{figure}
%\begin{minipage}[t]{10cm}
\begin{tt}
\begin{tabbing}
oslib--\=------ll--\=------i386 \\
\> | \> | \\
\> | \> | \\
\> |---lib \> |----sys----ll \\
\> | \\
\> |---xlib \> \\
\> | \> \\
\> |---libc \> \\
\> | \> \\
\> |---libm \> \\
\> | \\
\> |---kl \\
\> | \\
\> |---examples \\
\> | \\
\> |---mk \\
\end{tabbing}
\end{tt}
%\end{minipage}
\caption{The OSLib source tree.}
\label{fig:tree}
\end{figure}
 
The {\tt ll} directory contains the header files with the
definitions of the OSLib structures and the prototypes for the OSLib calls.
It is organized in two subdirectories: the {\tt i386} directory,
containing the include files for the hardware support library, and
the {\tt sys/ll} directory, containing the headers for the OS support
library.
 
The {\tt lib} directory is the place where all the libraries
will be put once compiled. Depending on the
distribution, the {\tt lib} directory is in the archive or will be
created at compilation time by the {\tt make} command.
 
The {\tt xlib} directory contains the sources for the hardware
support library; the {\tt libm} directory is used to compile a
modified version of the FreeBSD math library provided with OSLib; the
{\tt libc} directory contains the sources for the minimal C library,
while the {\tt kl} directory is the place where the Kernel support library
source code resides.
 
The {\tt examples} directory contains some examples
showing how to use all the functionalities provided by OSLib.
 
The {\tt mk} library contains some configuration files, used to
compile the libraries in different host OSs: currently, the files
to compile under MDSOS (using DJGPP V1 \& V2) and the file to compile
under Linux are provided. Moreover, a file to compile the H4 (S.Ha.R.K.)
kernel is provided.
 
In order to compile the system, proceed as follows
\begin{itemize}
\item Configure the compiling system, installing the
correct configuration file: copy the correct {\tt mk/*.mk}
file in {\tt config.mk}
\item make all the libraries, from directories {\tt xlib},
{\tt libc}, {\tt libm}, and {\tt kl}:
\begin{minipage}[t]{10cm}
\begin{tt}
\begin{tabbing}
cd xlib \\
make install \\
cd .. \\
cd libc \\
make install \\
cd .. \\
cd libm \\
$\ldots$
\end{tabbing}
\end{tt}
\end{minipage}
\item now the libraries are installed, and you are ready to
use them. In order to test OSLib, you can compile
the programs in the {\tt examples} directory:
 
\begin{minipage}[t]{10cm}
\begin{tt}
\begin{tabbing}
cd examples \\
make
\end{tabbing}
\end{tt}
\end{minipage}
\end{itemize}
 
A program compiled using the OSLib code can be run using the DOS
eXtender, or using GRUB. In order to use the extender, boot MSDOS (or
a 16 bit DOS compatible OS, such as FreeDOS), then copy {\tt X.EXE}
in the path, and finally use it: {\tt X <program name>} (for example,
try {\tt X schedtest.xtn}). Once the program execution is terminated,
it will nicely return to DOS.
 
In order to run a program through GRUB, put it in a GRUB accessible
partition, then boot GRUB and enter the command prompt pressing
{\tt `c'}. Now, specify the compiled program as a kernel: assuming
that you want to run {\tt schedtest.xtn}, residing in the
{\tt /oslib/examples} directory on the first partition of your first
hard drive, you have to type {\tt kernel=(hd0,0)/oslib/examples/schedtest.xtn}.
Finally, you can run the program typing {\tt boot}. Once the program
finishes, the system is halted and you must reboot it.
 
The OSLib code can be used including the adequate headers
from the {\tt include} directory, and linking the libraries from the
{\tt lib} directory. The compiler and linker options are set in the
{\tt config.mk} file: look at the makefile in the {\tt examples} directory
to see how to use it. The {\tt examples} directory contains
some simple programs to be browsed in order to learn how to use OSLib.
 
\chapter{The libraries}
As said, the OSLib code and data structures are organized in various
libraries, in order to increase the modularity and simplify the
structure. A description of those libraries and of the header files
that have to be included in order to use OSLib follows.
 
\section{The header files}
The {\tt ll} directory contains the header files to be included for
using OSLib. In particular, the directory structure tries to reflect
the standard POSIX include directory. Hence, the include files of the
minimal C library use the POSIX names and are distributed in {\tt ll}
and {\tt ll/sys}.
 
The {\tt xlib} headers are in the {\tt ll/i386} directory; in particular,
they are:
\begin{itemize}
\item {\tt ll/i386/hw-data.h}: this header defines the basic data
types and constants, and has to be included in order to use
them
%do we need to cite all them?
\item {\tt ll/i386/hw-instr.h}: this header defines the instruction
needed to access hardware registers (or memory locations) as
inlined functions
\item {\tt ll/i386/hw-func.h}: this header has to be included in
order to use the functions that permits to directly access
hardware, such as {\tt halt()} and {\tt reboot()},
{\tt IDT\_place()}, {\tt GDT\_place()} and
{\tt GDT\_read()}, {\tt addr2linear()}, and the
{\tt ll\_context\_*()} functions. Moreover, it contains the
prototypes of {\tt x\_init()}, {\tt x\_end()},
{\tt x\_exc\_bind()}, and {\tt x\_irq\_bind()}
\item {\tt ll/i386/hw-arch.h}: this header has to be included for
using the CPU/FPU detection functions {\tt X86\_get\_CPU()},
{\tt X86\_get\_FPU()}, {\tt X86\_is386()},
{\tt X86\_isCyrix()}, and {\tt X86\_hasCPUID()}
\item {\tt ll/i386/hw-io.h}: this header defines the I/O
instructions as inline functions. It is included by
{\tt ll/i386/hw-instr.h} and must never be directly
included by user programs
\item {\tt ll/i386/tss-ctx.h}: defines some macros for translating
CONTEXTs in TSSs and vice-versa
\item {\tt ll/i386/sel.h}: defines some symbolic names for the
predefined selectors used by the {\tt xlib}
\item {\tt ll/i386/int.h}: defines some macros that simplify
writing interrupt or exception handlers
\item {\tt ll/i386/pit.h}: this header has to be included in order
to access the Programmable Interrupt Timer (PIT) through
{\tt pit\_init()}, {\tt pit\_setconstant()}, and
{\tt pit\_read()}
\item {\tt ll/i386/pic.h}: this header has to be included to
access the Programmable Interrupt Controller (PIC)
through {\tt PIC\_init()}, {\tt PIC\_end()},
{\tt irq\_mask()}, and {\tt irq\_unmask()}
\item {\tt ll/i386/linkage.h}: this header can be included by
ASM files to generate correct C naming independently from
the architecture/file format
\item {\tt ll/i386/defs.h}: this header defines some macros to be
used to start/end header and C files
\item {\tt ll/i386/farptr.h}: this header contains the far pointer
access from DJGPP
\item {\tt ll/i386/x-bios.h}: this header has to be included to
call real mode functions through {\tt X\_callBIOS()}, or
{\tt vm86\_init()} and {\tt vm86\_callBIOS()}, or to
directly communicate with the eXtender through
{\tt x\_bios\_address()} and {\tt X\_meminfo()}
\item {\tt ll/i386/x-dosmem.h}: this header has to be included in
order to manage real-mode (DOS) memory through
{\tt DOS\_mem\_init()}, {\tt DOS\_alloc()}, and
{\tt DOS\_free()}
\item {\tt ll/i386/x-dos.h}: this header has to be included in
order to access a FAT file system through dos (using the
X-BIOS calls) with {\tt DOS\_fopen()},
{\tt DOS\_fclose()}, {\tt DOS\_fread()},
{\tt DOS\_fwrite()}, and {\tt DOS\_error()}
\item {\tt ll/i386/mb-hdr.h}: this header can be included by ASM
files in order to easily generate a MultiBoot header
\item {\tt ll/i386/mb-info.h}: this header contains the definition
of the MultiBoot Information (MBI) structure.
\end{itemize}
 
%Minimal libc includes...
%\item {\tt ll/time.h}:
%\item {\tt ll/string.h}:
%\item {\tt ll/stdio.h}:
%\item {\tt ll/math.h}:
%\item {\tt ll/limits.h}:
%\item {\tt ll/errno.h}:
%\item {\tt ll/assert.h}:
%\item {\tt ll/unistd.h}:
%\item {\tt ll/stdlib.h}:
%\item {\tt ll/stdarg.h}:
%\item {\tt ll/ctype.h}:
%\item {\tt ll/sys/types.h}:
%\item {\tt ll/sys/cdef.h}:
%\item {\tt ll/i386/mem.h}:
%\item {\tt ll/i386/stdio.h}:
%\item {\tt ll/i386/cons.h}:
%\item {\tt ll/i386/float.h}:
%\item {\tt ll/i386/stdlib.h}:
%\item {\tt ll/i386/string.h}:
%\item {\tt ll/i386/error.h}:
%\item {\tt ll/i386/limits.h}:
 
The {\tt kl} headers are in the {\tt ll/sys/ll} directory; in particular,
they are:
\begin{itemize}
\item {\tt ll/sys/ll/ll-func.h}: this header has to be included for
using the {\tt ll\_context\_create()},
{\tt ll\_context\_setspace()}, and {\tt ll\_context\_delete()},
{\tt ll\_init()}, {\tt ll\_end()}, and {\tt ll\_abort()}
{\tt ll\_context\_save()}, {\tt ll\_context\_change()},
{\tt ll\_context\_load()}, {\tt ll\_context\_from()}, and
{\tt ll\_context\_to} functions
\item {\tt ll/sys/ll/event.h}: this header has to be included for
using the event related functions, that are
{\tt event\_init()}, {\tt event\_post()},
{\tt event\_delete()}, {\tt irq\_bind()}, and
{\tt ll\_ActiveInt()}
\item {\tt ll/sys/ll/time.h}: this header has to be included for
using the {\tt gettime()} function. Moreover, it provides
some macros for manipulating timespecs.
\item {\tt ll/sys/ll/event.h}: this header has to be included for
using Address Spaces. In particular, it provides prototypes
and data definitions for the {\tt as\_init()},
{\tt as\_create()}, and {\tt as\_bind()} functions.
\end{itemize}
 
\section{The Hardware Support Library}
The Hardware support library provides all the functions and data
structures needed to access the hardware. In particular, it provides
the code necessary to boot the OSLib application, to manage the CPU
and the PC hardware, and to switch to Real Mode calling BIOS functions.
 
The booting code and data permits to create MultiBoot compliant
executables and to interface the application with a MultiBoot compliant
boot loader.
 
The CPU handling code and data permits to identify the CPU type and to
manage the CPU tables (GDT and IDT), while the hardware managing code permits
to access some specific PC hardware (PIT and PIC).
 
First of all, some basic data types are defined (in {\tt ll/i386/hw-data.h}):
\begin{itemize}
\item {\tt DWORD}: a 32 bit positive number;
\item {\tt WORD}: a 16 bit positive number;
\item {\tt BYTE}: an 8 bit positive number.
\end{itemize}
For each of these types, a {\tt MAX\_*} constant exists.
 
Based on the basic types, some important structures are defined:
\begin{itemize}
\item {\tt struct gate}: the x86 gate structure;
\item {\tt struct descriptor}: an x86 segment descriptor;
\item {\tt union gdt\_entry}: an x86 GDT entry: can be a
gate or a descriptor;
\item {\tt struct tss}: an x86 Task descriptor.
\end{itemize}
All the constant that can be useful for initializing those structures are
also defined. See Intel manuals for some explanations.
 
These are the functions provided by the hardware library to manage
the CPU:
 
\noindent {\tt void int X86\_get\_CPU(struct ll\_cpuInfo *p)}
 
This function identifies the CPU present in the system and reports
its characteristics in the {\tt ll\_cpuInfo} structure whose pointer is
passed as an input. The {\tt ll\_cpuInfo} is described in Figure
\ref{fig:cpuinfo}.
\begin{figure}
%\begin{minipage}[t]{15cm}
\begin{tt}
\begin{tabbing}
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; \\
\}
\end{tabbing}
\end{tt}
%\end{minipage}
\label{fig:cpuinfo}
\caption{The cpuInfo structure.}
\end{figure}
 
Basically, {\tt X86\_get\_CPU()} checks if the CPU is a 386, a 486, or
better; in the last case, it uses the {\tt cpuid} instruction to obtain
more information, otherwise it will use some custom code to determine the
manufacturer. In particular, it is based on the following functions:
\noindent {\tt void int X86\_is386(void)} \\
\noindent {\tt void int X86\_isCyrix(void)} \\
\noindent {\tt void int X86\_hasCPUID(void)} \\
It is recommended to invoke them through {\tt X86\_get\_CPU()}, but
sometime it can be useful to call one of the previous functions directly.
 
Similar code exists for detecting and initializing the FPU, but it still
need some work.
%void X86_get_FPU(void); FIX THIS STORY!!! check_fpu() ???
 
Some other functions are provided to manage the most important CPU tables:
 
\noindent {\tt void
GDT\_place(WORD sel, DWORD base, DWORD lim, BYTE acc, BYTE gran)}
 
This function permits to insert a new entry in the GDT; {\tt sel}
is the selector (equal to the entry number multiplied by
{\em sizeof(struct gdt\_entry)}), {\tt base} and {\tt lim} are the
base and the limit of the segment described by the entry (and identified
by {\tt sel}), while {\tt acc} and {\tt gran} are the access and granularity
bytes. They can be set using the constants defined in
{\tt ll/i386/hw-data.h}.
 
\noindent {\tt DWORD GDT\_read(WORD sel, DWORD *lim, BYTE *acc, BYTE *gran)}
 
This function permits to read an entry from the GDT, returning the
base of the segment identified by the descriptor {\tt sel}. Moreover,
if {\tt lim}, {\tt acc}, and {\tt gran} are not null, the limit, the
access byte and the granularity of the segment are stored in
{\tt *lim}, {\tt *acc}, and {\tt *gran}.
 
{\tt LIN\_ADDR addr2linear(WORD selector, DWORD offset)}
 
This function can be used to translate an {\tt <selector>:<offset>} address
in a 32bit linear address. It uses {\tt GDT\_read} for obtaining the
base of the segment identified by {\tt selector}.
 
\noindent {\tt void IDT\_place(BYTE num,void (*handler)(void))}
 
This function permits to insert an entry in the IDT; {\tt num} is the
number of the interrupt, whereas {\tt handler} is a pointer to the
code that has to be specified as an handler for that interrupt.
 
%multiprogramming --> These are described in the KL...
%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);
%
%PIC Stuff... --> TODO: documentation...
%void PIC_init(void);
%void PIC_end(void);
%void irq_mask(WORD irqno);
%void irq_unmask(WORD irqno);
After these very low level functionalities, the hardware support library
provides some other facilities:
 
\noindent{\tt void *x\_init(void)}
 
This function initializes a minimal programming environment, defining a
standard handler for all the CPU exceptions and hardware interrupts (through
{\tt IDT\_place()}), identifying the CPU type, initializing the FPU, setting
up a TSS for executing the code, and initializing the PIC.
 
Moreover, it returns a pointer to the MultiBoot Information structure (see
Figure \ref{fig:MBI}).
 
\noindent{\tt x\_exc\_bind(int i, void (*f)(int n))}
\noindent{\tt x\_irq\_bind(int i, void (*f)(int n))}
 
These two functions permit to associate a handler to a CPU exception or to
a hardware interrupt. Note that the handler is a C function, using the C
conventions for passing the parameters. Since these two functions are based
on the programming environment initialized by {\tt x\_init()}, they can be
used only {\em after} that {\tt x\_init()} has been called.
 
\noindent{\tt void x\_end(void)}
Restores the hardware settings to the DOS standards: it must be called on
shutdown if the execution is expected to return to a 16bit OS.
 
Some other functions can be used for accessing the PIT:
 
\noindent{\tt int pit\_init(BYTE c, BYTE m, WORD tconst)}
 
This function initializes the PIT channel {\tt c} (with {\tt c = 0},
{\tt 1}, or {\tt 2}) in mode {\tt m}, with the initial value of the
counter equal to {\tt tconst}. Returns a value {\tt < 0} on error (if
the requested channel does not exist).
 
\noindent{int pit\_setconstant(BYTE c, WORD val)}
 
This function sets the PIT channel {\tt c}'s counter to {\tt val}.
Returns a value {\tt < 0} on error (if the requested channel does not
exist).
 
\noindent{\tt WORD pit\_read(BYTE channel)}
 
This function reads the value of the counter of {\tt channel}.
 
Other functions permit to call real mode interrupts, either returning to
real mode or using the VM86 mode. Some of these functions are used to
access a FAT file system using DOS (they works only if the application is
invoked through the eXtender). See {\tt ll/i386/x-*.h} for more details.
 
%BIOS
%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();
%int vm86_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s);
 
%DOS
%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);
 
%void DOS_dump_mem(void);
%void DOS_mem_init(void);
%LIN_ADDR DOS_alloc(DWORD s);
%int DOS_free(LIN_ADDR p,DWORD s);
 
Some other functions directly remap the corresponding ASM
instructions (these functions are implemented by the {\tt xlib}):
\begin{itemize}
\item {\tt cli()}
\item {\tt sti()}
\item {\tt halt()}
\item {\tt clts()}
\item {\tt BYTE inp(WORD port)}
\item {\tt WORD inw(WORD port)}
\item {\tt DWORD ind(WORD port)}
\item {\tt void outp(WORD port, BYTE data)}
\item {\tt void outw(WORD port, WORD data)}
\item {\tt void outd(WORD port, DWORD data)}
\end{itemize}
the following two functions can be used instead of {\tt cli()} and
{\tt sti()}:
\begin{itemize}
\item {\tt SYS\_FLAGS ll\_fsave(void)}: performs a {\tt cli}, and return the
previous value of the flags register;
\item {\tt void ll\_frestore(SYS\_FLAGS f)}: restores the flags register to
{\tt f}; can be used instead of a {\tt sti()}.
\end{itemize}
 
Moreover, the library provides some inline functions for reading and
writing some CPU registers' values:
\begin{itemize}
\item {\tt get\_CS()}
\item {\tt get\_DS()}
\item {\tt get\_FS()}
\item {\tt get\_SP()}
\item {\tt get\_BP()}
\item {\tt get\_TR()}: returns the Task Register value
\item {\tt set\_TR()}: sets the Task Register value
\item {\tt set\_LDTR()}: sets the LDT address
\end{itemize}
 
\section{The Kernel Support Library}
The Kernel support library allows an OS developer to write interrupt
handlers, binding them to hardware interrupts, to create threads and
perform context switches, to crate address spaces and assign them to
threads, and to manage the time.
 
Time management consists in reading time, and assigning execution
time to threads through an event-based model. Hence, time management
is performed using {\em events}: an event permits to execute some code
(the event handler) at a specified time (the event rising time).
When an event raises the event handler is called (with interrupt disabled).
 
Interrupts are managed in a similar way, allowing the programmer to
specify the event handler for a special event that will raise when the
hardware interrupt arrives.
 
Using the event mechanism it is easy to implement {\em temporal protection}
(enforcing that a thread will never require too much execution time), while
spatial protection is provided by OSLib through {\em Address Spaces}. An
address space is a very basic abstraction encapsulating user data and code.
Address Spaces are implemented using x86 segments: each Address Space is a
different segment. If the user code uses only the default data and code
selectors, the code running in an address space can not access other address
spaces. As a default, OSLib provides a ``flat'' address space, mapping
$1 \rightarrow 1$ all the physical memory.
 
Here is a list of the functions provided by {\tt kl}:
 
\noindent {\tt void *ll\_init(void)}
 
This library function is used to initialize the Kernel Library: it
detects the CPU, initializes the FPU, and sets the interrupt and
exception handlers to default values.
 
\begin{figure}
%\begin{minipage}[t]{15cm}
\begin{tt}
\begin{tabbing}
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; \\
/* \\
Gerardo: I need to add also the physical 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; \\
\}; \\
\end{tabbing}
\end{tt}
%\end{minipage}
\caption{The MultiBoot Information structure.}
\label{fig:MBI}
\end{figure}
As output, {\tt ll\_init} returns informations about the environment
through a modified version of the MultiBoot Information (MBI)
structure (the returned value is a pointer to such a structure). The
MultiBoot Info structure is defined as shown in Figure \ref{fig:MBI}.
 
Refer to the MultiBoot documentation for more informations about the
fields behaviour. The only difference with the standard MultiBoot
Info structure is that a new flag {\tt MB\_INFO\_USEGDT} in the
{\tt flags} field is provided for informing that the program has been
loaded through a DOS Extender, and two new fields are added. If the
{\tt MB\_INFO\_USEGDT} is set, the two new fields {\tt mem\_lowbase}
and {\tt mem\_upbase} indicates the low memory and high memory
starting addresses, otherwise the standard values (respectively
$0x00$ and $0x100000$) have to be assumed.
 
\noindent{\tt CONTEXT ll\_context\_create(void (*entrypoint)(void *p),
BYTE *stack, void *parm, void (*killer)(void),
WORD control)}
 
This library function is used to create a new thread, allocating a
CPU context for it. A thread is defined as an independent flow of
execution and is characterized by the register set values, a private
stack (used to initialize the {\tt SS} and {\tt ESP} registers), and
an address space in which it executes. The code executed by a thread
is defined by a function called {\em thread body} that takes as input
a void pointer (passed at thread creation time).
 
The {\tt entrypoint} parameter is a pointer to the thread body, the
{\tt stack} parameter is a pointer to a preallocated chunk of memory
to be used as a stack for the new thread, while the {\tt parm}
parameter is a void pointer passed as parameter to the thread body
when the thread is created. The {\tt killer} parameter is a pointer
to a function that will be called on thread correct termination (a
thread terminates correctly when the execution arrives to the end of
the body function). The {\tt control} parameters defines some control
flags associated to the thread.
 
The function allocates a free CPU context and initializes the
register values using the passed parameters. The {\tt EIP} register
is initialized to {\tt entrypoint}, and {\tt ESP} is initialized
to {\tt stack}, whereas {\tt DS}, {\tt GS}, and {\tt FS} are
initialized to the default data segment and {\tt CS} is initialized to
the default code segment. As explained introducing Address Spaces, the
default code and data segments remap one-to-one all the system memory
(``flat'' Address Space). All the other registers are initialized to
standard values.
 
The return value is the identifier of the initialized CPU context.
 
\noindent {\tt void ll\_context\_delete(CONTEXT c);}
 
This library function is used to free a CPU context when a thread is
terminated. The {\tt c} parameter is the identifier of the context to
be freed. Note that the stack memory has to be explicitly freed, since
{\tt ll\_context\_delete()} does not free it.
 
\noindent {\tt CONTEXT ll\_context\_save(void);}
 
This library function saves the CPU registers' values in the current
CPU context and returns its identifier. In other words, the context
associated to the thread executing when {\tt ll\_context\_save()} is
called is saved and its identifier is returned. It can be used to
implement context switches in OS primitives, as shown in the
following code:
 
\begin{minipage}[t]{15cm}
\begin{tt}
\begin{tabbing}
SYSCALL(mysyscall(...)) \=\ \\
\{ \\
\> CONTEXT oldContext, newContext; \\
\> $\ldots$ \\
\\
/* This must be the first primitive instruction */ \\
\> oldContext = ll\_context\_save(); \\
\> $\ldots$ \\
\> OS primitive code \\
\\
/* This must be the last primitive instruction */ \\
\> ll\_context\_load(newContext); \\
\}; \\
\end{tabbing}
\end{tt}
\end{minipage}
 
{\bf Warning:} if the virtual context switch mechanism is used, this
function cannot be used (use {\tt ll\_context\_from()} instead).
 
\noindent {\tt void ll\_context\_load(CONTEXT c);}
 
This library call is used to load a new CPU context in the CPU, for
performing context switches, as shown in the example above (see
{\tt ll\_context\_save()}). Note that {\tt ll\_context\_load()} must
be called {\bf at the end} of a system call (immediately before re-enabling
interrupts); if a system programmer needs to perform a context switch
with interrupt disabled (in an event handler or in the middle of a
system call), the {\em virtual context switch} mechanism have to be used.
When virtual context switch is used, the context switch function only
stores the new context ID in a temporary variable and performs the
real context switch only when interrupts are enabled (see {\tt
ll\_context\_from()} and {\tt ll\_context\_to())}.
 
\noindent {\tt CONTEXT ll\_context\_from(void);}
 
This library function is similar to {\tt ll\_context\_save()}, but
can be called when the virtual context switch mechanism is used. In
this case it returns the ID of the last context that have been
selected to be loaded in the CPU.
 
\noindent {\tt void ll\_context\_to(CONTEXT c);}
 
This library selects a thread to be dispatched: if interrupts are
disabled and the context switch cannot be performed immediately, the
real context switch will happen as soon as possible (when interrupts
will be re-enabled). This is the {\tt virtual context switch}
mechanism.
 
{\tt ll\_context\_to()} is similar to {\tt ll\_context\_load()}, but
uses the virtual context switch mechanism; if interrupts are enabled,
they behave in the same manner.
 
\noindent {\tt void ll\_end(void);}
 
This function can be used in the shutdown code: if the application
was started through the DOS Extender, {\tt ll\_end()} resets the PIT
(and the rest of the hardware) to the standard DOS settings and
prepares the system to return to MSDOS, otherwise it simply halts the
system.
 
\noindent {\tt void ll\_abort(int code);}
 
This functions acts as safety place to go when any error occurs and
the OS does not know which context is active. The function loads a
safe context (with a safe stack), displays an error identified by
the {\tt code} parameter, and exits the OS support code
(see also {\tt ll\_end}).
 
\noindent {\tt void event\_init(struct ll\_initparms *l)}
 
This function sets the time management services up, by initializing
the event queue and programming the Programmable Interval Timer (PIT)
in a proper way. The PIT can be programmed in two
different modes: the periodic mode and the one-shot mode. In periodic
mode, the PIT is programmed to generate a timer interrupt each {\tt tick}
of $T$ $\mu$seconds, specified by the user through the {\tt l}
parameter. In one shot mode, the PIT is dynamically programmed to
generate an interrupt only when it is necessary to raise a
programmed event. It is worth noting that the PIT mode only
influences the error with which an event raises, but is invisible to
the OS (the PIT mode can be changed simply changing the {\tt event\_init()}
parameter, without any modify to the OS code).
 
The function takes as input a pointer {\tt l} to a {\tt ll\_initparms}
structure defined as follows:
 
\begin{minipage}[t]{15cm}
\begin{tt}
\begin{tabbing}
struct ll\_initparms \= \{ \\
\> DWORD mode; \\
\> TIME tick; \\
\};
\end{tabbing}
\end{tt}
\end{minipage}
 
The {\tt mode} field indicates the PIT mode ({\tt LL\_PERIODIC} or
{\tt LL\_ONESHOT}), while the {\tt tick} field indicates the tick size
(for periodic mode only) in $\mu$seconds.
 
\noindent {\tt TIME gettime(int mode, struct timespec *val)}
 
This function can be used to read the current system time. The system
time can be read using different levels of precision (and different
levels of overhead): currently only the {\tt TIME\_PTICK} and
{\tt TIME\_EXACT} modes are implemented. The {\tt TIME\_PTICK} mode
works only if the system timer is programmed in periodic mode, and
returns the system time in ticks. It is characterized by a low
overhead (small execution time). The {\tt TIME\_EXACT} mode reads the
exact system time and returns it measured in $\mu$seconds.
 
The {\tt mode} parameter can be {\tt TIME\_PTICK} or {\tt TIME\_EXACT}
and specifies the time reading mode; the {\tt val} parameter can
point to a {\tt timespec} structure that will be filled
with the current time ( if {\tt val != NULL}) .
 
This function returns the read time in $\mu$seconds, or $0$ if the
reading fails.
 
\noindent {\tt int event\_post(struct timespec *time,
void (*handler)(void *p), void *par)}
 
This function is used to create a new event, selecting an handler to
be called at the specified time passing an user provided parameter to
it. The {\tt handler} parameter specifies the event handler (the
function to be called when the event will raise), the {\tt time}
parameter indicates the time at which the event will raise, while
{\tt par} is a void pointer that will be passed as parameter to
the event handler.
 
The function returns the identifier of the created event, or -1 if an
error occurs (it can be due to the lack of free event
descriptors, or to some other internal error). The event identifier
is used to refer the event for modifying or deleting it (see
{\tt event\_delete()}).
 
The OS support code programs the interrupt controller in a periodic
or one-shot mode (see {\tt event\_init()}) so that an interrupt will be
generated near to time {\tt time} to call the event handler. The
event handler is called as a response to the timer interrupt, with
interrupts disabled, hence it {\bf must} execute for not too much time
(otherwise, interrupts will be left disabled for a long time). The
timer mode can affect the error with which the event handler is
called, but the code must be independent from the timer mode.
% CHIARIRE IL CONCETTO!!!!
% -- GLI EVENT HANDLER NON DEVONO PRENDERE TEMPO!!!
% -- IL MODO DI FUNZIONAMENTO DEL TIMER E' ``TRASPARENTE''!!!
 
\noindent {\tt int event\_delete(int index)}
 
This library function is used to delete a posted event, identified by
the {\tt index} parameter. It returns 1 in case of success, -1 in
case of failure.
 
\noindent {\tt int irq\_bind(int irq, void (*handler)(void *p), DWORD flags)}
 
This function can be used to associate an handler to an hardware
interrupt; each interrupt is converted by the support code in an
event, so the interrupt handler is identical to an event handler. The
function checks if the requested interrupt is free, and in this case
allocates it and assigns the handler to it. If the interrupt is
already allocated (is not free), that is, a handler has been already
associated to it, {\tt irq\_bind} returns an error and does nothing.
 
The {\tt irq} parameter specifies the interrupt number, while {\tt
handler} is a pointer to the interrupt event handler, and the {\tt
flags} parameter defines some flags associated to the interrupt. In
particular, the {\tt FORCE} flag can be used to set a handler for an
already allocated interrupt, and the {\tt PREEMPTABLE} flag specifies
that the handler can be called with interrupts enabled (interruptible
handler).
 
FLAGS: \begin{itemize}
\item the {\tt PREEMPTABLE} flag permits to specify
that the handler can be called with
interrupts enabled (interruptible handler).
\item the {\tt FORCE} flag can be used to set a handler for
an already allocated interrupt.
\end{itemize}
 
Interruptible handlers are useful to enhance system responsiveness,
reducing the time in which interrupts are disabled and allowing to
develop a preemptable OS. On the other hand, they must be used with
caution, since mutual exclusion is not guaranteed in an interruptible
handler.
 
The {\tt FORCE} flag can be useful for removing an interrupt handler
(use this flag with the {\tt handler} parameter set to {\tt NULL}.
 
\noindent {\tt int ll\_ActiveInt(void)}
 
This function returns the number of pending interrupts or event handlers.
 
\noindent {\tt void as\_init(void)}
 
This function initializes the Address Space management code. It must be
called before using Address Spaces ({\tt as\_create()} or
{\tt as\_bind()}).
 
\noindent {\tt AS as\_create(void)}
 
This library function can be used to create a new Address Space: it
searches for a free Address Space descriptor and initializes it to an
empty Address Space returning its identifier. The return value is the
created Address Space ID in case of success, or 0 in case of failure.
 
\noindent {\tt int as\_bind(AS as, DWORD ph\_addr, DWORD l\_addr, DWORD size)}
 
This library function binds a chunk of physical memory to an Address
Space. The {\tt as} parameter is the Address Space identifier,
{\tt ph\_addr} is the physical chunk start address, {\tt l\_addr} is the
logical address in the {\tt as} address space where the memory chunk
has to be mapped, and {\tt size} indicate the size of the memory
chunk expressed in bytes.
 
{\bf Warning:} currently, this function has been only partially implemented.
In particular, since paging is not enabled, a single chunk of memory can be
bound to an Address Space, starting from logical address 0.
 
\noindent {\tt void ll\_context\_setspace(CONTEXT c, AS as)}
 
This library functions changes the Address Space in which a thread runs.
Basically, {ll\_context\_setspace()} sets all the context {\tt c} segment
registers to the segment of the {\tt as} address space.
This function can be useful to create a new task: \begin{enumerate}
\item Create a new context
\item Create a new Address Space
\item Set the context Address Space to the created one...
\end{enumerate}
{\em We need an example...} Look at {\tt examples/aspacedemo.c}.
 
\section{Miscellaneous}
Two functions {\tt void *ll\_alloc(DWORD size)} and
{\tt void ll\_free(void *base, DWORD size)} are provided to
allocate and free physical memory. They are provided only for
convenience, but they should not be used: the memory allocator
should be implemented in an upper level, using the informations
returned by {\tt ll\_init()}.
 
Two functions {\tt char *ll\_context\_sprintf(char *str, CONTEXT c)} and
{\tt void dump\_TSS(WORD sel)} are provided for debugging purpose.
 
\end{document}
/shark/branches/xen/oslib/docs/ref.txt
0,0 → 1,142
cons.h:
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 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)));
 
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)));
 
error.h:
error(msg)
message
 
hw-func.h:
void halt(void);
void cold_reboot(void); ???
void warm_reboot(void); ???
void reboot(int mode); ???
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);
void *x_init(void);
void x_end(void);
void x_exc_bind(int i, void (*f)(int n));
void x_irq_bind(int i, void (*f)(int n));
/* Do something for these, please!!! */
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);
hw-instr.h:
INLINE_OP WORD get_CS(void)
INLINE_OP WORD get_DS(void)
INLINE_OP WORD get_FS(void)
INLINE_OP DWORD get_SP(void)
INLINE_OP DWORD get_BP(void)
INLINE_OP WORD get_TR(void)
INLINE_OP void set_TR(WORD n)
INLINE_OP void set_LDTR(WORD addr)
INLINE_OP void clts(void)
INLINE_OP void hlt(void)
INLINE_OP void sti(void)
INLINE_OP void cli(void)
INLINE_OP SYS_FLAGS ll_fsave(void)
INLINE_OP void ll_frestore(SYS_FLAGS f)
INLINE_OP void save_fpu(TSS *t)
INLINE_OP void restore_fpu(TSS *t)
INLINE_OP void smartsave_fpu(TSS *t)
INLINE_OP void reset_fpu(void)
INLINE_OP int check_fpu(void)
INLINE_OP void init_fpu(void)
extern __inline__ void LL_FPU_save
void LL_FPU_restore(void)
inp, outp, inpw, outpw, inpd & outpd
mem.h:
mem* functions
pic.h:
void PIC_init(void);
void PIC_end(void);
void irq_mask(WORD irqno);
void irq_unmask(WORD irqno);
pit.h:
INLINE_OP int pit_init(BYTE channel, BYTE mode, WORD tconst)
INLINE_OP int pit_setconstant(BYTE channel, DWORD c)
INLINE_OP WORD pit_read(BYTE channel)
ptspec structs & funcs...
stdio.h:
int vsprintf(char *buf,char *fmt,va_list parms);
int sprintf(char *buf,char *fmt,...) __attribute__((__format__(printf,2,3)));
int vsscanf(char *buf,char *fmt,va_list parms);
int sscanf(char *buf,char *fmt,...) __attribute__((__format__(scanf,2,3)));
(RIMUOVERE LL_PRINTF!!!)
stdlib.h:
long strtoi(char *s,int base,char **scan_end);
unsigned long strtou(char *s,int base,char **scan_end);
double strtod(char *s,char **scan_end);
long strtol(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *nptr, char **endptr, int base);
 
 
unsigned ecvt(double v,char *buffer,int width,int prec,int flag);
unsigned fcvt(double v,char *buffer,int width,int prec,int flag);
unsigned gcvt(double v,char *buffer,int width,int prec,int flag);
unsigned dcvt(long v,char *buffer,int base,int width,int flag);
unsigned ucvt(unsigned long v,char *buffer,int base,int width,int flag);`
#define atof(s) strtod(s, NULL);
#define atoi(s) strtoi(s, 10, NULL);
#define atou(s) strtou(s, 10, NULL);
#define atol(s) strtol(s, 10, NULL);
void srand(long int seed);
long int rand(void);
unsigned abs(int x);
void exit(int code);
string.h:
char *strcpy(char *dst,const char *src);
char *strncpy(char *dst,const char *src,int n);
int strcmp(const char *s1,const char *s2);
int strncmp(const char *s1,const char *s2,int n);
int strlen(const char *s);
char *strscn(char *s,char *pattern);
char *strchr(char *s,int c);
char *strupr(char *s);
char *strlwr(char *s);
char *strcat(char *dst,char *src);
tss-ctx.h:
#define TSSMax 155
#define TSSMain (TSSMax-1)
#define TSSBase 0x100
#define TSSsel2index(sel) ((sel-TSSBase)/8)
#define TSSindex2sel(i) (TSSBase + i*8)
x-bios.h:
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();
int vm86_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s);
x-dos.h:
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);
x-dosmem.h:
void DOS_dump_mem(void);
void DOS_mem_init(void);
LIN_ADDR DOS_alloc(DWORD s);
int DOS_free(LIN_ADDR p,DWORD s);
/shark/branches/xen/oslib/libcons/Makefile
0,0 → 1,53
# Standard library for X/COFF applications
# Makefile for GNU MAKE & GCC 2.8.0
 
ifndef BASE
BASE = ..
BASEDOS = ..
endif
 
include $(BASE)/config.mk
 
#C_OPT += -DPROFILE
#ASM_OPT += -DPROFILE
 
OBJS = cons1.o \
cons2.o \
cprintf.o \
message.o
 
.PHONY : clean allclean info install
 
info :
@echo "OSLib Makefile"
@echo "Chose: all, install, clean"
all : libcons.a
 
install : libcons.a $(LIB_DIR)
$(CP) libcons.a $(LIB_DIR)
 
$(LIB_DIR) :
$(MKDIR) $(LIB_DIR)
 
clean :
$(RM) *.o
$(RM) *.err
$(RM) libcons.a
 
allclean :
echo # XTN Library dependencies > deps
$(RM) $(LIB_PATH)libcons.a
 
deps: $(OBJS:.o=.c)
$(CC) $(C_OPT) -M $(OBJS:.o=.c) > deps
 
#
# The library!!
#
libcons.a : $(OBJS)
$(AR) rs libcons.a $(OBJS)
 
ifeq (deps,$(wildcard deps))
include deps
endif
/shark/branches/xen/oslib/libcons/cons1.c
0,0 → 1,201
/* 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 */
 
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>
/* #include <xsys.h>*/
#include <arch/i386/string.h>
#include <arch/i386/stdlib.h>
#include <arch/i386/stdio.h>
#include <arch/stdarg.h>
 
FILE(Cons1);
/* CGA compatible registers value */
 
#define CURSOR_POS_MSB 0x0E
#define CURSOR_POS_LSB 0x0F
#define CURSOR_START 0x0A
#define CURSOR_END 0x0B
 
/* CGA compatible registers */
 
#define CGA_INDEX_REG 0x3D4
#define CGA_DATA_REG 0x3D5
 
/* Standard tab size */
 
#define TAB_SIZE 8
 
/* Store bios settings */
 
static unsigned char bios_start,bios_end;
BYTE bios_x, bios_y, bios_attr;
 
/* Access directly to video & BIOS memory through linear addressing */
 
/* Active video page-buffer */
#define PAGE_SIZE 2048
 
int active_page = 0;
int visual_page = 0;
 
void bios_save(void)
{
/* This function must be called to init CONSole output */
#if 1
bios_attr = lmempeekb((LIN_ADDR)0xB8000 + 159);
bios_x = lmempeekb((LIN_ADDR)0x00450);
bios_y = lmempeekb((LIN_ADDR)0x00451);
bios_end = lmempeekb((LIN_ADDR)0x00460);
bios_start = lmempeekb((LIN_ADDR)0x00461);
active_page = visual_page = 0;
#else
LIN_ADDR p;
 
p = (LIN_ADDR)(0xB8000 + 159);
bios_attr = *p;
p = (LIN_ADDR)0x00450;
bios_x = *p;
p = (LIN_ADDR)0x00451;
bios_y = *p;
p = (LIN_ADDR)0x00460;
bios_end = *p;
p = (LIN_ADDR)0x00461;
bios_start = *p;
active_page = visual_page = 0;
#endif
}
 
void getcursorxy(int *x, int *y)
{
*x = bios_x;
*y = bios_y;
}
 
int get_attr(void)
{
return bios_attr;
}
 
void cursor(int start,int end)
{
/* Same thing as above; Set cursor scan line */
outp(CGA_INDEX_REG, CURSOR_START);
outp(CGA_DATA_REG, start);
outp(CGA_INDEX_REG, CURSOR_END);
outp(CGA_DATA_REG, end);
}
 
void bios_restore(void)
{
lmempokeb((LIN_ADDR)0x00450,bios_x);
lmempokeb((LIN_ADDR)0x00451,bios_y);
place(bios_x,bios_y);
cursor(bios_start, bios_end);
}
 
void place(int x,int y)
{
unsigned short cursor_word = x + y*80 + active_page*PAGE_SIZE;
/* Set cursor position */
/* CGA is programmed writing first the Index register */
/* to specify what internal register we are accessing */
/* Then we load the Data register with the wanted val */
outp(CGA_INDEX_REG,CURSOR_POS_LSB);
outp(CGA_DATA_REG,cursor_word & 0xFF);
outp(CGA_INDEX_REG,CURSOR_POS_MSB);
outp(CGA_DATA_REG,(cursor_word >> 8) & 0xFF);
/* Adjust temporary cursor bios position */
bios_x = x;
bios_y = y;
}
 
 
void _scroll(char attr,int x1,int y1,int x2,int y2)
{
register int x,y;
WORD xattr = (((WORD)attr) << 8) + ' ',w;
LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
for (y = y1+1; y <= y2; y++)
for (x = x1; x <= x2; x++) {
w = lmempeekw((LIN_ADDR)(v + 2*(y*80+x)));
lmempokew((LIN_ADDR)(v + 2*((y-1)*80+x)),w);
}
for (x = x1; x <= x2; x++)
lmempokew((LIN_ADDR)(v + 2*((y-1)*80+x)),xattr);
}
 
void scroll(void)
{
_scroll(bios_attr,0,0,79,24);
}
 
void cputc(char c)
{
static unsigned short scan_x,x,y;
LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
x = bios_x;
y = bios_y;
switch (c) {
case '\t' : x += 8;
if (x >= 80) {
x = 0;
if (y == 24) scroll();
else y++;
} else {
scan_x = 0;
while ((scan_x+8) < x) scan_x += 8;
x = scan_x;
}
break;
case '\n' : x = 0;
if (y == 24) scroll();
else y++;
break;
case '\b' : x--;
lmempokeb((LIN_ADDR)(v + 2*(x + y*80)),' ');
x++;
break;
default : lmempokeb((LIN_ADDR)(v + 2*(x + y*80)),c);
x++;
if (x > 80) {
x = 0;
if (y == 24) scroll();
else y++;
}
}
place(x,y);
}
 
void cputs(char *s)
{
char c;
while (*s != '\0') {
c = *s++;
cputc(c);
}
}
 
 
/shark/branches/xen/oslib/libcons/cons2.c
0,0 → 1,130
/* 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 - part 2 */
 
#include <arch/i386/string.h>
#include <arch/i386/stdlib.h>
#include <arch/i386/stdio.h>
#include <arch/stdarg.h>
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>
/* #include <xsys.h>*/
 
FILE(Cons2);
 
#define PAGE_SIZE 2048
#define PAGE_MAX 8
 
/* CGA compatible registers */
 
#define CGA_INDEX_REG 0x3D4
#define CGA_DATA_REG 0x3D5
 
#define VIDEO_ADDRESS_MSB 0x0C
#define VIDEO_ADDRESS_LSB 0x0D
 
 
extern int active_page;
extern int visual_page;
static int curs_x[PAGE_MAX];
static int curs_y[PAGE_MAX];
extern BYTE bios_x, bios_y, bios_attr;
 
void set_visual_page(int page)
{
unsigned short page_offset;
page_offset = page * PAGE_SIZE;
visual_page = page;
outp(CGA_INDEX_REG, VIDEO_ADDRESS_LSB);
outp(CGA_DATA_REG, page_offset & 0xFF);
outp(CGA_INDEX_REG, VIDEO_ADDRESS_MSB);
outp(CGA_DATA_REG, (page_offset >> 8) & 0xFF);
}
 
void set_active_page(int page)
{
curs_x[active_page] = bios_x;
curs_y[active_page] = bios_y;
bios_x = curs_x[page];
bios_y = curs_y[page];
active_page = page;
}
 
int get_visual_page(void)
{
return(visual_page);
}
 
int get_active_page(void)
{
return(active_page);
}
 
void _clear(char c,char attr,int x1,int y1,int x2,int y2)
{
register int i,j;
WORD w = attr;
w <<= 8; w |= c;
for (i = x1; i <= x2; i++)
for (j = y1; j <= y2; j++)
lmempokew((LIN_ADDR)(0xB8000 + 2*i+160*j + 2*active_page*PAGE_SIZE),w);
place(x1,y1);
bios_y = y1;
bios_x = x1;
}
 
void clear()
{
_clear(' ',bios_attr,0,0,79,24);
}
 
void puts_xy(int x,int y,char attr,char *s)
{
LIN_ADDR v = (LIN_ADDR)(0xB8000 + (80*y+x)*2 + active_page*(2*PAGE_SIZE));
while (*s != 0) {
/* REMEMBER! This is a macro! v++ is out to prevent side-effects */
lmempokeb(v,*s); s++; v++;
lmempokeb(v,attr); v++;
}
}
 
void putc_xy(int x,int y,char attr,char c)
{
LIN_ADDR v = (LIN_ADDR)(0xB8000 + (80*y+x)*2 + active_page*(2*PAGE_SIZE));
/* REMEMBER! This is a macro! v++ is out to prevent side-effects */
lmempokeb(v,c); v++;
lmempokeb(v,attr);
}
 
char getc_xy(int x,int y,char *attr,char *c)
{
LIN_ADDR v = (LIN_ADDR)(0xB8000 + (80*y+x)*2 + active_page*(2*PAGE_SIZE));
char r;
r = lmempeekb(v); v++;
if (c != NULL) *c = r;
r = lmempeekb(v);
if (attr != NULL) *attr = r;
return(r);
}
/shark/branches/xen/oslib/libcons/message.c
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.
*/
 
/* Console output functions */
 
#include <arch/i386/string.h>
#include <arch/i386/stdlib.h>
#include <arch/i386/stdio.h>
#include <arch/stdarg.h>
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>
 
FILE(message);
 
int message(char *fmt,...)
{
static char cbuf[500];
va_list parms;
int result;
 
va_start(parms,fmt);
result = vksprintf(cbuf,fmt,parms);
va_end(parms);
cputs(cbuf);
return(result);
}
/shark/branches/xen/oslib/libcons/cprintf.c
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.
*/
 
/* Console output functions */
 
#include <arch/i386/string.h>
#include <arch/i386/stdlib.h>
#include <arch/i386/stdio.h>
#include <arch/stdarg.h>
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>
 
FILE(cprintf);
 
int cprintf(char *fmt,...)
{
static char cbuf[500];
va_list parms;
int result;
va_start(parms,fmt);
result = vsprintf(cbuf,fmt,parms);
va_end(parms);
cputs(cbuf);
return(result);
}
 
int printf_xy(int x,int y,char attr,char *fmt,...)
{
char cbuf[200];
va_list parms;
int result;
 
va_start(parms,fmt);
result = vsprintf(cbuf,fmt,parms);
va_end(parms);
puts_xy(x,y,attr,cbuf);
return(result);
}
/shark/branches/xen/oslib/Makefile
0,0 → 1,3
targets:= xlib/ kl/
 
exported-cppflags:= -I$(srctree)/libc/arch/$(ARCH)/include
/shark/branches/xen/oslib/examples/Makefile
0,0 → 1,35
# Standard library for X/COFF applications
# Makefile for GNU MAKE & GCC 2.8.0
 
ifndef BASE
BASE = ..
BASEDOS = ..
endif
 
include $(BASE)/config.mk
 
all: mbdemo.xtn timetest.xtn eventdem.xtn vmdemo.xtn \
ctxswdem.xtn scheddem.xtn cpudemo.xtn biosdemo.xtn \
asdemo.xtn kerndem.xtn
 
%.ftp: %.xtn
ncftpput -u ll -p example thorin . $<
%.flp: %.xtn
mcopy $< a:
 
clean :
$(RM) *.o
$(RM) *.err
$(RM) *.xtn
 
#
# Demo
#
 
kerndem.xtn: syscalls.o $(LIB_PATH)/libhc.a $(LIB_PATH)/libhm.a $(LIB_PATH)/libhx.a $(LIB_PATH)/libkl.a
$(LD) $(LINK_OPT) $(LIB_PATH)x0.o syscalls.o --start-group -lhc -lhm -lhx -lkl -lcons --end-group -o $@
 
 
%.xtn : %.o $(LIB_PATH)/libhc.a $(LIB_PATH)/libhm.a $(LIB_PATH)/libhx.a $(LIB_PATH)/libkl.a
$(LD) $(LINK_OPT) $(LIB_PATH)x0.o $< --start-group -lhc -lhm -lhx -lkl -lcons --end-group -o $@
# $(LD) $(LINK_OPT) $(LIB_PATH)x0.o $< --start-group -lhc -lhx -lkl --end-group -o $@
/shark/branches/xen/oslib/examples/ctxswdem.c
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.
*/
 
/* Context Switch Demo */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/tss-ctx.h>
#include <ll/i386/error.h>
#include <ll/sys/ll/ll-instr.h>
#include <ll/sys/ll/ll-func.h>
 
#define STACK_SIZE 4096U /* Stack size in bytes */
#define USE_FPU 0x0001
 
WORD th1, thm;
 
#define T 1000
 
#if 1
#define TO ll_context_to
#define FROM ll_context_from
#else
#define TO ll_context_load
#define FROM ll_context_save
#endif
 
/* For stack allocation checking */
BYTE stack1[STACK_SIZE];
BYTE stack2[STACK_SIZE];
 
void thread1(void *px)
{
message("Thread 1 running\n");
message("Switching to main thread\n");
TO(thm);
message("Another time thread 1\n");
message("Back to main\n");
TO(thm);
message("And now, finishing thread 1\n");
}
 
void killer(void)
{
cli();
message("Killer!!!\n");
TO(thm);
}
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
void *mbi;
 
sp1 = get_SP();
cli();
 
mbi = ll_init();
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
sti();
message("LowLevel started...\n");
th1 = ll_context_create(thread1, &stack1[STACK_SIZE], NULL,killer, 0);
thm = FROM();
message("Thread 1 created\n");
message("Switching to it...\n");
TO(th1);
message("Returned to main\n");
message("And now, to thread 1 again!!!\n");
TO(th1);
message("Main another time...\n");
TO(th1);
message("OK, now I finish...\n");
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/timetest.c
0,0 → 1,88
/* 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.
*/
 
/* gettime() test file */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/error.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/event.h>
#include <ll/sys/ll/time.h>
 
DWORD smain;
DWORD sp;
 
int sys_abort(int code)
{
cli();
ll_abort(code);
/* Never reach this! Just to shut up compiler warning... */
/* In the general case, a sys_abort can resume... */
return(1);
}
 
int main (int argc, char *argv[])
{
DWORD t, t1, oldt, secs;
struct ll_initparms parms;
struct timespec ts;
cli();
message("Init Stack : %lu\n", get_SP());
parms.mode = LL_PERIODIC;
parms.tick = 1000;
ll_init();
event_init(&parms); /* It's here, but must be changed...*/
smain = get_SP();
message("Smain --> %lx\n",smain);
sti();
secs = 0; oldt = 0;
while (secs <= 120) {
cli();
t1 = ll_gettime(TIME_NEW, &ts);
t = ll_gettime(TIME_EXACT, NULL);
sti();
if (t < oldt) {
error("Time goes back??\n");
message("ARGGGGG! %lu %lu\n", t, oldt);
ll_abort(100);
}
oldt = t;
if ((t / 1000000) > secs) {
secs++;
message("%lu %lu %lu/%lu\n",
TIMESPEC2USEC(&ts), secs, t, t1);
}
}
message("\n DONE: Secs = %lu\n", secs);
cli();
ll_end();
sp = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ",sp);
message("Main stack : %lx\n",smain);
message("Check if same : %s\n",smain == sp ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/biosdemo.c
0,0 → 1,191
/* 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.
*/
 
/* VM86 demo: tries to call BIOS services in vm86 mode... */
 
#include <ll/i386/hw-func.h>
#include <ll/i386/tss-ctx.h>
#include <ll/i386/x-bios.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <arch/stdlib.h>
 
#define T 1000
#if 1
#define WAIT() for (w = 0; w < 0xFFFFFFFF; w++)
#else
#define WAIT() for (w = 0; w < 0xFFFFF; w++)
#endif
static unsigned long int w;
 
#define __VM86__
 
#ifdef __VM86__
 
//void emulate(void)
void emulate(DWORD intnum, struct registers r)
{
TSS *vm86_tss;
DWORD *bos;
DWORD isr_cs, isr_eip;
WORD *old_esp;
DWORD *IRQTable_entry;
CONTEXT c = get_TR();
vm86_tss = vm86_get_tss();
bos = (DWORD *)vm86_tss->esp0;
if (c == X_VM86_TSS) {
/*
message("Entering ESP: %lx (= 0x%lx?)\n",
(DWORD)(tos + 9), vm86_tss->esp0);
message("Old EIP: 0x%lx 0x%lx\n", *(tos + 9), *(bos - 9));
message("Old CS: 0x%x 0x%x\n", (WORD)(*(tos + 10)), (WORD)*(bos - 8));
message("Old EFlags: 0x%lx 0x%lx\n", *(tos + 11), *(bos - 7));
message("Old ESP: 0x%lx 0x%lx\n", *(tos + 12), *(bos - 6));
message("Emulate, please!!!\n");
*/
old_esp = (WORD *)(*(bos - 6) + (*(bos - 5) << 4));
// *(old_esp - 1) = /*(WORD)(*(bos - 7))*/ CPU_FLAG_VM | CPU_FLAG_IOPL;
r.flags = CPU_FLAG_VM | CPU_FLAG_IOPL;
*(old_esp - 2) = (WORD)(*(bos - 8));
*(old_esp - 3) = (WORD)(*(bos - 9));
*(bos - 6) -= 6;
/* We are emulating INT 0x6d */
IRQTable_entry = (void *)(0L);
isr_cs= ((IRQTable_entry[0x6d]) & 0xFFFF0000) >> 16;
isr_eip = ((IRQTable_entry[0x6d]) & 0x0000FFFF);
/*
message("I have to call 0x%lx:0x%lx\n", isr_cs, isr_eip);
*/
*(bos - 8) = isr_cs;
*(bos - 9) = isr_eip;
}
}
 
void vm86BIOSDemo(void)
{
X_REGS16 ir,or;
X_SREGS16 sr;
/* Print ASCII character */
ir.h.ah = 9;
/* AL = character to display */
ir.h.al = '+';
/* BH = page number, BL = attribute */
ir.x.bx = 3;
/* Count number */
ir.x.cx = 3;
vm86_callBIOS(0x10,&ir,&or,&sr);
}
#else
 
void XBIOSDemo(void)
{
X_REGS16 ir,or;
X_SREGS16 sr;
/* Set video mode */
ir.h.ah = 9;
ir.h.al = '+';
ir.x.bx = 3;
ir.x.cx = 3;
X_callBIOS(0x10,&ir,&or,&sr);
}
#endif
 
void BIOSDemo(void)
{
X_REGS16 ir,or;
X_SREGS16 sr;
register int i;
/* Set video mode */
ir.h.ah = 0;
 
#if 0
ir.h.al = 0x03;
vm86_callBIOS(0x10,&ir,&or,&sr);
 
ir.h.ah = 0x0C;
ir.h.al = i % 16;
ir.x.bx = 0;
ir.x.dx = i+40;
ir.x.cx = i+100;
vm86_callBIOS(0x10,&ir,&or,&sr);
 
 
#else
ir.h.al = 0x12;
vm86_callBIOS(0x10,&ir,&or,&sr);
/* Put some pixels */
for (i = 0; i < 200; i++) {
ir.h.ah = 0x0C;
ir.h.al = i % 16;
ir.x.bx = 0;
ir.x.dx = i+40;
ir.x.cx = i+100;
vm86_callBIOS(0x10,&ir,&or,&sr);
}
#endif
WAIT();
/* Set video mode */
ir.h.ah = 0;
ir.h.al = 0x03;
vm86_callBIOS(0x10,&ir,&or,&sr);
}
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
WORD c;
int i;
struct multiboot_info *mbi;
 
sp1 = get_SP();
mbi = l1_init();
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
l1_exit(-1);
}
message("Starting...");
c = ll_context_save();
message("CX=%x\n",c);
for (i = 0; i < 0x4F000; i++);
#ifdef __VM86__
vm86_init();
 
l1_int_bind(0x6d, emulate);
/*
l1_irq_bind(0x6d, emulate);
*/
 
BIOSDemo();
#else
XBIOSDemo();
#endif
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
l1_end();
return 1;
}
/shark/branches/xen/oslib/examples/mbdemo.c
0,0 → 1,114
/* 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.
*/
 
/* Multiboot Info test file */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/i386/mb-info.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/event.h>
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
struct ll_initparms parms;
struct multiboot_info *mbi;
DWORD lbase, hbase;
DWORD lsize, hsize;
int eXtender = 0;
 
sp1 = get_SP();
cli();
parms.mode = LL_PERIODIC;
parms.tick = 1000;
mbi = ll_init();
event_init(&parms);
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
sti();
 
message("LowLevel started...\n");
message("MultiBoot informations:\n");
if (mbi->flags & MB_INFO_BOOT_LOADER_NAME) {
message("Loader Name provided: %s\n", (char *)mbi->boot_loader_name);
if (*((char *)(mbi->boot_loader_name)) == 'X') {
eXtender = 1;
}
}
if (mbi->flags & MB_INFO_MEMORY) {
message("\tMemory informations OK\n");
lsize = mbi->mem_lower * 1024;
hsize = mbi->mem_upper * 1024;
message("Mem Lower: %lx %lu\n", lsize, lsize);
message("Mem Upper: %lx %lu\n", hsize, hsize);
if (eXtender) {
lbase = mbi->mem_lowbase;
hbase = mbi->mem_upbase;
} else {
lbase = 0x0;
hbase = 0x100000;
}
message("\t\tLow Memory: %ld - %ld (%lx - %lx) \n",
lbase, lbase + lsize,
lbase, lbase + lsize);
message("\t\tLow Memory: %ld - %ld (%lx - %lx)\n",
hbase, hbase + hsize,
hbase, hbase + hsize);
}
if (mbi->flags & MB_INFO_BOOTDEV) {
message("\tBoot device set\n");
}
if (mbi->flags & MB_INFO_CMDLINE) {
message("\tCommand line provided\n");
}
if (mbi->flags & MB_INFO_MODS) {
message("\tSome modules was loaded\n");
}
if (mbi->flags & MB_INFO_AOUT_SYMS) {
message("\tA.OUT Simbol table\n");
}
if (mbi->flags & MB_INFO_ELF_SHDR) {
message("\tELF Section header\n");
}
if (mbi->flags & MB_INFO_MEM_MAP) {
message("\tMemory map provided\n");
}
if (eXtender) {
message("\tLoaded through X\n");
}
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/pushdem.c
0,0 → 1,112
 
/*
* 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 <arch/i386/stdlib.h>
#include <ll/i386/tss-ctx.h>
#include <ll/i386/cons.h>
#include <ll/sys/ll/ll-instr.h>
#include <ll/sys/ll/ll-func.h>
 
#define STACK_SIZE 4096U /* Stack size in bytes */
#define USE_FPU 0x0001
 
WORD th1, thm;
 
#define T 1000
 
#if 1
#define TO ll_context_to
#define FROM ll_context_from
#else
#define TO ll_context_load
#define FROM ll_context_save
#endif
 
/* For stack allocation checking */
BYTE stack1[STACK_SIZE];
BYTE stack2[STACK_SIZE];
void tfunc(void)
{
message("ThreadFunc: Switching to main thread\n");
TO(thm);
message("ThreadFunc: I'm back\n");
}
 
void thread1(void *px)
{
message("Thread 1 running\n");
message("Calling ThreadFunc\n");
tfunc();
message("Another time thread 1\n");
message("Back to main\n");
TO(thm);
message("And now, finishing thread 1\n");
}
 
void alienfunc(void)
{
message("Who am I???\n");
}
 
void killer(void)
{
cli();
message("Killer!!!\n");
TO(thm);
}
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
void *mbi;
 
sp1 = get_SP();
cli();
 
mbi = ll_init();
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
sti();
message("LowLevel started...\n");
th1 = ll_context_create(thread1, &stack1[STACK_SIZE], NULL,killer, 0);
thm = FROM();
message("Thread 1 created\n");
message("Switching to it...\n");
TO(th1);
message("Returned to main\n");
message("Let's try if the push func works...\n");
message("It returned %lu\n", ll_push_func(alienfunc));
message("And now, to thread 1 again!!!\n");
TO(th1);
message("Main another time...\n");
TO(th1);
message("OK, now I finish...\n");
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/eventdem.c
0,0 → 1,173
/* 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.
*/
 
/* Event Demo */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/time.h>
#include <ll/sys/ll/event.h>
 
#define T 1000
 
DWORD t1[10], t2[10];
int id[10];
int canEnd;
 
void evtHandler(void *p)
{
int i;
struct timespec t;
static int n = 0;
 
i = *(int *)p;
 
t1[++n] = ll_gettime(TIME_NEW, &t);
t2[n] = TIMESPEC2USEC(&t);
id[n] = i;
 
if (n == 9) {
canEnd = 1;
/*message("\t\tCan End\n");*/
}
}
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
struct ll_initparms parms;
void *mbi;
struct timespec time1, time2, time3, time4, time5;
struct timespec time6, time7, time8, time9;
int par[10];
int i, secs;
DWORD oldt, t;
 
sp1 = get_SP();
cli();
 
#ifdef PERIODIC
parms.mode = LL_PERIODIC;
parms.tick = T;
#else
parms.mode = LL_ONESHOT;
#endif
 
mbi = ll_init();
event_init(&parms);
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
sti();
 
message("LowLevel started...\n");
 
/* cli(); */
NULL_TIMESPEC(&time1);
NULL_TIMESPEC(&time2);
NULL_TIMESPEC(&time3);
NULL_TIMESPEC(&time4);
NULL_TIMESPEC(&time5);
NULL_TIMESPEC(&time6);
NULL_TIMESPEC(&time7);
NULL_TIMESPEC(&time8);
NULL_TIMESPEC(&time9);
 
ADDNANO2TIMESPEC(1000000, &time1); /* Time1: 1 ms */
ADDNANO2TIMESPEC(5000000, &time2); /* Time2: 5 ms */
ADDNANO2TIMESPEC(10000000, &time3); /* Time 3: 10 ms */
ADDNANO2TIMESPEC(3000000, &time4); /* Time 4: 3 ms */
ADDNANO2TIMESPEC(7500000, &time5); /* Time 5: 7.5 ms */
ADDNANO2TIMESPEC(7000000, &time6); /* Time 6: 7 ms */
ADDNANO2TIMESPEC(500000000, &time7);
ADDNANO2TIMESPEC(500000000, &time7);
ADDNANO2TIMESPEC(500000000, &time7);
ADDNANO2TIMESPEC(500000000, &time7);
ADDNANO2TIMESPEC(500000000, &time7);
ADDNANO2TIMESPEC(500000000, &time7); /* Time 7: 6*500 ms = 3 Sec*/
ADDNANO2TIMESPEC(51700000, &time8); /* Time 8: 51.7 ms */
ADDNANO2TIMESPEC(51500000, &time9); /* Time 9: 51.5 ms */
 
cli();
t = ll_gettime(TIME_NEW, NULL);
sti();
for (i = 0; i < 10; i++) {
par[i] = i + 1;
}
canEnd = 0;
 
cli();
 
event_post(time1, evtHandler, &(par[0]));
event_post(time2, evtHandler, &(par[1]));
event_post(time3, evtHandler, &(par[2]));
event_post(time4, evtHandler, &(par[3]));
event_post(time5, evtHandler, &(par[4]));
i = event_post(time6, evtHandler, &(par[5]));
event_post(time7, evtHandler, &(par[6]));
event_post(time8, evtHandler, &(par[7]));
event_post(time9, evtHandler, &(par[8]));
 
event_delete(i);
event_post(time5, evtHandler, &(par[5]));
message("Now time is %lu\n", t);
secs = 0;
oldt = 0;
canEnd = 0;
while((canEnd == 0) && (secs < 6)) {
cli();
t = ll_gettime(TIME_NEW, NULL);
sti();
if (t < oldt) {
error("Time goes back???\n");
message("ARGGGGG! %lu %lu\n", t, oldt);
ll_abort(100);
}
oldt = t;
if ((t / 1000000) > secs) {
secs++;
message(" %d %lu\n", secs, t);
}
}
cli();
message("Can End detected\n");
ll_end();
sp2 = get_SP();
for (i = 1; i < 10; i++) {
message("Event %d called at time %lu == %lu\n", id[i],
t1[i], t2[i]);
}
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
 
return 1;
}
/shark/branches/xen/oslib/examples/asdemo.c
0,0 → 1,201
/* 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 test file */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/i386/hw-arch.h>
#include <ll/i386/farptr.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/aspace.h>
#include <ll/sys/ll/event.h>
 
#define T 1000
#define WAIT() for (w = 0; w < 0x5FFFFF; w++)
 
extern DWORD GDT_base;
 
BYTE space[2048];
BYTE stack1[1024];
WORD th1, th2, thm;
 
/* For now, this is not called */
void killer(void)
{
cli();
message("Killer!!!\n");
ll_context_load(thm);
}
 
/* Used to switch back to main thread */
void evtHandler(void *v)
{
ll_context_load(thm);
}
 
/*
Dummy thread: used only to test a context switch between two threads
in the same AS
*/
void nullfun1(void *p)
{
message("In thread 1\n");
ll_context_load(thm);
}
 
/*
And this is the thread that runs in the new AS... It cannot call
any function (it is alone in its AS), so it simply plots a star
on the screen and loops waiting for an event that switches to the
main thread.
*/
void nullfun(void *p)
{
/* Some asm to write on the screen (we cannot use libc... it is not
linked in this AS */
__asm__ __volatile__ ("movl $0xb8000, %ebp");
__asm__ __volatile__ ("addl $150, %ebp");
__asm__ __volatile__ ("movb $'*', %fs:0(%ebp)");
__asm__ __volatile__ ("incl %ebp");
__asm__ __volatile__ ("movb $6, %fs:0(%ebp)");
 
/* And now, WAIT!!! */
for(;;);
halt();
}
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
void *res;
AS as, ds;
int ok;
char mystring[20];
struct ll_initparms parms;
struct timespec time;
sp1 = get_SP();
cli();
if ((argc == 2) && (argv[1][0] == 'O')) {
parms.mode = LL_ONESHOT;
} else {
parms.mode = LL_PERIODIC;
parms.tick = 1000;
}
res = ll_init();
event_init(&parms);
 
if (res == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
NULL_TIMESPEC(&time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time);
ADDNANO2TIMESPEC(500000000, &time); /* Time1: 5 ms */
event_post(time, evtHandler, NULL);
sti();
 
message("LowLevel started...\n");
as_init();
 
message("Creating an Address Space\n");
as = as_create();
message("Created: ID = %d %x\n", as, as);
message("Binding array @ 0x%lx\n", (DWORD)space);
ok = as_bind(as, (DWORD)space, 0, sizeof(space));
 
if (ok < 0) {
message("Error in as_bind!!!\n");
} else {
message("Bound\n");
}
_farpokeb(as, 0, 'H');
_farpokeb(as, 1, 'e');
_farpokeb(as, 2, 'l');
_farpokeb(as, 3, 'l');
_farpokeb(as, 4, 'o');
_farpokeb(as, 5, 0);
 
ds = get_DS();
fmemcpy(ds, (DWORD)mystring, as, 0, 10);
message("Memory space: %s\n", space);
message("My String: %s\n", mystring);
 
fmemcpy(as, 0, ds, (DWORD)nullfun, 1000);
/* Create a thread (in our AS) and a task (in a different AS) */
th2 = ll_context_create(nullfun1, &stack1[1024], NULL,killer, 0);
th1 = ll_context_create(0, (void *)2048, NULL,killer, 0);
ll_context_setspace(th1, as);
/* Save our context, in order to permit to switch back to main */
thm = ll_context_save();
message("I am thread %x\n", thm);
message("Thread 1 created\n");
message("Switching to it...\n");
ll_context_load(th2);
message("Back to Main\n");
 
/* Plot something in a stupid way, just to do some work... */
__asm__ __volatile__ ("movl $0x30, %eax");
__asm__ __volatile__ ("movw %ax, %fs");
__asm__ __volatile__ ("movl $0xb8000, %edi");
__asm__ __volatile__ ("addl $152, %edi");
__asm__ __volatile__ ("movb $'+', %ds:0(%edi)");
__asm__ __volatile__ ("incl %edi");
__asm__ __volatile__ ("movb $6, %ds:0(%edi)");
/* And now, go to the new task!!! */
ll_context_load(th1);
 
message("Main task again...\n");
 
__asm__ __volatile__ ("movl $0x30, %eax");
__asm__ __volatile__ ("movw %ax, %fs");
__asm__ __volatile__ ("movl $0xb8000, %edi");
__asm__ __volatile__ ("addl $154, %edi");
__asm__ __volatile__ ("movb $'-', %fs:0(%edi)");
__asm__ __volatile__ ("incl %edi");
__asm__ __volatile__ ("movb $6, %fs:0(%edi)");
 
message("Current time: %ld (= %ld?)\n", ll_gettime(TIME_NEW, NULL),
ll_gettime(TIME_EXACT, NULL));
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/cpudemo.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.
*/
 
/* CPU Detection test file */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/i386/hw-arch.h>
#include <ll/sys/ll/ll-func.h>
 
#define T 1000
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
struct ll_cpuInfo cpu;
void *res;
char vendorName[13];
 
sp1 = get_SP();
cli();
res = ll_init();
 
if (res == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
sti();
 
message("LowLevel started...\n");
message("CPU informations:\n");
X86_get_CPU(&cpu);
 
message("\tCPU type: %lu\n", cpu.X86_cpu);
 
if (cpu.X86_cpuIdFlag) {
message("CPUID instruction workin'...\n");
message("\tCPU Vendor ID: ");
 
memcpy(vendorName, &(cpu.X86_vendor_1), 12);
vendorName[12] = 0;
message("%s\n", vendorName);
 
message("\tCPU Stepping ID: %lx", cpu.X86_cpu & 0x0F);
message("\tCPU Model: %lx", (cpu.X86_cpu >> 4) & 0x0F);
message("\tCPU Family: %lx", (cpu.X86_cpu >> 8) & 0x0F);
message("\tCPU Type: %lx\n", (cpu.X86_cpu >> 12) & 0x0F);
 
message("\tStandard Feature Flags %lx\n", cpu.X86_StandardFeature);
if (cpu.X86_StandardFeature & 0x01) {
message("Internal FPU present...\n");
}
if (cpu.X86_StandardFeature & 0x02) {
message("V86 Mode present...\n");
}
if (cpu.X86_StandardFeature & 0x04) {
message("Debug Extension present...\n");
}
if (cpu.X86_StandardFeature & 0x08) {
message("4MB pages present...\n");
}
if (cpu.X86_StandardFeature & 0x10) {
message("TimeStamp Counter present...\n");
}
if (cpu.X86_StandardFeature & 0x20) {
message("RDMSR/WRMSR present...\n");
}
if (cpu.X86_StandardFeature & 0x40) {
message("PAE present...\n");
}
if (cpu.X86_StandardFeature & 0x80) {
message("MC Exception present...\n");
}
if (cpu.X86_StandardFeature & 0x0100) {
message("CMPXCHG8B present...\n");
}
if (cpu.X86_StandardFeature & 0x0200) {
message("APIC on chip...\n");
}
if (cpu.X86_StandardFeature & 0x1000) {
message("MTRR present...\n");
}
if (cpu.X86_StandardFeature & 0x2000) {
message("Global Bit present...\n");
}
if (cpu.X86_StandardFeature & 0x4000) {
message("Machine Check present...\n");
}
if (cpu.X86_StandardFeature & 0x8000) {
message("CMOV present...\n");
}
if (cpu.X86_StandardFeature & 0x800000) {
message("MMX present...\n");
}
}
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
 
return 1;
}
/shark/branches/xen/oslib/examples/scheddem.c
0,0 → 1,291
/* 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.
*/
 
/* Stupid Scheduling Demo */
 
#include <ll/i386/cons.h>
#include <ll/i386/tss-ctx.h>
#include <ll/i386/error.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 <arch/stdlib.h>
 
#define FREE 0
#define IDLE 1
 
struct ctx {
WORD ll;
struct timespec time;
DWORD cputime;
DWORD toexec;
int acc;
DWORD slice;
int state;
};
 
struct trkevt {
int thread;
DWORD time;
int value;
};
 
struct trkevt track[10000];
 
DWORD cpu[] = { 5000, 2000, 10000, 500, 5000, 6000, 20000, 1000, 7000 };
DWORD p[] =
{ 100000, 50000, 100000, 5000, 20000, 30000, 200000, 200000, 35000 };
 
#define STACK_SIZE 100000U /* Stack size in bytes */
#define USE_FPU 0x0001
 
WORD th1, thm;
 
#define T 1000
 
#if 1
#define TO ll_context_to
#define FROM ll_context_from
#else
#define TO ll_context_load
#define FROM ll_context_save
#endif
 
/* For stack allocation checking */
BYTE stacks[STACK_SIZE];
#define N 10
 
struct ctx context[N];
int exec;
 
 
 
void endProg(void *p)
{
int i;
DWORD last[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
DWORD lasttime, lastthread;
 
lasttime = 0;
lastthread = 0;
for (i = 0; i < 120; i++) {
if (last[track[i].thread] != 0) {
if (lastthread == 3) {
message("Thread %d <-- time %lu (after %lu), Thread %lu executed for %lu --- %d\n",
track[i].thread, track[i].time,
track[i].time - last[track[i].thread], lastthread,
track[i].time - lasttime, track[i].value);
}
}
lastthread = track[i].thread;
last[track[i].thread] = track[i].time;
lasttime = track[i].time;
}
 
ll_abort(110);
}
 
int schedule(void);
 
 
void endBudget(void *p)
{
struct ctx *c = p;
struct timespec time, toexec, xcuted, start;
int newthread;
 
ll_gettime(TIME_NEW, &time);
NULL_TIMESPEC(&toexec);
ADDNANO2TIMESPEC(c->toexec, &toexec);
SUBTIMESPEC(&(c->time), &toexec, &start);
SUBTIMESPEC(&time, &start, &xcuted);
NULL_TIMESPEC(&toexec);
ADDNANO2TIMESPEC(c->cputime * 1000, &toexec);
SUBTIMESPEC(&xcuted, &toexec, &start);
c->acc += TIMESPEC2NANOSEC(&start);
 
newthread = schedule();
TO(context[newthread].ll);
}
 
int schedule(void)
{
static int k = 0;
int toe;
int done;
 
done = 0;
while (!done) {
exec = (exec + 1) % N;
while (context[exec].state == FREE) {
exec = (exec + 1) % N;
}
/*
track[k].thread = exec;
track[k].value = context[exec].acc;
track[k].time = ll_gettime(TIME_NEW, &(context[exec].time));
k++;
*/
ll_gettime(TIME_NEW, &(context[exec].time));
toe = (context[exec].cputime * 1000 - context[exec].acc);
if (toe <= 0) {
context[exec].acc -= (context[exec].cputime * 1000);
k--;
} else {
done = 1;
}
}
context[exec].toexec = toe;
ADDNANO2TIMESPEC(toe, &(context[exec].time));
event_post(context[exec].time, endBudget, &(context[exec]));
return exec;
}
 
void thread(void *p)
{
int i, ii;
int position = 0;
char mark[11];
int active = 1;
WORD count = 0;
 
i = *(int *) p;
while (active) {
/*
printf_xy(10, i * 2 + 1, WHITE, "%c", mark);
*/
count++;
position = (position + 1) % 10;
for (ii = 0; ii < 10; ii++) {
mark[ii] = ' ';
}
mark[10] = 0;
mark[position] = 'O';
printf_xy(10, i * 2 + 1, WHITE, "%s", mark);
printf_xy(25, i * 2 + 1, WHITE, "%d %u", i, count);
for (ii = 0; ii < 10000; ii++);
 
if (count == 1000)
active = 0;
}
printf_xy(20, i * 2 + 1, WHITE, "Finished %d", i);
}
 
void killer(void)
{
int th;
 
cli();
context[exec].state = FREE;
th = schedule();
sti();
TO(context[th].ll);
}
 
int main(int argc, char *argv[])
{
DWORD sp1, sp2;
struct ll_initparms parms;
void *mbi;
DWORD t, oldt, secs;
int th;
int i;
int pars[N];
struct timespec endTime;
 
sp1 = get_SP();
cli();
parms.mode = LL_ONESHOT;
parms.tick = T;
 
mbi = ll_init();
event_init(&parms);
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
message("LowLevel started...\n");
for (i = 0; i < N - 1; i++) {
pars[i] = i;
context[i].ll =
ll_context_create(thread, &stacks[STACK_SIZE * (i + 1) / N],
&(pars[i]), killer, 0);
if (context[i].ll == 0) {
error("Unable to create thread");
ll_abort(100);
}
context[i].state = IDLE;
context[i].cputime = cpu[i];
context[i].toexec = cpu[i];
context[i].acc = 0;
context[i].slice = p[i];
}
 
context[N - 1].ll = FROM();
context[N - 1].state = IDLE;
context[N - 1].cputime = 200;
context[N - 1].slice = 20000;
 
message("All Threads created...\n");
NULL_TIMESPEC(&endTime);
endTime.tv_sec = 30;
 
event_post(endTime, endProg, NULL);
sti();
 
cli();
th = schedule();
sti();
 
TO(context[th].ll);
 
message("Thread MAIN restartin'\n");
 
secs = 0;
oldt = 0;
while (secs <= 20) {
cli();
t = ll_gettime(TIME_NEW, NULL);
sti();
if (t < oldt) {
message("ARGGGGG! %lu %lu\n", t, oldt);
ll_abort(99);
}
oldt = t;
if ((t / 1000000) > secs) {
secs++;
printf_xy(40, 20, WHITE, "%lu %lu ", secs, t);
}
}
message("\n DONE: Secs = %lu\n", secs);
 
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n", sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/syscalls.c
0,0 → 1,203
/* 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 test file */
 
#include <arch/i386/stdlib.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/i386/hw-arch.h>
#include <ll/i386/farptr.h>
#include <ll/sys/ll/ll-func.h>
#include <ll/sys/ll/aspace.h>
#include <ll/sys/ll/event.h>
#include <arch/string.h>
 
#define USE_NEW_HANDLERS
#define T 1000
#define WAIT() for (w = 0; w < 0x5FFFFF; w++)
 
extern DWORD GDT_base;
extern void int0x31(void);
 
#ifndef USE_NEW_HANDLERS
struct regs {
DWORD flags;
DWORD egs;
DWORD efs;
DWORD ees;
DWORD eds;
DWORD edi;
DWORD esi;
DWORD ebp;
DWORD esp;
DWORD ebx;
DWORD edx;
DWORD ecx;
DWORD eax;
};
#endif
 
BYTE space[2048];
WORD th1, th2, thm;
 
char outstring[] = "Hi there!!!\n";
 
#ifdef USE_NEW_HANDLERS
void chandler(DWORD intnum, struct registers r)
#else
void chandler(struct regs r, DWORD intnum)
#endif
{
message("[System Call] EAX = 0x%lx EBX = 0x%lx ECX = 0x%lx...\n",
r.eax, r.ebx, r.ecx);
 
if (r.eax == 1) {
message("Exit!!!\n");
ll_context_load(thm);
}
 
if (r.eax == 2) {
char string[20];
DWORD p;
unsigned int size;
 
p = GDT_read(r.eds, NULL, NULL, NULL);
p += r.ebx;
size = r.ecx;
if (size > 20) {
size = 20;
}
#if 0
message("Buffer @0x%lx, len %u\n", p, size);
l1_end();
sti();
l1_exit(0);
#endif
 
memcpy(string, (void *)p, size);
string[19] = 0;
message("Write...\n");
message("%s", string);
return;
}
 
message("Unsupported System Call!!!\n");
}
 
 
/* For now, this is not called */
void killer(void)
{
cli();
message("Killer!!!\n");
ll_context_load(thm);
}
 
/*
And this is the thread that runs in the new AS... It cannot call
any function (it is alone in its AS), so it simply plots a star
on the screen and loops waiting for an event that switches to the
main thread.
*/
void nullfun(void *p)
{
/* Some asm to write on the screen (we cannot use libc... it is not
linked in this AS */
__asm__ __volatile__ ("movl $2, %eax");
__asm__ __volatile__ ("movl $1000, %ebx");
__asm__ __volatile__ ("movl $16, %ecx");
__asm__ __volatile__ ("int $0x31");
__asm__ __volatile__ ("movl $1, %eax");
__asm__ __volatile__ ("int $0x31");
 
/* should not arrive here... */
for(;;);
halt();
}
 
int main (int argc, char *argv[])
{
DWORD sp1, sp2;
void *res;
AS as, ds;
int ok;
sp1 = get_SP();
cli();
res = ll_init();
 
if (res == NULL) {
message("Error in LowLevel initialization code...\n");
sti();
l1_exit(-1);
}
message("LowLevel started...\n");
#ifdef USE_NEW_HANDLERS
l1_int_bind(0x31, chandler);
#else
IDT_place(0x31, int0x31);
#endif
as_init();
 
message("Creating an Address Space\n");
as = as_create();
message("Created: ID = %d %x\n", as, as);
message("Binding array @ 0x%lx\n", (DWORD)space);
ok = as_bind(as, (DWORD)space, 0, sizeof(space));
 
if (ok < 0) {
message("Error in as_bind!!!\n");
} else {
message("Bound\n");
}
 
ds = get_DS();
/* Let's create the image of the process...
* 0 --> 1000 : text
* 1000 --> 1000 + strlen(outstring) : initialized data
* ? <-- 2048 : stack
*/
fmemcpy(as, 0, ds, (DWORD)nullfun, 1000);
fmemcpy(as, 1000, ds, (DWORD)outstring, strlen(outstring));
/* Create a thread (in our AS) and a task (in a different AS) */
th1 = ll_context_create(0, (void *)2048, NULL,killer, 0);
ll_context_setspace(th1, as);
/* Save our context, in order to permit to switch back to main */
thm = ll_context_save();
message("I am thread %x\n", thm);
message("Thread 1 created\n");
message("Switching to it...\n");
ll_context_load(th1);
message("Back to Main\n");
 
cli();
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
}
/shark/branches/xen/oslib/examples/pitsdemo.c
0,0 → 1,35
 
/*
* 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/pit.h>
#include <ll/sys/ll/time.h>
 
main()
{
struct pitspec ps1;
struct timespec ts1;
 
ps1.units = 1432809;
ps1.gigas = 10;
 
PITSPEC2TIMESPEC(&ps1, &ts1);
 
message("%lu %lu\n", PITSPEC2USEC(&ps1), TIMESPEC2USEC(&ts1));
message("%lu %lu\n", ts1.tv_sec, ts1.tv_nsec);
for(;;);
}
/shark/branches/xen/oslib/examples/vmdemo.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.
*/
 
/* Only to test if the VM include is OK... */
 
#include <ll/ll.h>
 
#define T 1000
int a; /* This must be global, otherwise the compiler optimization will
remove the division by 0...
*/
 
int main (int argc, char *argv[])
{
/*
DWORD sp1, sp2;
struct ll_initparms parms;
struct multiboot_info *mbi;
 
sp1 = get_SP();
parms.mode = LL_PERIODIC;
parms.tick = T;
mbi = ll_init();
event_init(&parms);
 
if (mbi == NULL) {
message("Error in LowLevel initialization code...\n");
l1_exit(-1);
}
ll_end();
sp2 = get_SP();
message("End reached!\n");
message("Actual stack : %lx - ", sp2);
message("Begin stack : %lx\n", sp1);
message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
return 1;
*/
l1_init();
a = 1 / 0; /* Test the exception handler... */
l1_end();
 
return 1;
}
/shark/branches/xen/oslib/examples/bugs.txt
0,0 → 1,5
- The scheduling demo is bugged... The error is in the demo code, not in
the OS library :) FIXED!!! It is orrible (and gives some warning compiling),
but now it works correctly.
 
- Now, also the warning has been removed...
/shark/branches/xen/oslib/xlib/Makefile
0,0 → 1,19
targets:= \
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
 
/shark/branches/xen/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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/oslib/xlib/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);
}
/shark/branches/xen/oslib/xlib/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/oslib/xlib/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/oslib/config.mk
0,0 → 1,73
include $(BASE)/../shark.cfg
 
CC = gcc
AS = gcc
LD = ld
AR = ar
INCL = -I$(BASE) -I$(BASE)/../libc/arch/$(ARCH)/include
LIB_PATH = $(BASE)/lib/
LIB_DIR = $(BASE)/lib
 
CFG_OPT += -D__LINUX__
 
ifeq ($(TSC),TRUE)
CFG_OPT += -D__TSC__
ifeq ($(APIC),TRUE)
CFG_OPT += -D__APIC__
endif
endif
 
ifeq ($(findstring 1000,$(TIMER_OPT)) , 1000)
CFG_OPT += -D__O1000__
else
ifeq ($(findstring 2000,$(TIMER_OPT)) , 2000)
CFG_OPT += -D__O2000__
else
ifeq ($(findstring 4000,$(TIMER_OPT)) , 4000)
CFG_OPT += -D__O4000__
else
CFG_OPT += -D__O8000__
endif
endif
endif
 
ifeq ($(findstring NEW,$(TRACER)) , NEW)
ifeq ($(TSC),TRUE)
CFG_OPT += -D__NEW_TRACER__
endif
endif
ifeq ($(findstring OLD,$(TRACER)) , OLD)
CFG_OPT += -D__OLD_TRACER__
endif
 
ifeq ($(findstring GCC4,$(COMPILER)) , GCC4)
# this options are for newer gcc4 compilers
C_OPT = -Wall -O -fno-builtin -nostdinc -Wno-attributes -Wno-pointer-sign -minline-all-stringops $(CFG_OPT) -DMAIN=__kernel_init__ $(INCL)
endif
 
ifeq ($(findstring GCC3,$(COMPILER)) , GCC3)
C_OPT = -Wall -O -fno-builtin -nostdinc -minline-all-stringops $(CFG_OPT) -DMAIN=__kernel_init__ $(INCL)
endif
 
ifeq ($(findstring DJGPP,$(COMPILER)) , DJGPP)
C_OPT = -Wall -O -fno-builtin -nostdinc -minline-all-stringops $(CFG_OPT) -DMAIN=__kernel_init__ $(INCL)
endif
 
ASM_OPT = -x assembler-with-cpp $(CFG_OPT) $(INCL)
LINK_OPT = -Bstatic -Ttext $(MEM_START) -s -nostartfiles -nostdlib -L$(LIB_PATH)
 
MKDIR = mkdir
CP = cp
CAT = cat
RM = rm -f
RMDIR = rm -rf
 
# Common rules
 
%.o : %.s
$(REDIR) $(CC) $(ASM_OPT) -c $<
%.o : %.c
$(REDIR) $(CC) $(C_OPT) -c $<
%.s : %.c
$(REDIR) $(CC) $(C_OPT) -S $<
 
/shark/branches/xen/oslib/tools/binfin.c
0,0 → 1,63
 
/*
* 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 <malloc.h>
#include <stdio.h>
#include "../ll/i386/mb-hdr.h"
 
/*
* Warning!!! This program does not work properly...
* FIXIT!
*/
void main(int argc, char *argv[])
{
FILE *in;
char *buf,*p;
register scan;
unsigned long multiboot_sign = MULTIBOOT_MAGIC, size;
unsigned long *search;
if (argc != 2) {
printf("Usage: binfin <file>\n");
exit(0);
}
in = fopen(argv[1],"rb");
if (in == NULL) {
printf("Error! File %s not found\n",argv[1]);
exit(-1);
}
fseek(in, 0, SEEK_END);
size = ftell(in);
buf = malloc(size);
if (buf == NULL) {
printf("Malloc error! Requested : %lu\n",size);
exit(-2);
}
fread(buf,1,size,in);
fclose(in);
for (scan = 0, p = buf; scan < size; scan++,p++) {
search = (unsigned long *)(p);
if (*search == multiboot_sign) {
printf("Gotta! Offset = %lx(%lu)\nAligned = %s",scan,scan, scan == (scan & ~0x00000003) ? "Yes" : "No" );
free(buf);
exit(1);
}
}
printf("Not found!\n");
exit(1);
}
/shark/branches/xen/oslib/tools/checksymbols.c
0,0 → 1,73
 
/*
* 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 <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
char *symbol[100];
int i, j, found, size;
FILE *f;
char buff[20], *profile = "Profile:", *str, c;
if (argc != 2) {
printf("Usage: %s <filename>\n", argv[0]);
exit(-1);
}
 
f = fopen(argv[1], "r");
if (f == NULL) {
printf("Input file: %s\n", argv[1]);
perror("error opening file");
exit(-1);
}
fseek(f, 0, SEEK_END);
size = ftell(f);
printf("File Name: %s\n", argv[1]);
printf("File Size: %d\n", size);
found = 0;
for (i = 0; i < size; i++) {
fseek(f, i, SEEK_SET);
fread(buff, 8, 1, f);
if (memcmp(buff, profile, 8) == 0) {
/* Found!!! */
str = malloc(20);
symbol[found++] = str;
j = 0;
do {
c = fgetc(f);
if ((j != 0) || (c != 0)) {
str[j] = c;
j++;
} else {
c = 1;
}
} while (c != 0);
}
i++;
}
fclose(f);
 
printf("%d symbols found:\n", found);
for(i = 0; i < found; i++) {
printf("\t%s\n", symbol[i]);
}
exit(0);
}
/shark/branches/xen/oslib/mk/gnu.mk
0,0 → 1,61
include $(BASE)/../shark.cfg
 
CC = gcc
AS = gcc
LD = ld
AR = ar
INCL = $(BASE)
LIB_PATH = $(BASE)/lib/
LIB_DIR = $(BASE)/lib
 
CFG_OPT += -D__LINUX__
 
ifeq ($(TSC),TRUE)
CFG_OPT += -D__TSC__
ifeq ($(APIC),TRUE)
CFG_OPT += -D__APIC__
endif
endif
 
ifeq ($(findstring 1000,$(TIMER_OPT)) , 1000)
CFG_OPT += -D__O1000__
else
ifeq ($(findstring 2000,$(TIMER_OPT)) , 2000)
CFG_OPT += -D__O2000__
else
ifeq ($(findstring 4000,$(TIMER_OPT)) , 4000)
CFG_OPT += -D__O4000__
else
CFG_OPT += -D__O8000__
endif
endif
endif
 
ifeq ($(findstring NEW,$(TRACER)) , NEW)
ifeq ($(TSC),TRUE)
CFG_OPT += -D__NEW_TRACER__
endif
endif
ifeq ($(findstring OLD,$(TRACER)) , OLD)
CFG_OPT += -D__OLD_TRACER__
endif
 
C_OPT = -Wall -O -fno-builtin -nostdinc $(CFG_OPT) -DMAIN=__kernel_init__ -I$(INCL)
ASM_OPT = -x assembler-with-cpp $(CFG_OPT) -I$(INCL)
LINK_OPT = -Bstatic -Ttext $(MEM_START) -s -nostartfiles -nostdlib -L$(LIB_PATH)
 
MKDIR = mkdir
CP = cp
CAT = cat
RM = rm -f
RMDIR = rm -rf
 
# Common rules
 
%.o : %.s
$(REDIR) $(CC) $(ASM_OPT) -c $<
%.o : %.c
$(REDIR) $(CC) $(C_OPT) -c $<
%.s : %.c
$(REDIR) $(CC) $(C_OPT) -S $<
 
/shark/branches/xen/oslib/mk/linux.mk
0,0 → 1,61
include $(BASE)/../shark.cfg
 
CC = gcc
AS = gcc
LD = ld
AR = ar
INCL = $(BASE)
LIB_PATH = $(BASE)/lib/
LIB_DIR = $(BASE)/lib
 
CFG_OPT += -D__LINUX__
 
ifeq ($(TSC),TRUE)
CFG_OPT += -D__TSC__
ifeq ($(APIC),TRUE)
CFG_OPT += -D__APIC__
endif
endif
 
ifeq ($(findstring 1000,$(TIMER_OPT)) , 1000)
CFG_OPT += -D__O1000__
else
ifeq ($(findstring 2000,$(TIMER_OPT)) , 2000)
CFG_OPT += -D__O2000__
else
ifeq ($(findstring 4000,$(TIMER_OPT)) , 4000)
CFG_OPT += -D__O4000__
else
CFG_OPT += -D__O8000__
endif
endif
endif
 
ifeq ($(findstring NEW,$(TRACER)) , NEW)
ifeq ($(TSC),TRUE)
CFG_OPT += -D__NEW_TRACER__
endif
endif
ifeq ($(findstring OLD,$(TRACER)) , OLD)
CFG_OPT += -D__OLD_TRACER__
endif
 
C_OPT = -Wall -O -fno-builtin -nostdinc $(CFG_OPT) -DMAIN=__kernel_init__ -I$(INCL)
ASM_OPT = -x assembler-with-cpp $(CFG_OPT) -I$(INCL)
LINK_OPT = -Bstatic -Ttext $(MEM_START) -s -nostartfiles -nostdlib -L$(LIB_PATH)
 
MKDIR = mkdir
CP = cp
CAT = cat
RM = rm -f
RMDIR = rm -rf
 
# Common rules
 
%.o : %.s
$(REDIR) $(CC) $(ASM_OPT) -c $<
%.o : %.c
$(REDIR) $(CC) $(C_OPT) -c $<
%.s : %.c
$(REDIR) $(CC) $(C_OPT) -S $<
 
/shark/branches/xen/oslib/mk/os.x
0,0 → 1,25
OUTPUT_FORMAT("coff-go32")
ENTRY(start)
SECTIONS
{
.text 0x1000+SIZEOF_HEADERS : {
*(.text)
etext = . ; _etext = .;
}
.data : {
djgpp_first_ctor = . ;
*(.ctor)
djgpp_last_ctor = . ;
djgpp_first_dtor = . ;
*(.dtor)
djgpp_last_dtor = . ;
*(.data)
edata = . ; _edata = .;
}
.bss SIZEOF(.data) + ADDR(.data) :
{
*(.bss)
*(COMMON)
end = . ; _end = .;
}
}
/shark/branches/xen/oslib/mk/oldgnu.mk
0,0 → 1,23
CC = gcc
AS = gcc
LD = ld
AR = ar
INCL = $(BASE)
LIB_PATH = $(BASE)/lib/
LIB_DIR = $(BASE)\lib
 
C_OPT = -Wall -O -finline-functions -fno-builtin -nostdinc -D__GNU__ -D__OLD_GNU__ -I$(INCL)
ASM_OPT = -x assembler-with-cpp -D__GNU__ -I$(INCL)
LINK_OPT = -T $(BASE)/mk/os.x -Bstatic -Ttext 0x320000 -oformat coff-go32 -s -nostartfiles -nostdlib -L$(LIB_PATH)
 
MKDIR = md
CP = copy
CAT = @type
RM = -del
RMDIR = -deltree
 
# Common rules
%.o : %.s
$(REDIR) $(CC) $(ASM_OPT) -c $<
%.o : %.c
$(REDIR) $(CC) $(C_OPT) -c $<
/shark/branches/xen/oslib/todo.txt
0,0 → 1,51
- The vm86 reflection code contains a dirty hack: the vm86_exc1 function
in vm86-exc.c hardcodes the int to be reflected...
This should be fixed in some way!!!
FIXED (and seems to be working very well...)
 
- Now, the registers structure should be fixed: move the flags field to the
other side of the structure (adding the CS and EIP fields), so that
we will not have to push flags and explicitly move it anymore...
DONE
 
- Fix problems with ASs and INTs (see kl/cxsw-1.s and xlib/exc.s)
Done! At least it doesn't crash :)
Must check in some way if the stack is correct or not...
I checked it, and it seems to be ok...
 
- verify that only the needed .o files are linked (see -DPROFILE); provide
a lightweight implementation of ``message'' (currently remapped on
cprintf) that does not require linking libm
 
- profile and optimize the event management code
 
- rewrite cons.c isolating the parts making assumptions on memory spaces and
improving efficency (window-based functions can be implemented
separately)
 
- pentium timestamp conter code... Integrate it in timer code and event
management
Assigned to Gerardo
 
- provide some macro for int-based and call gate-based system calls
Done for INT: see examples/syscalls.c
 
- begin to implement some serious code using OSLib:
1) some simple multithreading executive based on cooperative and
preemptive scheduling, message-based or based on shared
memory and semaphores...
2) some real small kernel, separating it from application code
3) as 2), but with different address spaces for kernel and
application
...
 
- fix the eXtender in order to be fully multiboot compliant (no extension to
the standard multiboot structure: we can use memory maps). Upgrade it
to the latest version of the standard. Implement modules loading
== Some work has been done... Now the eXtender can load MB compiant images
and manages modules.
== Now everything is compatible with the latest MB standard (the loader
name is used)
o Still to do: the memory map stuff & module parameters
 
- what about fixing that _NOH4_ story?
/shark/branches/xen/oslib/GPL.txt
0,0 → 1,340
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
 
How to Apply These Terms to Your New Programs
 
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
 
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
 
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
 
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
 
 
Also add information on how to contact you by electronic and paper mail.
 
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
 
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
 
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
 
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
 
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
 
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
/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)/tracer/include \
-I$(srctree)/oslib
 
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:= arch/$(ARCH)/ kernel/ modules/
libgkern.a-objs:= oslib/ kernel/ modules/
 
# Let the good times roll...
$(eval $(call recurse-templ,$(srctree)))