/shark/trunk/oslib/kl/time.c |
---|
30,17 → 30,15 |
#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 */ |
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 WORD lastTime; /* From event.c */ |
extern struct pitspec globalCounter; /* From event.c */ |
extern BYTE frc; |
extern int activeEvent; |
FILE(Time); |
47,80 → 45,84 |
TIME ll_gettime(int mode, struct timespec *tsres) |
{ |
DWORD res, tc; |
BYTE isr; |
struct timespec tmp; |
DWORD res, tc; |
BYTE isr; |
struct timespec tmp; |
if (activeEvent) { |
if (tsres != NULL) { |
PITSPEC2TIMESPEC(&globalCounter, tsres); |
return TIMESPEC2USEC(tsres); |
} else { |
PITSPEC2TIMESPEC(&globalCounter, &tmp); |
return TIMESPEC2USEC(&tmp); |
} |
} |
#if 1 |
if (activeEvent) { |
if (tsres != NULL) { |
PITSPEC2TIMESPEC(&globalCounter, tsres); |
} else { |
struct timespec tmp; |
if (mode == TIME_PTICK) { |
if (timermode != LL_PERIODIC) { |
return 0; |
PITSPEC2TIMESPEC(&globalCounter, &tmp); |
return TIMESPEC2USEC(&tmp); |
} |
return TIMESPEC2USEC(tsres); |
} |
res = TIMESPEC2USEC(&actTime); |
if (tsres != NULL) { |
memcpy(tsres, &actTime, sizeof(struct timespec)); |
#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; |
} |
return res; |
} |
if (mode == TIME_EXACT) { |
WORD tmp; |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
if (tsres != NULL) { |
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)); |
} |
return (PITSPEC2USEC(&globalCounter)); |
} |
if (mode == TIME_NEW) { |
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; |
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; |
} |
/* 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); |
/* 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; |
if (tsres != NULL) { |
memcpy(tsres, &tmp, sizeof(struct timespec)); |
} |
return res; |
} else { |
return 0; |
} |
} |
} |
return 0; |
return 0; |
} |
/shark/trunk/oslib/kl/event1.c |
---|
1,216 → 1,216 |
/* 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 routines (one shot mode) */ |
#include <ll/i386/stdlib.h> |
#include <ll/i386/mem.h> |
#include <ll/i386/pit.h> |
#include <ll/sys/ll/ll-data.h> |
#include <ll/sys/ll/time.h> |
#include <ll/sys/ll/event.h> |
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); |
/* TODO: oneshot_event_delete & oneshot_event_init... */ |
/* 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; |
if (!freeevents) { |
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) { |
ll_gettime(TIME_EXACT, &now); |
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) { |
NULL_TIMESPEC(&tmp); |
} else { |
SUBTIMESPEC(&(firstevent->time), &now, &tmp); |
} |
tnext = TIMESPEC2USEC(&tmp); |
tnext = (tnext * 1197) / 1000; |
pit_setconstant(0, 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; |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
PITSPEC2TIMESPEC(&globalCounter, &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--; |
} |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
PITSPEC2TIMESPEC(&globalCounter, &now); |
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); |
tnext = (tnext * 1197) / 1000; |
pit_setconstant(0, tnext); |
activeEvent = 0; |
} else { |
pit_setconstant(0, 0xFFFF); |
} |
} |
int oneshot_event_delete(int index) |
{ |
struct event *p1, *t; |
struct timespec tmp, now; |
DWORD tnext; |
int firstdeleted = FALSE; |
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) { |
pit_setconstant(0, 0xFFFF); |
} else { |
if (firstdeleted) { |
ll_gettime(TIME_EXACT, &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); |
tnext = (tnext * 1197) / 1000; |
pit_setconstant(0, tnext); |
} |
} |
} |
return 1; |
} |
/* 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 routines (one shot mode) */ |
#include <ll/i386/stdlib.h> |
#include <ll/i386/mem.h> |
#include <ll/i386/pit.h> |
#include <ll/sys/ll/ll-data.h> |
#include <ll/sys/ll/time.h> |
#include <ll/sys/ll/event.h> |
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); |
/* TODO: oneshot_event_delete & oneshot_event_init... */ |
/* 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; |
if (!freeevents) { |
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) { |
ll_gettime(TIME_NEW, &now); |
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) { |
NULL_TIMESPEC(&tmp); |
} else { |
SUBTIMESPEC(&(firstevent->time), &now, &tmp); |
} |
tnext = TIMESPEC2USEC(&tmp); |
tnext = (tnext * 1197) / 1000; |
pit_setconstant(0, 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; |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
PITSPEC2TIMESPEC(&globalCounter, &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--; |
} |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
PITSPEC2TIMESPEC(&globalCounter, &now); |
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); |
tnext = (tnext * 1197) / 1000; |
pit_setconstant(0, tnext); |
activeEvent = 0; |
} else { |
pit_setconstant(0, 0xFFFF); |
} |
} |
int oneshot_event_delete(int index) |
{ |
struct event *p1, *t; |
struct timespec tmp, now; |
DWORD tnext; |
int firstdeleted = FALSE; |
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) { |
pit_setconstant(0, 0xFFFF); |
} else { |
if (firstdeleted) { |
ll_gettime(TIME_NEW, &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); |
tnext = (tnext * 1197) / 1000; |
pit_setconstant(0, tnext); |
} |
} |
} |
return 1; |
} |
/shark/trunk/oslib/kl/init.c |
---|
28,6 → 28,7 |
#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> |
34,14 → 35,19 |
#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 */ |
#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); |
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 ll_exc_hook(int i) |
{ |
static char *exc_mess[] = { |
static char *exc_mess[] = { |
"#Division by 0", |
"#Debug fault", |
"#NMI detected", |
49,7 → 55,7 |
"#Overflow detected on INTO", |
"#BOUND limit exceeded", |
"*Unvalid opcode", |
"1FPU context switch", /* Handled in the llCtx.Asm/S File */ |
"1FPU context switch", /* Handled in the llCtx.Asm/S File */ |
"*Double defect", |
"#INTEL reserved", |
"*Unvalid TSS", |
59,103 → 65,131 |
"#Page fault", |
"#INTEL reserved", |
"2Coprocessor error" |
}; |
}; |
static int exc_code[] = { |
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 */ |
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 |
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(); */ |
ll_abort(exc_code[i]); |
/* 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(); */ |
ll_abort(exc_code[i]); |
} |
void *ll_init(void) |
{ |
void *p; |
int i; |
LIN_ADDR b; |
DWORD s; |
BYTE *base; |
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++) { |
p = l1_init(); |
/* First of all, init the exc and irq tables... */ |
irq_init(); |
for (i = 0; i < 16; i++) { |
void act_int(int 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_irq_bind(i, act_int); |
l1_exc_bind(i, 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); |
} |
/* ll_mem_init must be explicitelly called by program... */ |
/* 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 |
/* 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); |
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 |
ll_mem_init(base, s); |
#ifdef __MEM_DEBUG__ |
ll_mem_dump(); |
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 |
#endif |
return p; |
return p; |
} |
void abort_tail(int code) |
{ |
message("ABORT %d !!!", code); |
l1_end(); |
sti(); |
l1_exit(1); |
message("ABORT %d !!!",code); |
l1_end(); |
sti(); |
l1_exit(1); |
} |
void ll_end(void) |
{ |
l1_end(); |
l1_end(); |
} |
/shark/trunk/oslib/kl/intevt.c |
---|
1,4 → 1,3 |
/* Project: OSLib |
* Description: The OS Construction Kit |
* Date: 1.6.2000 |
27,6 → 26,7 |
#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> |
88,6 → 88,15 |
{ |
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(); |
109,3 → 118,5 |
} |
activeInt--; |
} |
/shark/trunk/oslib/kl/mem.c |
---|
32,16 → 32,16 |
FILE(Memory); |
#define MAX_PARTITION 50 /* Max available partition */ |
#define MAX_PARTITION 50 /* Max available partition */ |
static struct { |
BYTE used; |
BYTE used; |
#ifdef __WC16__ |
BYTE __huge *addr; |
BYTE __huge *addr; |
#else |
BYTE *addr; |
BYTE *addr; |
#endif |
DWORD size; |
DWORD size; |
} mem_table[MAX_PARTITION]; |
void ll_mem_init(void *base, DWORD size) |
50,8 → 50,7 |
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; |
for (i = 1; i < MAX_PARTITION; i++) mem_table[i].used = 0; |
} |
void *ll_alloc(DWORD s) |
61,31 → 60,28 |
while (i < MAX_PARTITION && p == NULL) { |
if (mem_table[i].used && (mem_table[i].size >= s)) |
p = mem_table[i].addr; |
else |
i++; |
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; |
} |
else mem_table[i].used = FALSE; |
} |
return (p); |
return(p); |
} |
WORD ll_free(void *p, DWORD s) |
WORD ll_free(void *p,DWORD s) |
{ |
register int i = 1; |
unsigned i1 = 0, i2 = 0; |
while (i < MAX_PARTITION && ((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; |
if (mem_table[i].addr + mem_table[i].size == p) i1 = i; |
if (mem_table[i].addr == (BYTE *)(p) + s) i2 = i; |
} |
i++; |
} |
92,22 → 88,21 |
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) { |
} |
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 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); |
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); |
return(TRUE); |
} |
void ll_mem_dump(void) |
114,8 → 109,6 |
{ |
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); |
if (mem_table[i].used) message("Entry : [%d] Addr : %p Size : %ld\n",i,mem_table[i].addr,mem_table[i].size); |
} |
} |
/shark/trunk/oslib/kl/event.c |
---|
25,6 → 25,7 |
#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/sys/ll/ll-data.h> |
#include <ll/sys/ll/ll-instr.h> |
60,7 → 61,10 |
extern void (*evt_prol) (void); |
extern void (*evt_epil) (void); |
void event_setlasthandler(void *p) { last_handler = p; } |
void event_setlasthandler(void *p) |
{ |
last_handler = p; |
} |
void event_setprologue(void *p) |
{ |
190,15 → 194,14 |
BYTE mask; |
TIME t; |
IDT_place(0x40, ll_timer); |
IDT_place(0x40,ll_timer); |
if (l->mode != LL_PERIODIC) { |
message("One-shot timer selected...\n"); |
error("Trying one-shot!!!"); |
t = 0; |
/* Mode: Binary/Mode 4/16 bit Time_const/Counter 0 */ |
pit_init(0, TMR_MD4, 0xFFFF); /* Timer 0, Mode 4, constant 0xFFFF */ |
} else { |
message("Periodic timer selected...\n"); |
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 */ |
221,8 → 224,8 |
} |
timermode = l->mode; |
if (ll_arch.x86.cpu > 4) { |
if (ll_arch.x86.cpu > 4) { |
/* Timer1: mode 0, time const 0... */ |
pit_init(1, TMR_MD0, 0); |
frc = 1; |
229,7 → 232,7 |
} else { |
frc = 2; |
pit_init(2, TMR_MD0, 0); |
outp(0x61, 3); |
outp(0x61, 3); |
} |
mask = ll_in(0x21); |
265,4 → 268,7 |
event_post = oneshot_event_post; |
event_delete = oneshot_event_delete; |
} |
/* Last but not least... */ |
irq_unmask(0); |
} |
/shark/trunk/oslib/kl/estub.c |
---|
24,7 → 24,7 |
#include <hw-data.h> |
#include "event.h" |
FILE(Event - Stub); |
FILE(Event-Stub); |
extern struct event *freeevents; |
extern struct event *firstevent; |
33,76 → 33,76 |
void called(void) |
{ |
printf("Called...\n"); |
printf("Called...\n"); |
} |
void event_printqueue(struct event *q) |
{ |
struct event *p; |
struct event *p; |
for (p = q; p; p = p->next) { |
printf("Entry %d: Time %d...\n", p->index, p->time); |
} |
for (p = q; p; p = p->next) { |
printf("Entry %d: Time %d...\n", p->index, p->time); |
} |
} |
main() |
{ |
int i, rem; |
event_init(); |
int i, rem; |
event_init(); |
printf("Free event queue:\n"); |
event_printqueue(freeevents); |
printf("Pending events queue:\n"); |
event_printqueue(firstevent); |
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(10, 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("Free event queue:\n"); |
event_printqueue(freeevents); |
printf("Pending events queue:\n"); |
event_printqueue(firstevent); |
printf("Pending events queue:\n"); |
event_printqueue(firstevent); |
i = event_post(100, called, NULL); |
printf("Inserted Event %d\n", i); |
printf("Now, Wakin' up...\n"); |
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); |
actTime = 1; |
wake_up(10); |
printf("Pending events queue:\n"); |
event_printqueue(firstevent); |
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); |
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/trunk/oslib/kl/cxsw-2.c |
---|
28,12 → 28,12 |
#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-instr.h> /* Only for HW instr... */ |
#include <ll/sys/ll/ll-func.h> |
FILE(KL - Context - Switch); |
FILE(KL-Context-Switch); |
extern TSS TSS_table[TSSMax]; |
extern TSS TSS_table[TSSMax]; |
extern WORD TSS_control[TSSMax]; |
extern BYTE ll_FPU_stdctx[FPU_CONTEXT_SIZE]; |
47,8 → 47,8 |
/* Just a debugging function; it dumps the status of the TSS */ |
void dump_TSS(WORD sel) |
{ |
BYTE acc, gran; |
DWORD base, lim; |
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); |
57,16 → 57,15 |
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)); |
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); |
int index = TSSsel2index(c); |
TSS_table[index].ss0 = as; |
TSS_table[index].cs = as + 8; |
76,30 → 75,29 |
} |
/* Initialize context -> TSS in 32 bit */ |
CONTEXT ll_context_create(void (*task) (void *p), BYTE * stack, |
void *parm, void (*killer) (void), WORD control) |
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; |
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 = (DWORD)(parm); |
stack_ptr--; |
*stack_ptr = (DWORD) (killer); |
*stack_ptr = (DWORD)(killer); |
/* Find a free TSS */ |
while ((TSS_control[index] & TSS_USED) && (index < TSSMain)) |
index++; |
while ((TSS_control[index] & TSS_USED) && (index < TSSMain)) index++; |
/* This exception would signal an error */ |
if (index >= TSSMain) { |
message("No more Descriptors...\n"); |
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].esp0 = (DWORD)(stack_ptr); |
TSS_table[index].esp1 = 0; |
TSS_table[index].esp2 = 0; |
TSS_table[index].ss0 = get_DS(); |
108,7 → 106,7 |
/* No paging activated */ |
TSS_table[index].cr3 = 0; |
/* Task entry point */ |
TSS_table[index].eip = (DWORD) (task); |
TSS_table[index].eip = (DWORD)(task); |
/* Need only to unmask interrupts */ |
TSS_table[index].eflags = 0x00000200; |
TSS_table[index].eax = 0; |
117,8 → 115,8 |
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].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(); |
130,10 → 128,10 |
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); |
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)); |
return(TSSindex2sel(index)); |
} |
145,18 → 143,18 |
TSS_control[index] = 0; |
} |
#if 0 /* It does not work... Fix it!!! */ |
DWORD ll_push_func(void (*func) (void)) |
#if 0 /* It does not work... Fix it!!! */ |
DWORD ll_push_func(void (*func)(void)) |
{ |
DWORD *p; |
DWORD old; |
DWORD *p; |
DWORD old; |
p = (DWORD *) entrypoint; |
old = *p; |
p = (DWORD *)entrypoint; |
old = *p; |
*p = (DWORD) func; |
return old; |
*p = (DWORD)func; |
return old; |
} |
#endif |
167,5 → 165,5 |
char *ll_context_sprintf(char *str, CONTEXT c) |
{ |
ksprintf(str, "%x (Hex)", c); |
return (str); |
return(str); |
} |
/shark/trunk/oslib/kl/timeint.s |
---|
83,7 → 83,6 |
xorl %ebx, %ebx |
movw %ss, %bx |
/* We must switch to a ``safe stack'' */ |
#if 0 |
/* |
* OK, this is the idea: in %esp we have the address of the |
* stack pointer in the APPLICATION address space... |
110,7 → 109,6 |
movw %cx, %ss |
pushl %ebx |
pushl %edx |
#endif |
cld |
movl SYMBOL_NAME(timermode), %eax |
cmpl $1, %eax |
133,13 → 131,12 |
call SYMBOL_NAME(ll_abort) |
Timer_OK: |
#if 0 |
/* Restore ESP */ |
popl %edx |
popl %ebx /* We must subtract it from ESP...*/ |
subl %ebx, %esp |
movw %dx, %ss |
#endif |
#ifdef __VIRCSW__ |
movw SYMBOL_NAME(currCtx), %ax |
/shark/trunk/oslib/kl/makefile |
---|
6,11 → 6,11 |
# |
ifndef BASE |
BASE = ../.. |
BASEDOS = ..\.. |
BASE = .. |
BASEDOS = .. |
endif |
include $(BASE)/config/config.mk |
include $(BASE)/config.mk |
C_OPT += -D__VIRCSW__ |
ASM_OPT += -D__VIRCSW__ |
17,9 → 17,7 |
#C_OPT += -DPROFILE |
#ASM_OPT += -DPROFILE |
KL_C_OBJ = stuff.o \ |
mem.o \ |
KL_C_OBJ = mem.o \ |
cxsw-2.o \ |
init.o \ |
time.o \ |
56,7 → 54,7 |
allclean : clean |
echo # Kernel Dependency file > deps |
$(RM) ..\lib\libkl.a |
$(RM) $(LIB_PATH)libkl.a |
deps :$(KL_C_OBJ:.o=.c) |
$(CC) $(C_OPT) $(KLINCL) -M $(KL_C_OBJ:.o=.c) > deps |
/shark/trunk/oslib/kl/aspace.c |
---|
24,61 → 24,61 |
#include <ll/sys/ll/ll-data.h> |
#include <ll/sys/ll/aspace.h> |
FILE(Address - Space); |
FILE(Address-Space); |
struct as AS_table[ASMax]; |
void as_init(void) |
{ |
int i; |
int i; |
for (i = 0; i < ASMax; i++) { |
AS_table[i].status = AS_FREE; |
} |
for (i = 0; i < ASMax; i++) { |
AS_table[i].status = AS_FREE; |
} |
} |
AS as_create(void) |
{ |
int i; |
int i; |
i = 0; |
while ((i < ASMax) && (AS_table[i].status & AS_BUSY)) { |
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; |
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); |
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); |
return ASindex2sel(i); |
} |
int as_bind(AS as, DWORD ph_addr, DWORD l_addr, DWORD size) |
{ |
int i = ASsel2index(as); |
int i = ASsel2index(as); |
/* We have not paging... So l_addr must be 0 */ |
if (l_addr != 0) |
return -1; |
/* 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; |
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); |
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; |
return 1; |
} |