/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))) |