#include "clib.h"
#include "globals.h"
#include "i386.h"
#include "phmem.h"
#include "paging.h"
#include "systab.h"
#include "sched.h"
#include "excpt.h"
#include "irq.h"
#include "kmalloc.h"
#include "vm86.h"
#include "debugg.h"
#ifndef NDEBUG
bool debug_verbose = false;
bool debug_trace = false;
bool debug_flag = false;
#endif
stub_stat_t stub_stat;
#define SHOW_CR4(b) DEBUG_VERBOSE(#b" %d ", _cr4.##b);
void start_kernel();
/*
* questa e` la prima procedura chiamata da crt0.asm situazione :
*
* ds,ss,es = KERNEL_DS fs,gs=0 cs=KERNEL_CS
* esp = stack dello stub, poco meno di 1K
*
* la paginazione e` gia` attivata [e con lo stub 0.6 le tabelle sono
* nella memoria video!]
*
* cr0 : per 386 -> PG/PE
* per 486 -> PG/AM/WP/PE
* per 586 -> PG/AM/WP/NE/PE
*
* se c'e` la FPU MP = 1, comunque EM e` sempre a 0
*
* cr4 : per 386/486dx2 -> nada
* per 486dx4+ -> vengono abilitati VME/PVI/DE/PSE/PGE se disponibili
*
*
*
* gli interrupt sono disabilitati, il PIC e` stato riprogrammato,
* l'IRQ0 e` l'int 0xf0, IRQ 8 = int 0xf8, uso l'auto EOI
*
* TR = task temporaneo
* ldt = 0
* GDT = gdt dello stub loader, per la V0.6 i descrittori sono 10
* IDT = nulla
*/
int start(void)
{
int i;
#ifndef NDEBUG
if (stub_stat.flags & 1) {
debug_verbose = 1;
debug_trace = 1;
memset((void*)0xB8000, 0, 50*80*2); /* clrscr */
}
#endif
DEBUG_VERBOSE("CPU %d vendor %s feature %xh FPU %d CR4 %xh\n",
_cpu_family, _cpu_vendor, _cpu_feature, _fpu_family, _cr4);
SHOW_CR4(vme);
SHOW_CR4(pvi);
SHOW_CR4(tsd);
SHOW_CR4(de);
SHOW_CR4(pse);
SHOW_CR4(pae);
SHOW_CR4(mce);
SHOW_CR4(pge);
SHOW_CR4(pce);
DEBUG_VERBOSE("\nkernel phisical addr %xh, virtual addr %xh\n",
stub_stat.kernel_base, (u32)&end_texts & 0xFFFF0000);
i = (int)&end_bsss & 0x3FFFFF;
DEBUG_VERBOSE("kernel pages %xh\n", i shr 12);
/*
* inizializza il gestore delle pagine di memoria
*
*/
ph_memory_setup(stub_stat.kernel_base + i,
stub_stat.kernel_pages - (i shr 12));
/*
* alloca spazio per una nuova GDT e IDT, entrambe da 256 descrittori.
* la GDT viene riempita coi valori della vecchia GDT
*/
systab_setup();
/*
* inizializza per scheduler
*/
sched_setup();
/*
* ok, ora ho sufficienti procedure per creare il vero task del kernel
*/
/*
* crea i task ausiliari per le eccezioni, e quello
* del kernel.
*/
base_tasks_setup();
tss_kernel.esp = (u32)valloc(2) + 8192;
tss_kernel.eip = &start_kernel;
jmp_task(tss_kernel.tss_sel);
DEBUG_FATAL("unexpected return");
return 1;
}
v86_tss *v86;
tss_t *t;
extern void v86_startup;
void start_kernel()
{
int i;
tss_t *dbg;
/*
* ora posso inizializzare anche kmalloc
*/
kmalloc_startup(16); // 16 pagine = 64K
/*
* imposta i descrittori degli irq.
* NB: Irq0 = int 0xf0, irq 8=int0xf8
*/
irq_setup();
asm_sti;
dbg = alloc_tss(NULL, "KDebugger");
dbg->cs = KERNEL_CS;
dbg->ds = dbg->ss = dbg->es = KERNEL_DS;
dbg->esp = (u32)valloc(4) + 4*4096;
dbg->eip = debug_start;
dbg->handler = debug_handler;
dbg->eflags = 0;
dbg->cr3 = tss_kernel.cr3;
jmp_task(dbg->tss_sel);
DEBUG_TRACE;
exit(0);
#if 0
v86 = alloc_v86_task("DOSV86");
v86->tss.cs = stub_stat.dos_mem_ptr shr 16;
v86->tss.eip = 0;
v86->tss.ss = v86->tss.ds = v86->tss.es = v86->tss.cs;
v86->tss.gs = stub_stat.prefixseg;
v86->tss.esp = 0xfffc;
v86->tss.ss0 = KERNEL_DS;
v86->tss.esp0 = alloc_free_page() + 4096;
map_memory(&v86->tss, v86->tss.esp0-4096, v86->tss.esp0-4096, 1, pfWritable);
// v86->tss.eflags |= (1 shl 12)+(1 shl 13);
memset(v86->iobitmap, 0, 128);
// v86->iobitmap[4] |= 1;
memset(v86->intbitmap, 0, 32);
v86->intbitmap[2] |= (1 shl 5);
// v86->tss.cr3 = tss_kernel.cr3;
map_memory(&v86->tss, (addr_t)0xB8000, (addr_t)0xB8000, 8, pfWritable + pfUser);
// memcpy((char*)&v86_startup+4, stub_stat.cmd_line, 40);
write_to_task(&v86->tss, (addr_t)(v86->tss.cs*16L), &v86_startup, 500);
// memset((addr_t)0xB8000, 0x20, 0x2000);
kprintf("DOS MEM: %x, CS:IP %x:%x\n\n", stub_stat.dos_mem_ptr,
v86->tss.cs,v86->tss.eip);
DEBUG_TRACE
jmp_task(v86->tss.tss_sel);
DEBUG_TRACE
exit(0);
#endif
}