/shark/trunk/oslib/libm/makefile |
---|
6,20 → 6,20 |
# |
ifndef BASE |
BASE = ../.. |
BASEDOS = ..\.. |
BASE = .. |
BASEDOS = .. |
endif |
include $(BASE)/config/config.mk |
include $(BASE)/config.mk |
C_INC= -I. -I$(BASE)/include/ll -I$(BASE)/include |
C_OPT += -I$(INCL)/ll -I. |
C_OPT += -Dlint -Wno-uninitialized -Wno-parentheses |
ASM_OPT += -Dlint -I. |
# by Massy |
# so there is no conflict with standard libC library |
C_OPT += -Dwrite=ll_internal_write |
C_OPT += -Dwrite=glue_write |
SRCDIRS = msun/src msun/i387 machine |
space := $(empty) $(empty) |
75,16 → 75,17 |
allclean : clean |
echo # Kernel Dependency file > deps |
$(RM) ..\lib\libhm.a |
$(RM) (LIB_PATH)libhm.a |
deps : $(OBJS:.o=.c) |
$(CC) $(C_OPT) $(VMINCL) -M $(OBJS:.o=.c) > deps |
#deps : $(OBJS:.o=.c) |
deps : makefile $(CFILES) |
$(CC) $(C_OPT) -M $(CFILES) > deps |
libhm.a : $(OBJS) |
$(AR) rs libhm.a $(OBJS) |
deb: |
type $(VPATH) |
echo $(CFILES) |
%.s:%.c |
/shark/trunk/oslib/todo.txt |
---|
1,6 → 1,17 |
- 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 |
17,6 → 28,7 |
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 |
32,4 → 44,8 |
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/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; |
} |
/shark/trunk/oslib/mk/gnu.mk |
---|
8,7 → 8,7 |
C_OPT = -Wall -O -finline-functions -fno-builtin -nostdinc -D__GNU__ -I$(INCL) |
ASM_OPT = -x assembler-with-cpp -D__GNU__ -I$(INCL) |
LINK_OPT = -Bstatic -Ttext 0x320000 -oformat coff-go32 -s -nostartfiles -nostdlib -L$(LIB_PATH) |
LINK_OPT = -T $(BASE)/mk/os.x -Bstatic -Ttext 0x320000 -oformat coff-go32 -s -nostartfiles -nostdlib -L$(LIB_PATH) |
MKDIR = md |
CP = copy |
/shark/trunk/oslib/mk/oldgnu.mk |
---|
8,7 → 8,7 |
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 = -Bstatic -Ttext 0x320000 -oformat coff-go32 -s -nostartfiles -nostdlib -L$(LIB_PATH) |
LINK_OPT = -T $(BASE)/mk/os.x -Bstatic -Ttext 0x320000 -oformat coff-go32 -s -nostartfiles -nostdlib -L$(LIB_PATH) |
MKDIR = md |
CP = copy |
/shark/trunk/oslib/libc/ioformat/ksprintf.c |
---|
25,8 → 25,6 |
#include <ll/i386/float.h> |
#include <ll/i386/mem.h> |
#include <ll/stdarg.h> |
#include <ll/ctype.h> |
#include <ll/math.h> |
#include "sprintf.h" |
FILE(ksprintf); |
/shark/trunk/oslib/libc/ioformat/ucvt.c |
---|
26,7 → 26,6 |
#include <ll/i386/mem.h> |
#include <ll/stdarg.h> |
#include <ll/ctype.h> |
#include <ll/math.h> |
#include "sprintf.h" |
FILE(ucvt); |
/shark/trunk/oslib/libc/ioformat/sscanf.c |
---|
24,7 → 24,6 |
#include <ll/i386/limits.h> |
#include <ll/stdarg.h> |
#include <ll/ctype.h> |
#include <ll/math.h> |
#include "sprintf.h" |
FILE(sscanf); |
/shark/trunk/oslib/libc/stdlib/strtou.c |
---|
24,7 → 24,6 |
#include <ll/i386/limits.h> |
#include <ll/stdarg.h> |
#include <ll/ctype.h> |
#include <ll/math.h> |
FILE(strtou); |
/shark/trunk/oslib/libc/reboot.c |
---|
22,7 → 22,7 |
/* Reset (or halt...) the system */ |
#include <ll/i386/hw-func.h> |
#include <ll/i386/cons.h> |
#include <ll/i386/error.h> |
FILE(reboot); |
/shark/trunk/oslib/libc/makefile |
---|
5,18 → 5,17 |
# Makefile for GNU MAKE & GCC 2.8.0 |
ifndef BASE |
BASE = ../.. |
BASEDOS = ..\.. |
BASE = .. |
BASEDOS = .. |
endif |
include $(BASE)/config/config.mk |
include $(BASE)/config.mk |
COMMON_OBJS = cons1.o \ |
cons2.o \ |
reboot.o \ |
cprintf.o \ |
message.o |
#C_OPT += -DPROFILE |
#ASM_OPT += -DPROFILE |
COMMON_OBJS = reboot.o |
STRING_OBJS = strncat.o \ |
strrchr.o \ |
strstr.o \ |
47,8 → 46,6 |
OBJS = $(GNU_S_OBJS) $(GNU_C_OBJS) $(COMMON_OBJS) $(STRING_OBJS) $(IO_OBJS) $(STD_OBJS) |
vpath %.c string stdlib ioformat |
#VPATH := $(subst $(space),:,$(SRCDIRS) $(MOSTLY_SRCDIRS)) |
75,10 → 72,10 |
allclean : |
echo # XTN Library dependencies > deps |
$(RM) $(BASE)\lib\libhc.a |
$(RM) $(LIB_PATH)libhc.a |
deps: $(COMMON_OBJS:.o=.c) $(patsubst %.o,string/%.c,$(STRING_OBJS)) $(patsubst %.o,ioformat/%.c,$(IO_OBJS)) $(patsubst %.o,stdlib/%.c,$(STD_OBJS)) |
$(CC) -E $(C_OPT) $(VMINCL) -M $(COMMON_OBJS:.o=.c) \ |
$(CC) -E $(C_OPT) -M $(COMMON_OBJS:.o=.c) \ |
$(patsubst %.o,string/%.c,$(STRING_OBJS)) \ |
$(patsubst %.o,ioformat/%.c,$(IO_OBJS)) \ |
$(patsubst %.o,stdlib/%.c,$(STD_OBJS)) > deps |
/shark/trunk/oslib/makefile |
---|
1,19 → 1,27 |
include config.mk |
all: |
make -C xlib all |
make -C libm all |
make -C libc all |
make -C kl all |
make -C libcons all |
make -C kl all |
install: |
make -C xlib install |
make -C libm install |
make -C libc install |
make -C kl install |
# make -C examples all |
make -C libcons install |
make -C kl install |
#make -C examples all |
clean: |
make -C xlib clean |
make -C libm clean |
make -C libc clean |
make -C kl clean |
# make -C examples clean |
make -C libcons clean |
make -C kl clean |
#make -C examples clean |
allclean: clean |
$(RMDIR) lib |
/shark/trunk/oslib/examples/biosdemo.c |
---|
29,13 → 29,57 |
#include <ll/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; |
72,9 → 116,22 |
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); |
#if 1 |
/* Put some pixels */ |
for (i = 0; i < 200; i++) { |
ir.h.ah = 0x0C; |
112,7 → 169,13 |
message("CX=%x\n",c); |
for (i = 0; i < 0x4F000; i++); |
#ifdef __VM86__ |
vm86_init(); |
vm86_init(); |
l1_int_bind(0x6d, emulate); |
/* |
l1_irq_bind(0x6d, emulate); |
*/ |
BIOSDemo(); |
#else |
XBIOSDemo(); |
/shark/trunk/oslib/examples/mbdemo.c |
---|
36,6 → 36,7 |
struct multiboot_info *mbi; |
DWORD lbase, hbase; |
DWORD lsize, hsize; |
int eXtender = 0; |
sp1 = get_SP(); |
cli(); |
54,6 → 55,12 |
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; |
60,7 → 67,7 |
hsize = mbi->mem_upper * 1024; |
message("Mem Lower: %lx %lu\n", lsize, lsize); |
message("Mem Upper: %lx %lu\n", hsize, hsize); |
if (mbi->flags & MB_INFO_USEGDT) { |
if (eXtender) { |
lbase = mbi->mem_lowbase; |
hbase = mbi->mem_upbase; |
} else { |
92,7 → 99,7 |
if (mbi->flags & MB_INFO_MEM_MAP) { |
message("\tMemory map provided\n"); |
} |
if (mbi->flags & MB_INFO_USEGDT) { |
if (eXtender) { |
message("\tLoaded through X\n"); |
} |
cli(); |
/shark/trunk/oslib/examples/vmdemo.c |
---|
24,6 → 24,9 |
#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[]) |
{ |
53,6 → 56,7 |
return 1; |
*/ |
l1_init(); |
a = 1 / 0; /* Test the exception handler... */ |
l1_end(); |
return 1; |
/shark/trunk/oslib/examples/makefile |
---|
10,7 → 10,7 |
all: mbdemo.xtn timetest.xtn eventdem.xtn vmdemo.xtn \ |
ctxswdem.xtn scheddem.xtn cpudemo.xtn biosdemo.xtn \ |
asdemo.xtn |
asdemo.xtn kerndem.xtn |
%.ftp: %.xtn |
ncftpput -u ll -p example thorin . $< |
26,6 → 26,10 |
# 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 --end-group -o $@ |
$(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/trunk/oslib/xlib/exc.s |
---|
33,10 → 33,8 |
ASMFILE(Exc) |
.globl SYMBOL_NAME(ll_irq_table) |
.globl SYMBOL_NAME(ll_exc_table) |
SYMBOL_NAME_LABEL(ll_irq_table) .space 64, 0 |
SYMBOL_NAME_LABEL(ll_exc_table) .space 64, 65 |
SYMBOL_NAME_LABEL(ll_irq_table) .space 1024, 0 |
.text |
48,6 → 46,7 |
/* 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) |
54,7 → 53,6 |
INT(4) |
INT(5) |
INT(6) |
INT(7) |
INT(8) |
INT(9) |
INT(10) |
63,60 → 61,254 |
INT(13) |
INT(14) |
INT(15) |
INT(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) |
#if 0 |
/* MPF... If we have an external FPU, it will generate |
* INT 13 instead of EXC 16... |
* We must remap it to EXC 16... |
*/ |
#if 1 |
SYMBOL_NAME_LABEL(h13_bis) |
/* Send EOI for 8086 coprocessor trick */ |
/* Send 0H on Coprocessor port 0F0H */ |
pushl %eax |
xorb %al, %al |
outb %al, $0x0F0 |
movb $0x020, %al |
outb %al, $0x0A0 |
outb %al, $0x020 |
popl %eax |
movl $16, %eax |
jmp ll_handler2 |
#else |
SYMBOL_NAME_LABEL(h13_bis) pushal |
/* Send EOI for 8086 coprocessor trick */ |
/* Send 0H on Coprocessor port 0F0H */ |
xorb %al,%al |
outb %al,$0x0F0 |
movb $0x020,%al |
outb %al,$0x0A0 |
outb %al,$0x020 |
pushl %ds |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
movw %ax,%ds |
movl $(MATH_EXC),%eax |
pushl %eax |
/* LL_ABORT OR EXC_HOOK?? */ |
/*THIS SURELY WRONG!!!! FIX IT!!!! Gerardo, help me!!! */ |
hlt |
/* call SYMBOL_NAME(ll_abort) */ |
addl $4,%esp |
popl %gs |
popl %fs |
popl %es |
popl %ss |
popl %ds |
popal |
ret |
#endif |
#endif |
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) |
INT(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! */ |
128,7 → 320,7 |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
pushl %gs |
/* But we first transfer to the _act_int */ |
/* the interrupt number which is required */ |
/* as second argument */ |
136,6 → 328,8 |
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) */ |
148,7 → 342,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... |
171,11 → 364,10 |
addl %ebx, %esp |
/* Save EBX for returning to our stack... */ |
movw %ss, %dx |
movw %ds, %bx |
movw %bx, %ss |
movw %ds, %cx |
movw %cx, %ss |
pushl %ebx |
pushl %edx |
#endif |
pushl %eax |
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx |
182,20 → 374,10 |
call *%ebx |
popl %ebx /* Store in EBX the Int number */ |
#if 0 |
popl %eax |
popl %ecx /* We must subtract it from ESP...*/ |
subl %ecx, %esp |
movw %ax, %ss |
#endif |
/* Send EOI to master & slave (if necessary) PIC */ |
movb $0x20,%al |
cmpl $0x08,%ebx |
jb eoi_master |
eoi_slave: movl $0xA0,%edx |
outb %al,%dx |
eoi_master: movl $0x20,%edx |
outb %al,%dx |
/* Resume the return value of _act_int */ |
/* & do the context switch if necessary! */ |
213,41 → 395,89 |
popl %ds |
popal |
iret |
EXC(0) |
EXC(1) |
EXC(2) |
EXC(3) |
EXC(4) |
EXC(5) |
EXC(6) |
EXC(8) |
EXC(9) |
EXC(10) |
EXC(11) |
EXC(12) |
EXC(13) |
EXC(14) |
EXC(15) |
EXC(16) |
/* 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 |
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 |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
movw %ax,%ds |
/* 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 |
call SYMBOL_NAME(ll_FPU_hook) |
popl %gs |
/* 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 |
254,22 → 484,48 |
popl %ds |
popal |
iret |
ll_handler_slave_pic: |
/* We do not know what is the DS value */ |
/* Then we save it & set it correctly */ |
ll_handler2: |
pushl %eax |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%ds |
movw %ax,%es |
/* Again, the following could be optimized... */ |
/* |
If the Exception raised in a different address space, we have to |
access the task stack from the kernel address space (the linear one...) |
*/ |
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 |
281,17 → 537,68 |
addl %ebx, %esp |
/* Save EBX for returning to our stack... */ |
movw %ss, %dx |
movw %ds, %bx |
movw %bx, %ss |
movw %ds, %cx |
movw %cx, %ss |
pushl %ebx |
pushl %edx |
pushl %eax |
call *SYMBOL_NAME(ll_exc_table)(, %eax, 4) |
addl $4,%esp |
/* Restore the stack pointer!!! */ |
popl %eax |
popl %ebx |
movw %ax, %ss |
subl %ebx, %esp |
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 |
/* 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/trunk/oslib/xlib/vm86.c |
---|
27,14 → 27,16 |
* 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/hw-func.h> |
#include <ll/i386/hw-instr.h> |
#include <ll/i386/x-dosmem.h> |
#include <ll/i386/cons.h> |
#include <ll/i386/error.h> |
FILE(VM - 86); |
FILE(VM-86); |
/* |
#define __LL_DEBUG__ |
42,10 → 44,12 |
#define __CHK_IO__ |
*/ |
#define VM86_STACK_SIZE 1024 |
#define VM86_STACK_SIZE 1024 |
extern DWORD ll_irq_table[256]; |
/* TSS optional section */ |
static BYTE vm86_stack0[VM86_STACK_SIZE]; |
static BYTE vm86_stack0[VM86_STACK_SIZE]; |
static struct { |
TSS t; |
55,76 → 59,77 |
static LIN_ADDR vm86_iretAddress; |
DWORD *GLOBesp; |
struct registers *global_regs; |
#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) */ |
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 |
0xcf, /* iret */ |
0xf4, /* hlt */ |
0 |
}; |
#endif |
#ifdef __LL_DEBUG__ |
static BYTE vm86_retAddr[] = { |
0x1e, /* push ds */ |
0xb8, 0x00, 0xb8, /* mov ax,0xb800 */ |
0x8e, 0xd8, /* mov ds,ax */ |
0xbf, 0x3e, 0x01, /* mov di,0x013c (316) */ |
0xb0, '%', /* mov ax,'%' */ |
0x88, 0x05, /* mov ds:[di],al */ |
0x1f, /* pop ds */ |
0xcd, 0x48 |
}; /* int 0x48 */ |
0x1e, /* push ds */ |
0xb8,0x00,0xb8, /* mov ax,0xb800 */ |
0x8e,0xd8, /* mov ds,ax */ |
0xbf,0x3e,0x01, /* mov di,0x013c (316) */ |
0xb0,'%', /* mov ax,'%' */ |
0x88,0x05, /* mov ds:[di],al */ |
0x1f, /* pop ds */ |
0xcd, 0x48}; /* int 0x48 */ |
#else |
static BYTE vm86_retAddr[] = { 0xcd, 0x48 }; /* int 48h */ |
static BYTE vm86_retAddr[] = {0xcd, 0x48}; /* int 48h */ |
#endif |
TSS *vm86_get_tss(void) |
{ |
return &(vm86_TSS.t); |
} |
/* This is the return point from V86 mode, called through int 0x48 |
* (see vm86-exc.s). We double check that this function is called in |
* the V86 TSS. Otherwise, Panic!!! |
*/ |
void vm86_return(DWORD * tos) |
void vm86_return(DWORD n, struct registers r) |
{ |
CONTEXT c = get_TR(); |
#ifdef __LL_DEBUG__ |
DWORD cs, eip; |
DWORD cs,eip; |
void *esp; |
DWORD a; |
/* message("Gotta code=%d [0 called from GPF/1 int 0x48]\n",code);*/ |
#endif |
if (c == X_VM86_TSS) { |
GLOBesp = tos; |
global_regs = &r; |
#ifdef __LL_DEBUG__ |
message("TSS CS=%x IP=%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
message("Switching to %x\n", vm86_TSS.t.back_link); |
a = (DWORD) (vm86_iretAddress); |
cs = (a & 0xFF000) >> 4; |
eip = (a & 0xFFF); |
message("Real-Mode Address is CS=%lx IP=%lx\nLinear=%lx\n", cs, |
eip, a); |
esp = (void *) (tos); |
message("Stack frame: %p %lx %lx\n", |
esp, vm86_TSS.t.esp0, vm86_TSS.t.esp); |
message("%lx ", lmempeekd(esp)); /* bp */ |
message("%lx ", lmempeekd(esp + 4)); /* eip */ |
message("%lx ", lmempeekd(esp + 8)); /* 0x0d */ |
message("%lx\n", lmempeekd(esp + 12)); /* error code */ |
message("TSS CS=%x IP=%lx\n",vm86_TSS.t.cs,vm86_TSS.t.eip); |
message("Switching to %x\n", vm86_TSS.t.back_link); |
a = (DWORD)(vm86_iretAddress); |
cs = (a & 0xFF000) >> 4; |
eip = (a & 0xFFF); |
message("Real-Mode Address is CS=%lx IP=%lx\nLinear=%lx\n",cs,eip,a); |
esp = /* (void *)(tos)*/ 0x69; |
message("Stack frame: %p %lx %lx\n", |
esp, vm86_TSS.t.esp0, vm86_TSS.t.esp); |
message("%lx ",lmempeekd(esp)); /* bp */ |
message("%lx ",lmempeekd(esp+4)); /* eip */ |
message("%lx ",lmempeekd(esp+8)); /* 0x0d */ |
message("%lx\n",lmempeekd(esp+12)); /* error code */ |
/* The error code is given by the selector causing shifted and or-ed with |
3 bits: [LDT/GDT | IDT | Ext/Int] |
If IDT == 1 -> the fault was provoked bu an interrupt (Internal if the |
132,17 → 137,18 |
Else the LDT/GDT bit shows if the selector belongs to the LDT (if 1) |
or GDT (if 0) |
*/ |
message("%lx ", lmempeekd(esp + 16)); /* EIP of faulting instr */ |
message("%lx ", lmempeekd(esp + 20)); /* CS of faulting instr */ |
message("%lx ", lmempeekd(esp + 24)); /* EFLAGS */ |
message("%lx\n", lmempeekd(esp + 28)); /* old ESP */ |
message("%lx ", lmempeekd(esp + 32)); /* old SS */ |
message("%lx ", lmempeekd(esp + 36)); /* old ES */ |
message("%lx ", lmempeekd(esp + 40)); /* old DS */ |
message("%lx\n", lmempeekd(esp + 44)); /* old FS */ |
message("%lx ",lmempeekd(esp+16)); /* EIP of faulting instr */ |
message("%lx ",lmempeekd(esp+20)); /* CS of faulting instr*/ |
message("%lx ",lmempeekd(esp+24)); /* EFLAGS*/ |
message("%lx\n",lmempeekd(esp+28)); /* old ESP*/ |
message("%lx ",lmempeekd(esp+32)); /* old SS*/ |
message("%lx ",lmempeekd(esp+36)); /* old ES*/ |
message("%lx ",lmempeekd(esp+40)); /* old DS*/ |
message("%lx\n",lmempeekd(esp+44)); /* old FS*/ |
#endif |
ll_context_load(vm86_TSS.t.back_link); |
ll_context_load(vm86_TSS.t.back_link); |
} |
message("Here?\n"); |
halt(); |
} |
151,27 → 157,27 |
/* Just a debugging function; it dumps the status of the TSS */ |
void vm86_dump_TSS(void) |
{ |
BYTE acc, gran; |
DWORD base, lim; |
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("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)); |
base,lim,(unsigned)(acc),(unsigned)(gran)); |
} |
void vm86_init(void) |
{ |
int register i; |
/* Init the DOS memory allocator */ |
// DOS_mem_init(); |
DOS_mem_init(); |
/* First of all, we need to setup a GDT entries to |
* allow vm86 task execution. We just need a free 386 TSS, which |
178,29 → 184,33 |
* 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); |
IDT_place(0x48, vm86_exc); |
GDT_place(X_VM86_TSS,(DWORD)(&vm86_TSS), |
sizeof(vm86_TSS),FREE_TSS386,GRAN_16); |
/* HACKME!!! */ |
// IDT_place(0x48,vm86_exc); |
l1_int_bind(0x48, vm86_return); |
// ll_irq_table[0x48] = (DWORD)vm86_return; |
/* 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_stack = DOS_alloc(VM86_STACK_SIZE*2); |
vm86_stack += VM86_STACK_SIZE/2; |
/* Create a location of DOS memory containing the |
* opcode sequence which will generate a GPF |
* We use the privileged instruction hlt to do it |
*/ |
vm86_iretAddress = DOS_alloc(sizeof(vm86_retAddr)); |
memcpy(vm86_iretAddress, vm86_retAddr, sizeof(vm86_retAddr)); |
memcpy(vm86_iretAddress,vm86_retAddr,sizeof(vm86_retAddr)); |
#ifdef __LL_DEBUG__ |
message("PM reentry linear address=%p\n", vm86_iretAddress); |
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)); |
lmemcpy(vm86_code,prova86,sizeof(prova86)); |
#endif |
/* Zero the PM/Ring[1,2] ss:esp; they're unused! */ |
vm86_TSS.t.esp1 = 0; |
220,55 → 230,51 |
* 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.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) |
int vm86_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s) |
{ |
DWORD vm86_tmpAddr; |
DWORD vm86_flags, vm86_cs, vm86_ip; |
DWORD vm86_flags, vm86_cs,vm86_ip; |
LIN_ADDR vm86_stackPtr; |
DWORD *IRQTable_entry; |
if (service < 0x10 || in == NULL) |
return -1; |
if (service < 0x10 || in == NULL) return -1; |
/* Setup the stack frame */ |
vm86_tmpAddr = (DWORD) (vm86_stack); |
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; |
+ VM86_STACK_SIZE - 6; |
/* Build an iret stack frame which returns to vm86_iretAddress */ |
vm86_tmpAddr = (DWORD) (vm86_iretAddress); |
vm86_tmpAddr = (DWORD)(vm86_iretAddress); |
vm86_cs = (vm86_tmpAddr & 0xFF000) >> 4; |
vm86_ip = (vm86_tmpAddr & 0xFFF); |
vm86_flags = 0; /* CPU_FLAG_VM | CPU_FLAG_IOPL; */ |
vm86_flags = 0; /* CPU_FLAG_VM | CPU_FLAG_IOPL; */ |
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); |
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); |
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]); |
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); |
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); |
(DWORD)vm86_TSS.t.cs,vm86_TSS.t.eip,&prova86); |
message("(DUMB CODE) Go...\n"); |
#endif |
vm86_TSS.t.back_link = ll_context_save(); |
279,44 → 285,41 |
#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; |
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; |
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.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; |
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; |
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:%hx IP:%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
#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... */ |
vm86_TSS.t.back_link = ll_context_save(); |
ll_context_load(X_VM86_TSS); |
#ifdef __LL_DEBUG__ |
#ifdef __LL_DEBUG__ |
message("I am back...\n"); |
message("TSS CS=%hx IP=%lx\n", vm86_TSS.t.cs, vm86_TSS.t.eip); |
{ |
char *xp = (char *) (vm86_iretAddress + 0xe); |
message("PM reentry linear address=%p\n", vm86_iretAddress); |
message("Executing code: %x ", (unsigned char) (*xp)); |
xp++; |
message("%x\n", (unsigned char) (*xp)); |
} |
{ char *xp = (char *)(vm86_iretAddress + 0xe); |
message("PM reentry linear address=%p\n", vm86_iretAddress); |
message("Executing code: %x ",(unsigned char)(*xp)); xp++; |
message("%x\n",(unsigned char)(*xp));} |
#endif |
/* Send back in the X_*REGS structure the value obtained with |
* the real-mode interrupt call |
332,26 → 335,26 |
out->x.cflag = (WORD)vm86_TSS.t.eflags; |
*/ |
#ifdef __LL_DEBUG__ |
message("%x\n", (WORD) * (GLOBesp)); |
message("%x\n", (WORD) * (GLOBesp + 1)); |
/*EDI*/ message("%x\n", (WORD) * (GLOBesp + 2)); |
/*ESI*/ message("%x\n", (WORD) * (GLOBesp + 3)); |
/*EBP*/ message("%x\n", (WORD) * (GLOBesp + 4)); |
/*ESP*/ message("%x\n", (WORD) * (GLOBesp + 5)); |
/*EBX*/ message("%x\n", (WORD) * (GLOBesp + 6)); |
/*EDX*/ |
#error Fix the following: use global_regs->xxx ??? |
message("%x\n", (WORD)*(GLOBesp)); |
message("%x\n", (WORD)*(GLOBesp+1)); /*EDI*/ |
message("%x\n", (WORD)*(GLOBesp+2)); /*ESI*/ |
message("%x\n", (WORD)*(GLOBesp+3)); /*EBP*/ |
message("%x\n", (WORD)*(GLOBesp+4)); /*ESP*/ |
message("%x\n", (WORD)*(GLOBesp+5)); /*EBX*/ |
message("%x\n", (WORD)*(GLOBesp+6)); /*EDX*/ |
#endif |
out->x.ax = (WORD) * (GLOBesp + 8); |
out->x.bx = (WORD) * (GLOBesp + 5); |
out->x.cx = (WORD) * (GLOBesp + 7); |
out->x.dx = (WORD) * (GLOBesp + 6); |
out->x.si = (WORD) * (GLOBesp + 2); |
out->x.di = (WORD) * (GLOBesp + 1); |
out->x.cflag = (WORD) * (GLOBesp); |
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; |
} |
if (s != NULL) { |
s->es = vm86_TSS.t.es; |
s->ds = vm86_TSS.t.ds; |
s->es = vm86_TSS.t.es; |
s->ds = vm86_TSS.t.ds; |
} |
#endif |
return 1; |
/shark/trunk/oslib/xlib/x0.s |
---|
153,23 → 153,27 |
*/ |
/* Test if GDT is usable */ |
movl %gs:0(%ebx),%ecx |
andl $0x080,%ecx |
jnz GDT_is_OK |
/* |
* Fix the X_RM_BACK_GATE with the address of halt() |
*/ |
/* Now I test if the check mechanism is OK... */ |
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 |
/shark/trunk/oslib/xlib/ctxsw.c |
---|
25,7 → 25,7 |
#include <ll/i386/hw-func.h> |
#include <ll/i386/tss-ctx.h> |
FILE(Context - Switch); |
FILE(Context-Switch); |
extern unsigned short int currCtx; |
#ifdef __VIRCSW__ |
37,31 → 37,31 |
void ll_context_to(CONTEXT c) |
{ |
#ifdef __VIRCSW__ |
currCtx = c; |
if (activeInt == 0) { |
currCtx = c; |
if (activeInt == 0) { |
context_load(c); |
} |
#else |
currCtx = c; |
context_load(c); |
} |
#else |
currCtx = c; |
context_load(c); |
#endif |
} |
CONTEXT ll_context_from(void) |
{ |
#ifdef __VIRCSW__ |
return currCtx; |
return currCtx; |
#else |
return context_save(); |
return context_save(); |
#endif |
} |
CONTEXT ll_context_save(void) |
{ |
return currCtx; |
return currCtx; |
} |
void ll_context_load(CONTEXT c) |
{ |
currCtx = c; |
context_load(c); |
currCtx = c; |
context_load(c); |
} |
/shark/trunk/oslib/xlib/ctx.s |
---|
25,8 → 25,6 |
#include <ll/i386/linkage.h> |
#include <ll/i386/defs.h> |
#include <ll/sys/ll/exc.h> |
.data |
ASMFILE(Context) |
/shark/trunk/oslib/xlib/xdosf.c |
---|
27,7 → 27,7 |
#include <ll/i386/x-dos.h> |
#include <ll/i386/x-dosmem.h> |
FILE(X - Dos - File); |
FILE(X-Dos-File); |
/* Basic DOS I/O Flag */ |
37,8 → 37,8 |
#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 */ |
#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... */ |
47,61 → 47,56 |
/* The Last DOS Error occurred! */ |
static unsigned _DOS_error = 0; |
#ifdef __NOH4__ |
int DOS_init(void) |
{ |
/* Init the DOS memory allocator */ |
DOS_mem_init(); |
/* Init the DOS memory allocator */ |
DOS_mem_init(); |
/* TODO: Add a check if we are run through X */ |
return 1; |
/* TODO: Add a check if we are run through X */ |
return 1; |
} |
#endif |
unsigned DOS_error(void) |
{ |
unsigned v = _DOS_error; |
_DOS_error = 0; |
return (v); |
return(v); |
} |
DOS_FILE *DOS_fopen(char *name, char *mode) |
DOS_FILE *DOS_fopen(char *name,char *mode) |
{ |
X_REGS16 ir, or; |
X_REGS16 ir,or; |
X_SREGS16 sr; |
DOS_FILE *f; |
register int i; |
#ifdef __DEBUG__ |
char xname[80]; |
#endif |
#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); |
if (i == DOS_MAXDESCR) return(NULL); |
/* Otherwise, lock the descriptor & remember the index */ |
f = &DOS_descr[i]; |
busy[i] = 1; |
f->index = i; |
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); |
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 |
*/ |
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') { |
} |
else if (mode[0] == 'w') { |
/* DOS Call: Intr 0x21 |
AH = 0x3C - Create a file |
AL = File attribute [0x20 = Standard,r/w,archive] |
*/ |
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; |
109,75 → 104,72 |
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 |
#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); |
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); |
DOS_free(f->n1,80); |
busy[i] = 0; |
_DOS_error = or.x.ax; |
return (NULL); |
return(NULL); |
} |
/* Allocate the DOS buffer for temporary I/O */ |
f->buf = DOS_alloc(DOS_BUFSIZE); |
return (f); |
return(f); |
} |
void DOS_fclose(DOS_FILE * f) |
void DOS_fclose(DOS_FILE *f) |
{ |
X_REGS16 ir, or; |
X_REGS16 ir,or; |
X_SREGS16 sr; |
if (f == NULL || busy[f->index] == 0) |
return; |
if (f == NULL || busy[f->index] == 0) return; |
/* DOS Call: Intr 0x21 |
AH = 0x3E - Close a file |
BX = File handle |
*/ |
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); |
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) |
DWORD DOS_fread(void *abuf,DWORD size,DWORD num,DOS_FILE *f) |
{ |
X_REGS16 ir, or; |
X_REGS16 ir,or; |
X_SREGS16 sr; |
DWORD count = size * num, now = 0, chunk; |
DWORD count = size*num,now = 0,chunk; |
BYTE done = 0; |
BYTE *buf = (BYTE *) (abuf); |
BYTE *buf = (BYTE *)(abuf); |
while (done == 0) { |
/* Fragment the read operation ... */ |
if (count > DOS_BUFSIZE) |
chunk = DOS_BUFSIZE; |
else |
chunk = count; |
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 |
*/ |
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); |
X_callBIOS(0x21,&ir,&or,&sr); |
/* If it was OK ... */ |
if (!(or.x.cflag)) { |
/* Copy data into application buffer */ |
187,47 → 179,44 |
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; |
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); |
return(now); |
} |
DWORD DOS_fwrite(void *abuf, DWORD size, DWORD num, DOS_FILE * f) |
DWORD DOS_fwrite(void *abuf,DWORD size,DWORD num,DOS_FILE *f) |
{ |
X_REGS16 ir, or; |
X_REGS16 ir,or; |
X_SREGS16 sr; |
DWORD count = size * num, now = 0, chunk; |
DWORD count = size*num,now = 0,chunk; |
BYTE done = 0; |
BYTE *buf = (BYTE *) (abuf); |
BYTE *buf = (BYTE *)(abuf); |
while (done == 0) { |
/* Fragment the write operation ... */ |
if (count > DOS_BUFSIZE) |
chunk = DOS_BUFSIZE; |
else |
chunk = count; |
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 |
*/ |
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); |
X_callBIOS(0x21,&ir,&or,&sr); |
/* If it was OK ... */ |
if (!(or.x.cflag)) { |
f->offset += or.x.ax; |
234,12 → 223,12 |
count -= or.x.ax; |
buf += or.x.ax; |
now += or.x.ax; |
if (now == size * num || or.x.ax != chunk) |
done = 1; |
if (now == size*num || or.x.ax != chunk) done = 1; |
} else { |
done = -1; |
_DOS_error = or.x.ax; |
} |
} |
return (now); |
return(now); |
} |
/shark/trunk/oslib/xlib/xinfo.c |
---|
26,7 → 26,7 |
#include <ll/i386/mb-info.h> |
#include <ll/i386/x-bios.h> |
FILE(X - Info); |
FILE(X-Info); |
/* |
The x_bios is stored in the low memory area and contains all the |
34,10 → 34,9 |
using a linear pointer, which is returned by the following call! |
*/ |
X_CALLBIOS *x_bios_address(void) |
X_CALLBIOS * x_bios_address(void) |
{ |
X_CALLBIOS *a = |
(X_CALLBIOS *) GDT_read(X_CALLBIOS_SEL, NULL, NULL, NULL); |
X_CALLBIOS *a = (X_CALLBIOS *)GDT_read(X_CALLBIOS_SEL,NULL,NULL,NULL); |
return (a); |
} |
46,30 → 45,32 |
WORD X_version(void) |
{ |
X_CALLBIOS *x_bios = x_bios_address(); |
return (x_bios->ver); |
return(x_bios->ver); |
} |
void X_meminfo(LIN_ADDR * b1, DWORD * s1, LIN_ADDR * b2, DWORD * s2) |
void X_meminfo(LIN_ADDR *b1,DWORD *s1,LIN_ADDR *b2,DWORD *s2) |
{ |
struct multiboot_info *mbi = mbi_address(); |
if (mbi->flags & MB_INFO_USEGDT) { |
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; |
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; |
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__ |
91,12 → 92,11 |
/* Alert if a wrong addressing is intercepted */ |
/* Used only for debug purposes */ |
void check_addr(void *addr, char *caller) |
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); |
if ((DWORD)(addr) < _stktop) { |
cprintf("CRISIS! Addr : %lx(%lx) Caller was %s\n",(DWORD)(addr),_stktop,caller); |
} |
} |
#endif |
/shark/trunk/oslib/xlib/xbios.c |
---|
26,12 → 26,12 |
#include <ll/i386/x-bios.h> |
#include <ll/i386/mem.h> |
FILE(X - BIOS); |
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) |
void X_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s) |
{ |
/* Assembler gate JMP instruction */ |
extern void _x_callBIOS(void); |
39,13 → 39,13 |
/* 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)); |
memcpy(&(xbc->ir),in,sizeof(X_REGS16)); |
memcpy(&(xbc->sr),s,sizeof(X_SREGS16)); |
/* Back to RM to execute the BIOS routine */ |
_x_callBIOS(); |
/* Get the return register values */ |
memcpy(out, &(xbc->or), sizeof(X_REGS16)); |
memcpy(s, &(xbc->sr), sizeof(X_SREGS16)); |
memcpy(out,&(xbc->or),sizeof(X_REGS16)); |
memcpy(s,&(xbc->sr),sizeof(X_SREGS16)); |
} |
/shark/trunk/oslib/xlib/x1.c |
---|
63,7 → 63,7 |
/* function __CHK to detect it! The compiler place it whenever */ |
/* it calls a function to detect overflow */ |
DWORD _stkbase; |
DWORD _stkbase; |
DWORD _stktop; |
/* This is some extra stuff we need to compile with argument */ |
72,7 → 72,11 |
typedef char *charp; |
charp _argv[100]; |
extern void main(int argc, char *argv[]); |
#ifndef MAIN |
#define MAIN main |
#endif |
extern void MAIN(int argc,char *argv[]); |
extern void bios_save(void); |
extern void bios_restore(void); |
83,93 → 87,54 |
} |
struct multiboot_info *mbi_address(void) |
struct multiboot_info * mbi_address(void) |
{ |
/* This is declared in [wc32/gnu]\x0.[asm/s] */ |
extern struct multiboot_info *mbi; |
/* This is declared in [wc32/gnu]\x0.[asm/s] */ |
extern struct multiboot_info *mbi; |
return (mbi); |
return (mbi); |
} |
#ifndef __NOH4__ |
void __kernel_init__(struct multiboot_info *m); |
void _startup(void) |
{ |
struct multiboot_info *mbi = mbi_address(); |
register int i = 0; |
struct multiboot_info *mbi = mbi_address(); |
char *cmdline = (char *)(mbi->cmdline); |
bios_save(); |
/* Call init 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",_argc); |
message("Argv[0] : %s / %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 |
__kernel_init__(mbi); |
bios_restore(); |
} |
#else |
void _startup(void) |
{ |
register int i = 0; |
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_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) { |
_argv[_argc] = &(cmdline[i]); |
while (cmdline[i] != ' ' && cmdline[i] != 0) i++; |
if (cmdline[i] == ' ') { |
cmdline[i] = 0; i++; _argc++; |
} |
} |
if (mbi->flags & MB_INFO_CMDLINE) { |
/* Build parameter list, up to 100 parms... */ |
while (cmdline[i] != 0) { |
_argv[_argc] = &(cmdline[i]); |
while (cmdline[i] != ' ' && cmdline[i] != 0) |
i++; |
if (cmdline[i] == ' ') { |
cmdline[i] = 0; |
i++; |
_argc++; |
} |
} |
_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() */ |
_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", _argc); |
message("Argv[0] : %s / %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]); |
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",_argc); |
message("Argv[0] : %s / %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(); |
MAIN(_argc,_argv); |
bios_restore(); |
} |
#endif |
/shark/trunk/oslib/xlib/fpu.c |
---|
1,4 → 1,3 |
/* Project: OSLib |
* Description: The OS Construction Kit |
* Date: 1.6.2000 |
27,6 → 26,7 |
#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> |
33,15 → 33,15 |
FILE(FPU); |
extern TSS TSS_table[]; |
extern TSS main_tss; |
BYTE LL_FPU_savearea[FPU_CONTEXT_SIZE]; /* Global FPU scratch SaveArea */ |
BYTE LL_FPU_savearea[FPU_CONTEXT_SIZE]; /* Global FPU scratch SaveArea */ |
#ifdef __FPU_DEBUG__ |
long int ndp_called = 0, ndp_switched = 0; |
long int ndp_called = 0,ndp_switched = 0; |
#endif |
/* FPU context management */ |
static CONTEXT LL_has_FPU = TSSMain; |
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. */ |
51,37 → 51,40 |
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 == TSSsel2index(get_TR())) |
return; |
#ifdef __FPU_DEBUG__ |
ndp_switched++; |
#endif |
#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(&(TSS_table[LL_has_FPU])); |
memcpy(TSS_table[LL_has_FPU].ctx_FPU,LL_FPU_savearea,FPU_CONTEXT_SIZE); |
#else |
save_fpu(LL_has_FPU); |
#endif |
LL_has_FPU = TSSsel2index(get_TR()); |
LL_has_FPU = base; |
#if 1 |
memcpy(LL_FPU_savearea, TSS_table[LL_has_FPU].ctx_FPU, |
FPU_CONTEXT_SIZE); |
memcpy(LL_FPU_savearea, base->ctx_FPU, FPU_CONTEXT_SIZE); |
LL_FPU_restore(); |
#else |
#else |
restore_fpu(&(TSS_table[LL_has_FPU])); |
#endif |
return; |
} |
CONTEXT LL_FPU_get_task(void) |
TSS *LL_FPU_get_task(void) |
{ |
return (LL_has_FPU); |
return(LL_has_FPU); |
} |
/shark/trunk/oslib/xlib/ccpu.c |
---|
25,46 → 25,50 |
#include <ll/i386/hw-arch.h> |
#include <ll/i386/mem.h> |
FILE(Cpu - C); |
FILE(Cpu-C); |
INLINE_OP void cpuid(DWORD a, DWORD * outa, DWORD * outb, DWORD * outc, |
DWORD * outd) |
INLINE_OP void cpuid(DWORD a, DWORD *outa, DWORD *outb, DWORD *outc, DWORD *outd) |
{ |
#ifdef __OLD_GNU__ |
__asm__ __volatile__(".byte 0x0F,0xA2" |
__asm__ __volatile__ (".byte 0x0F,0xA2" |
#else |
__asm__ __volatile__("cpuid" |
__asm__ __volatile__ ("cpuid" |
#endif |
:"=a"(*outa), |
"=b"(*outb), "=c"(*outc), "=d"(*outd):"a"(a)); |
: "=a" (*outa), |
"=b" (*outb), |
"=c" (*outc), |
"=d" (*outd) |
: "a" (a)); |
} |
void X86_get_CPU(struct ll_cpuInfo *p) |
{ |
DWORD tmp; |
DWORD tmp; |
memset(p, 0, sizeof(struct ll_cpuInfo)); |
if (X86_is386()) { |
p->X86_cpu = 3; |
return; |
} |
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)); |
memset(p, 0, sizeof(struct ll_cpuInfo)); |
if (X86_is386()) { |
p->X86_cpu = 3; |
return; |
} |
} else { |
p->X86_cpu = 4; |
if (X86_isCyrix()) { |
/* Err... Adjust IT!!!! */ |
p->X86_cpu = 11; |
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)); |
} |
} else { |
p->X86_cpu = 4; |
if (X86_isCyrix()) { |
/* Err... Adjust IT!!!! */ |
p->X86_cpu = 11; |
} |
/* Need tests for AMD and others... */ |
} |
/* Need tests for AMD and others... */ |
} |
} |
/shark/trunk/oslib/xlib/xdosm.c |
---|
26,7 → 26,7 |
#include <ll/i386/x-dosmem.h> |
#include <ll/i386/error.h> |
FILE(X - Dos - Memory); |
FILE(X-Dos-Memory); |
/* |
We do not use the standard K&R pointer based memory allocator! |
39,12 → 39,12 |
since DOS memory is only used for reflection related purposes |
*/ |
#define MAX_PARTITION 50 /* Max available partition */ |
#define MAX_PARTITION 50 /* Max available partition */ |
static struct { |
BYTE used; |
LIN_ADDR addr; |
DWORD size; |
BYTE used; |
LIN_ADDR addr; |
DWORD size; |
} mem_table[MAX_PARTITION]; |
static int inited = 0; |
53,28 → 53,26 |
{ |
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); |
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); |
} |
} |
void DOS_mem_init(void) |
__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; |
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; |
inited = 1; |
} |
} |
LIN_ADDR DOS_alloc(DWORD s) |
__attribute__ ((weak)) LIN_ADDR DOS_alloc(DWORD s) |
{ |
LIN_ADDR p = 0; |
int i = 0; |
81,31 → 79,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 != 0) { |
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); |
} |
int DOS_free(LIN_ADDR p, DWORD s) |
__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))) { |
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; |
if (mem_table[i].addr + mem_table[i].size == p) i1 = i; |
if (mem_table[i].addr == p + s) i2 = i; |
} |
i++; |
} |
112,20 → 107,19 |
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); |
} |
/shark/trunk/oslib/xlib/irq.c |
---|
22,10 → 22,11 |
/* 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 ICW1_M 0x020 /* Master PIC (8259) register settings */ |
#define ICW2_M 0x021 |
#define ICW3_M 0x021 |
#define ICW4_M 0x021 |
33,7 → 34,7 |
#define OCW2_M 0x020 |
#define OCW3_M 0x020 |
#define ICW1_S 0x0A0 /* Slave PIC register setting */ |
#define ICW1_S 0x0A0 /* Slave PIC register setting */ |
#define ICW2_S 0x0A1 |
#define ICW3_S 0x0A1 |
#define ICW4_S 0x0A1 |
41,66 → 42,61 |
#define OCW2_S 0x0A0 |
#define OCW3_S 0x0A0 |
#define PIC1_BASE 0x040 /* Interrupt base for each PIC in HARTIK 3.0 */ |
#define PIC2_BASE 0x070 |
#define EOI 0x020 /* End Of Interrupt code for PIC! */ |
#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 = 0xFE; |
BYTE ll_PIC_slave_mask = 0xFE; |
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_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); |
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_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); |
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) |
{ |
/* Cannot mask timer interrupt! */ |
if (irqno == 0) |
return; |
/* Interrupt is on master PIC */ |
if (irqno < 8) { |
bit_on(ll_PIC_master_mask, irqno); |
outp(0x21, ll_PIC_master_mask); |
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); |
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) */ |
/* 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); |
bit_on(ll_PIC_master_mask,2); |
outp(0x21,ll_PIC_master_mask); |
} |
} |
} |
107,22 → 103,19 |
void irq_unmask(WORD irqno) |
{ |
/* It is a nonsense to unmask the timer interrupt */ |
if (irqno == 0) |
return; |
/* Interrupt is on master PIC */ |
if (irqno < 8) { |
bit_off(ll_PIC_master_mask, irqno); |
outp(0x21, ll_PIC_master_mask); |
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); |
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); |
bit_off(ll_PIC_master_mask,2); |
outp(0x21,ll_PIC_master_mask); |
} |
} |
} |
/shark/trunk/oslib/xlib/xinit.c |
---|
31,240 → 31,118 |
#include <ll/i386/tss-ctx.h> |
#include <ll/i386/hw-arch.h> |
FILE(X - Init); |
FILE(X-Init); |
extern DWORD ll_irq_table[16]; |
extern DWORD ll_exc_table[16]; |
extern DWORD ll_irq_table[256]; |
#ifdef __VIRCSW__ |
int activeInt = 0; |
#endif |
/* Architecture definition */ |
LL_ARCH ll_arch; |
/* These are declared in llCx32b.C */ |
TSS TSS_table[TSSMax]; |
WORD TSS_control[TSSMax]; |
BYTE ll_FPU_stdctx[FPU_CONTEXT_SIZE]; |
/* The following stuff is in llCxA.Asm/S */ |
/* Assembly external routines! */ |
/* Setup the TR register of the 80386, to initialize context switch */ |
extern void init_TR(WORD v); |
TSS main_tss; |
/* ll hardware interrupt hooks */ |
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 h7(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 h13_bis(void); |
extern void h14(void); |
extern void h15(void); |
/* Architecture definition */ |
LL_ARCH ll_arch; |
/* ll hardware exception hooks */ |
/* In llCtx1.Asm/s */ |
extern void exc0(void); |
extern void exc1(void); |
extern void exc2(void); |
extern void exc3(void); |
extern void exc4(void); |
extern void exc5(void); |
extern void exc6(void); |
extern void exc7(void); |
extern void exc8(void); |
extern void exc9(void); |
extern void exc10(void); |
extern void exc11(void); |
extern void exc12(void); |
extern void exc13(void); |
extern void exc14(void); |
extern void exc15(void); |
extern void exc16(void); |
/* The following stuff is in llCxA.Asm/S */ |
static void dummyfun(int i) |
{ |
cputs("Unhandled Exc or Int occured!!!\n"); |
/* |
#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); |
*/ |
halt(); |
#endif |
halt(); |
} |
void l1_exc_bind(int i, void (*f) (int n)) |
void l1_int_bind(int i, void *f) |
{ |
ll_exc_table[i] = (DWORD) f; |
ll_irq_table[i] = (DWORD)f; |
} |
void l1_irq_bind(int i, void (*f) (int n)) |
{ |
ll_irq_table[i] = (DWORD) f; |
} |
void *l1_init(void) |
{ |
register int i; |
struct ll_cpuInfo cpuInfo; |
LIN_ADDR b; |
extern BYTE X86_fpu; |
TSS dummy_tss; /* Very dirty, but we need it, in order to |
get an initial value for the FPU |
context... |
*/ |
/* First of all, init the exc and irq tables... */ |
for (i = 0; i < 16; i++) { |
ll_irq_table[i] = (DWORD) dummyfun; |
ll_exc_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); |
/* TODO! Need to map featuresXXX & Signature onto ll_arch! */ |
/* TODO! Need to check for CPU bugs!! */ |
register int i; |
struct ll_cpuInfo cpuInfo; |
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); |
/* 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); |
#endif /* __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); |
#endif /* __LL_DEBUG__ */ |
IDT_init(); |
/* Insert the Exceptions handler into IDT */ |
IDT_place(0x00, exc0); |
IDT_place(0x01, exc1); |
IDT_place(0x02, exc2); |
IDT_place(0x03, exc3); |
IDT_place(0x04, exc4); |
IDT_place(0x05, exc5); |
IDT_place(0x06, exc6); |
IDT_place(0x07, exc7); |
IDT_place(0x08, exc8); |
IDT_place(0x09, exc9); |
IDT_place(0x0A, exc10); |
IDT_place(0x0B, exc11); |
IDT_place(0x0C, exc12); |
IDT_place(0x0D, exc13); |
IDT_place(0x0E, exc14); |
IDT_place(0x0F, exc15); |
IDT_place(0x10, exc16); |
/* Insert HW timer handler into IDT */ |
/* Now it is done in event.c |
IDT_place(0x40,ll_timer); |
*/ |
IDT_place(0x41, h1); |
IDT_place(0x42, h2); |
IDT_place(0x43, h3); |
IDT_place(0x44, h4); |
IDT_place(0x45, h5); |
IDT_place(0x46, h6); |
IDT_place(0x47, h7); |
IDT_place(0x70, h8); |
IDT_place(0x71, h9); |
IDT_place(0x72, h10); |
IDT_place(0x73, h11); |
IDT_place(0x74, h12); |
#if 0 |
/* If FPU is on-chip IRQ #13 is free to use */ |
/* Else IRQ #13 vectors the coprocessor errors */ |
if (check_fpu()) |
ll_arch.x86.capabilities |= LL_X86_INTERNAL_FPU; |
#ifdef __LL_DEBUG__ |
message("Check FPU : %s\n", |
ll_arch.x86. |
capabilities & LL_X86_INTERNAL_FPU ? "Internal" : "External"); |
#endif |
if (ll_arch.x86.capabilities & LL_X86_INTERNAL_FPU) { |
/* Install the generic handler */ |
IDT_place(0x75, h13); |
} else { |
/* Install the external FPU error handler */ |
IDT_place(0x75, h13_bis); |
irq_unmask(13); |
} |
#else |
IDT_place(0x75, h13); |
#endif |
IDT_place(0x76, h14); |
IDT_place(0x77, h15); |
/* 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); |
} |
/* Set the TR initial value */ |
init_TR(TSSindex2sel(TSSMain)); |
/* 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(); |
#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(); |
/* Init PIC controllers & unmask timer */ |
PIC_init(); |
return mbi_address(); |
/* 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 */ |
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); |
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 */ |
} |
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/trunk/oslib/xlib/makefile |
---|
2,11 → 2,11 |
# Makefile for GNU MAKE & GCC 2.8.0 |
ifndef BASE |
BASE = ../.. |
BASEDOS = ..\.. |
BASE = .. |
BASEDOS = .. |
endif |
include $(BASE)/config/config.mk |
include $(BASE)/config.mk |
C_OPT += -D__VIRCSW__ |
ASM_OPT += -D__VIRCSW__ |
19,16 → 19,17 |
xsystab.o \ |
xconv.o \ |
xdosf.o \ |
xdosm.o \ |
ccpu.o \ |
fpu.o \ |
irq.o \ |
ctxsw.o \ |
xinit.o \ |
idtinit.o \ |
vm86.o \ |
xbios.o |
#xdosm.o |
GNU_S_OBJS = xsys0.o cpu2.o exc.o ctx.o vm86-exc.o mem.o |
GNU_S_OBJS = xsys0.o cpu2.o exc.o ctx.o mem.o |
#GNU_C_OBJS = gnucomp.o |
OBJS = $(GNU_S_OBJS) $(GNU_C_OBJS) $(COMMON_OBJS) |
57,11 → 58,11 |
allclean : |
echo # XTN Library dependencies > deps |
$(RM) $(BASE)\lib\libhx.a |
$(RM) $(BASE)\lib\x0.o |
$(RM) $(LIB_PATH)libhx.a |
$(RM) $(LIB_PATH)x0.o |
deps: $(COMMON_OBJS:.o=.c) $(patsubst %.o,gnu/%.c,$(GNU_C_OBJS)) |
$(CC) $(C_OPT) $(VMINCL) -M $(COMMON_OBJS:.o=.c) $(patsubst %.o,gnu/%.c,$(GNU_C_OBJS)) > deps |
$(CC) $(C_OPT) -M $(COMMON_OBJS:.o=.c) $(patsubst %.o,gnu/%.c,$(GNU_C_OBJS)) > deps |
# |
# The library!! |
/shark/trunk/oslib/xlib/xconv.c |
---|
24,7 → 24,7 |
#include <ll/i386/hw-func.h> |
#include <ll/i386/mem.h> |
FILE(X - Conv); |
FILE(X-Conv); |
/* Conversion between PM address space & phisical address space */ |
/* If we do not support paging we need to relocate the .ELF executable */ |
54,9 → 54,9 |
} |
*/ |
LIN_ADDR addr2linear(unsigned short seg, unsigned long offset) |
LIN_ADDR addr2linear(unsigned short seg,unsigned long offset) |
{ |
LIN_ADDR flatbase; |
flatbase = (LIN_ADDR) GDT_read(seg, NULL, NULL, NULL); |
return (flatbase + offset); |
flatbase = (LIN_ADDR)GDT_read(seg,NULL,NULL,NULL); |
return(flatbase + offset); |
} |
/shark/trunk/oslib/xlib/xsystab.c |
---|
23,9 → 23,8 |
#include <ll/i386/cons.h> |
#include <ll/i386/mem.h> |
#include <ll/math.h> |
FILE(X - SysTab); |
FILE(X-SysTab); |
extern GATE IDT[256]; |
33,9 → 32,9 |
/* 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)) |
void IDT_place(BYTE num,void (*handler)(void)) |
{ |
DWORD offset = (DWORD) (handler); |
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; |
49,7 → 48,7 |
/* 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) |
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] */ |
60,8 → 59,8 |
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)); |
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 */ |
69,14 → 68,14 |
/* a descriptor rather than reading,modifying & updating with */ |
/* this high level functions! */ |
DWORD GDT_read(WORD sel, DWORD * lim, BYTE * acc, BYTE * gran) |
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 offset = appl2linear(&x);*/ |
DWORD base; |
memcpy(&x, GDT_base + sel, sizeof(union gdt_entry)); |
memcpy(&x,GDT_base+sel,sizeof(union gdt_entry)); |
base = x.d.base_hi; |
base <<= 8; |
base |= x.d.base_med; |
87,9 → 86,7 |
*lim <<= 16; |
*lim |= x.d.lim_lo; |
} |
if (acc != NULL) |
*acc = x.d.access; |
if (gran != NULL) |
*gran = x.d.gran & 0xF0; |
return (base); |
if (acc != NULL) *acc = x.d.access; |
if (gran != NULL) *gran = x.d.gran & 0xF0; |
return(base); |
} |