Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 39 → Rev 40

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