#include <threads.h>
-// === TYPES ===
-#if USE_MP
-typedef struct sCPU
-{
- Uint8 APICID;
- Uint8 State; // 0: Unavaliable, 1: Idle, 2: Active
- Uint16 Resvd;
- tThread *Current;
-} tCPU;
-#endif
-
+// === TYPES ==
typedef struct sTSS {
Uint32 Link;
Uint32 ESP0, SS0;
// === GLOBALS ===
char *gsBootCmdLine = NULL;
struct {
+ Uint32 PBase;
void *Base;
Uint Size;
char *ArgString;
// Multiboot 2
case MULTIBOOT2_MAGIC:
- Warning("Multiboot 2 Not yet supported");
+ Panic("Multiboot 2 not yet supported");
//MM_InstallMBoot2( MbInfo ); // Set up physical memory manager
return 0;
break;
Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
- // Always HW map the module data
+ gaArch_BootModules[i].PBase = mods[i].Start;
gaArch_BootModules[i].Size = mods[i].End - mods[i].Start;
-
+
+ // Always HW map the module data
ofs = mods[i].Start&0xFFF;
gaArch_BootModules[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
(gaArch_BootModules[i].Size+ofs+0xFFF) / 0x1000
void Arch_LoadBootModules(void)
{
- int i;
+ int i, j, numPages;
for( i = 0; i < giArch_NumBootModules; i ++ )
{
- Log_Debug("Arch", "Module %i: %p - %p 0x%x",
- i, gaArch_BootModules[i].ArgString,
- gaArch_BootModules[i].Base, gaArch_BootModules[i].Size
- );
Log_Log("Arch", "Loading '%s'", gaArch_BootModules[i].ArgString);
if( !Module_LoadMem( gaArch_BootModules[i].Base, gaArch_BootModules[i].Size, gaArch_BootModules[i].ArgString ) )
Log_Warning("Arch", "Unable to load module");
}
- MM_UnmapHWPages(
- (tVAddr)gaArch_BootModules[i].Base,
- (gaArch_BootModules[i].Size + ((Uint)gaArch_BootModules[i].Base&0xFFF) + 0xFFF) >> 12
- );
+ // Unmap and free
+ numPages = (gaArch_BootModules[i].Size + ((Uint)gaArch_BootModules[i].Base&0xFFF) + 0xFFF) >> 12;
+ MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].Base, numPages );
+
+ for( j = 0; j < numPages; j++ )
+ MM_DerefPhys( gaArch_BootModules[i].PBase + (j << 12) );
if( (tVAddr) gaArch_BootModules[i].ArgString > MAX_ARGSTR_POS )
MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].ArgString, 2 );
tMBoot_MMapEnt *ent;
// --- Find largest address
- Log("MBoot->MMapAddr = %08x", MBoot->MMapAddr);
MBoot->MMapAddr |= KERNEL_BASE;
ent = (void *)( MBoot->MMapAddr );
while( (Uint)ent < MBoot->MMapAddr + MBoot->MMapLength )
{
- Log(" ent->Size = %08x", ent->Size);
// Adjust for size
ent->Size += 4;
// Mark Multiboot's pages as taken
// - Structure
MM_RefPhys( (Uint)MBoot - KERNEL_BASE );
- Log("MBoot->ModuleCount = %i", MBoot->ModuleCount);
// - Module List
for(i = (MBoot->ModuleCount*sizeof(tMBoot_Module)+0xFFF)>12; i--; )
MM_RefPhys( MBoot->Modules + (i << 12) );
// - Modules
- Log("MBoot->Modules = %p", MBoot->Modules);
mods = (void*)(MBoot->Modules + KERNEL_BASE);
for(i = 0; i < MBoot->ModuleCount; i++)
{
// Unset kernel on the User Text pages
for( i = ((tVAddr)&_UsertextEnd-(tVAddr)&_UsertextBase+0xFFF)/4096; i--; ) {
- Log("MM_SetFlags( 0x%08x, 0, MM_PFLAG_KERNEL)", (tVAddr)&_UsertextBase + i*4096);
MM_SetFlags( (tVAddr)&_UsertextBase + i*4096, 0, MM_PFLAG_KERNEL );
}
}
[global GetCPUNum]
GetCPUNum:
xor eax, eax
- ltr ax
+ str ax
sub ax, 0x30
shr ax, 3 ; ax /= 8
ret
// Base is 1193182
#define TIMER_DIVISOR 11931 //~100Hz
+// === TYPES ===
+#if USE_MP
+typedef struct sCPU
+{
+ Uint8 APICID;
+ Uint8 State; // 0: Unavaliable, 1: Idle, 2: Active
+ Uint16 Resvd;
+ tThread *Current;
+} tCPU;
+#endif
+
// === IMPORTS ===
extern tGDT gGDT[];
extern tIDT gIDT[];
+extern void APWait(void); // 16-bit AP pause code
extern void APStartup(void); // 16-bit AP startup code
extern Uint GetEIP(void); // start.asm
extern int GetCPUNum(void); // start.asm
tAPIC *gpMP_LocalAPIC = NULL;
Uint8 gaAPIC_to_CPU[256] = {0};
tCPU gaCPUs[MAX_CPUS];
+ int giProc_BootProcessorID = 0;
#else
tThread *gCurrentThread = NULL;
#endif
Log("\t.ExtendedTableChecksum = 0x%02x", mptable->ExtendedTableChecksum);
Log("}");
- gpMP_LocalAPIC = (void*)MM_MapHWPage(mptable->LocalAPICMemMap, 1);
+ gpMP_LocalAPIC = (void*)MM_MapHWPages(mptable->LocalAPICMemMap, 1);
ents = mptable->Entries;
giNumCPUs = 0;
gaCPUs[giNumCPUs].State = 0;
giNumCPUs ++;
- // Send IPI
- if( !(ents->Proc.CPUFlags & 2) )
- {
- MP_StartAP( giNumCPUs-1 );
+ // Set BSP Variable
+ if( ents->Proc.CPUFlags & 2 ) {
+ giProc_BootProcessorID = giNumCPUs-1;
}
break;
entSize = 8;
Log("%i: Bus", i);
Log("\t.ID = %i", ents->Bus.ID);
- Log("\t.TypeString = '%6c'", ents->Bus.TypeString);
+ Log("\t.TypeString = '%6C'", ents->Bus.TypeString);
break;
case 2: // I/O APIC
entSize = 8;
Warning("Too many CPUs detected (%i), only using %i of them", giNumCPUs, MAX_CPUS);
giNumCPUs = MAX_CPUS;
}
-
- while( giNumInitingCPUs )
- MM_FinishVirtualInit();
-
- Panic("Uh oh... MP Table Parsing is unimplemented\n");
}
else {
Log("No MP Table was found, assuming uniprocessor\n");
#endif
// Initialise Double Fault TSS
- /*
- gGDT[5].LimitLow = sizeof(tTSS);
- gGDT[5].LimitHi = 0;
- gGDT[5].Access = 0x89; // Type
- gGDT[5].Flags = 0x4;
- */
gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF;
gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16;
gGDT[5].BaseHi = (Uint)&gDoubleFault_TSS >> 24;
- Log_Debug("Proc", "gIDT[8] = {OffsetLo:%04x, CS:%04x, Flags:%04x, OffsetHi:%04x}",
- gIDT[8].OffsetLo, gIDT[8].CS, gIDT[8].Flags, gIDT[8].OffsetHi);
+ // Set double fault IDT to use the new TSS
gIDT[8].OffsetLo = 0;
gIDT[8].CS = 5<<3;
gIDT[8].Flags = 0x8500;
gIDT[8].OffsetHi = 0;
- Log_Debug("Proc", "gIDT[8] = {OffsetLo:%04x, CS:%04x, Flags:%04x, OffsetHi:%04x}",
- gIDT[8].OffsetLo, gIDT[8].CS, gIDT[8].Flags, gIDT[8].OffsetHi);
-
- //__asm__ __volatile__ ("xchg %bx, %bx");
#if USE_MP
// Initialise Normal TSS(s)
gGDT[6+pos].BaseHi = ((Uint)(&gTSSs[pos])) >> 24;
#if USE_MP
}
- for(pos=0;pos<giNumCPUs;pos++) {
- #endif
- __asm__ __volatile__ ("ltr %%ax"::"a"(0x30+pos*8));
- #if USE_MP
+
+ // Start APs
+ for( pos = 0; pos < giNumCPUs; pos ++ )
+ {
+ gaCPUs[pos].Current = NULL;
+ if( pos != giProc_BootProcessorID ) {
+ Log("Starting AP %i, (APIC %i)\n", pos, gaCPUs[pos].APICID);
+ MP_StartAP( pos );
+ }
}
+
+ Log("Waiting for APs to come up\n");
+ while( giNumInitingCPUs ) __asm__ __volatile__ ("hlt");
+ MM_FinishVirtualInit();
+ //Panic("Uh oh... MP Table Parsing is unimplemented\n");
#endif
+ // Load the BSP's TSS
+ __asm__ __volatile__ ("ltr %%ax"::"a"(0x30));
+
#if USE_MP
gaCPUs[0].Current = &gThreadZero;
#else
void MP_StartAP(int CPU)
{
Log("Starting AP %i (APIC %i)", CPU, gaCPUs[CPU].APICID);
+
// Set location of AP startup code and mark for a warm restart
- *(Uint16*)(KERNEL_BASE|0x467) = (Uint)&APStartup - (KERNEL_BASE|0xFFFF0);
+ *(Uint16*)(KERNEL_BASE|0x467) = (Uint)&APWait - (KERNEL_BASE|0xFFFF0);
*(Uint16*)(KERNEL_BASE|0x469) = 0xFFFF;
outb(0x70, 0x0F); outb(0x71, 0x0A); // Warm Reset
- MP_SendIPI(gaCPUs[CPU].APICID, 0, 5);
+ MP_SendIPI(gaCPUs[CPU].APICID, 0, 5); // Init IPI
+
+ // Delay
+ inb(0x80); inb(0x80); inb(0x80); inb(0x80);
+
+ // Create a far jump
+ *(Uint8*)(KERNEL_BASE|0x11000) = 0xEA; // Far JMP
+ *(Uint16*)(KERNEL_BASE|0x11001) = (Uint)&APStartup - (KERNEL_BASE|0xFFFF0); // IP
+ *(Uint16*)(KERNEL_BASE|0x11003) = 0xFFFF; // CS
+ // Send a Startup-IPI to make the CPU execute at 0x11000 (which we
+ // just filled)
+ MP_SendIPI(gaCPUs[CPU].APICID, 0x11, 6); // StartupIPI
+
giNumInitingCPUs ++;
}
+/**
+ * \brief Send an Inter-Processor Interrupt
+ * \param APICID Processor's Local APIC ID
+ * \param Vector Argument of some kind
+ * \param DeliveryMode Type of signal?
+ */
void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode)
{
Uint32 addr = (Uint)gpMP_LocalAPIC + 0x300;
val = (Uint)APICID << 24;
Log("*%p = 0x%08x", addr+0x10, val);
*(Uint32*)(addr+0x10) = val;
+
// Low (and send)
val = ((DeliveryMode & 7) << 8) | (Vector & 0xFF);
Log("*%p = 0x%08x", addr, val);
[extern gaCPUs]
[extern giNumInitingCPUs]
lGDTPtr: ; Local GDT Pointer
- dw 2*8-1
+ dw 3*8-1
dd gGDT-KERNEL_BASE
[bits 16]
+[global APWait]
+APWait:
+ ;xchg bx, bx
+.hlt:
+ ;hlt
+ jmp .hlt
[global APStartup]
APStartup:
- xchg bx, bx ; MAGIC BREAK!
+ ;xchg bx, bx ; MAGIC BREAK!
mov ax, 0xFFFF
mov ds, ax
lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
[bits 32]
.ProtectedMode:
+ ; Load segment registers
+ mov ax, 0x10
+ mov ss, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
; Start Paging
mov eax, gaInitPageDir - KERNEL_BASE
mov cr3, eax
lidt [gIDTPtr]
mov eax, [gpMP_LocalAPIC]
- mov DWORD [eax], 0
xor ecx, ecx
- mov cl, BYTE [eax+0x10]
+ mov cl, BYTE [eax+0x20]
; CL is now local APIC ID
mov cl, BYTE [gaAPIC_to_CPU+ecx]
; CL is now the CPU ID
mov BYTE [gaCPUs+ecx*8+1], 1
; Decrement the remaining CPU count
dec DWORD [giNumInitingCPUs]
+ xchg bx, bx ; MAGIC BREAK
+ ; Set TSS
+ shl cx, 3
+ add cx, 0x30
+ ltr cx
; CPU is now marked as initialised
sti
+ xchg bx, bx ; MAGIC BREAK
.hlt:
hlt
jmp .hlt
#endif
// Is shift pressed
- // - Darn ugly hacks !(!x) means (bool)x
- if( !(!gbKB_ShiftState) ^ gbKB_CapsState)
+ // - Darn ugly hacks !!x means (bool)x
+ if( !!gbKB_ShiftState ^ gbKB_CapsState)
{
switch(ch)
{
{\r
Uint16 vendor;\r
int i;\r
- Uint32 addr;\r
\r
vendor = PCI_CfgReadWord(bus, slot, fcn, 0x0|0);\r
if(vendor == 0xFFFF) // Invalid Device\r
info->oc = PCI_CfgReadWord(bus, slot, fcn, 0x8|2);\r
\r
// Load Config Bytes\r
- addr = 0x80000000 | ((Uint)bus<<16) | ((Uint)slot<<11) | ((Uint)fcn<<8);\r
for(i=0;i<256/4;i++)\r
{\r
- #if 0\r
- outd(0xCF8, addr);\r
- info->ConfigCache[i] = ind(0xCFC);\r
- addr += 4;\r
- #else\r
info->ConfigCache[i] = PCI_CfgReadDWord(bus, slot, fcn, i*4);\r
- #endif\r
}\r
\r
//#if LIST_DEVICES\r
*/
void Log_Int_PrintMessage(tLogEntry *Entry)
{
+ //LOCK( &glLogOutput );
LogF("%s%014lli%s [%+8s] %s\x1B[0m\n",
csaLevelColours[Entry->Level],
Entry->Time,
Entry->Ident,
Entry->Data
);
+ //RELEASE( &glLogOutput );
}
/**
--- /dev/null
+Makefile.i386.cfg
\ No newline at end of file
--- /dev/null
+Makefile.i386.cfg
\ No newline at end of file
EOF;
+$gInputFile = $argv[1];
+$gOutputFile = $argv[2];
+$gDepFile = ($argc > 3 ? $argv[3] : false);
+
+$gDependencies = array();
+
$lines = file($argv[1]);
$lDepth = 0;
if(preg_match('/^File\s+"([^"]+)"\s+"([^"]+)"$/', $line, $matches))
{
$lStack[$lDepth][1][] = array($matches[1], $matches[2]);
+ $gDependencies[] = $matches[2];
continue;
}
echo "ERROR: $line\n";
}
function hd($fp)
+{
+ //return "0x".str_pad( dechex(ord(fgetc($fp))), 8, "0", STR_PAD_LEFT );
+ $val = unpack("I", fread($fp, 4));
+ //print_r($val); exit -1;
+ return "0x".dechex($val[1]);
+}
+
+function hd8($fp)
{
return "0x".str_pad( dechex(ord(fgetc($fp))), 2, "0", STR_PAD_LEFT );
}
}
$size = filesize($item[1]);
- $gOutput .= "Uint8 {$prefix}_{$i}_data[] = {\n";
$fp = fopen($item[1], "rb");
- for( $j = 0; $j + 16 < $size; $j += 16 )
+ if(0)
{
+ $gOutput .= "Uint32 {$prefix}_{$i}_data[] = {\n";
+ for( $j = 0; $j + 16 < $size; $j += 16 )
+ {
+ $gOutput .= "\t";
+ $gOutput .= hd($fp).",".hd($fp).",";
+ $gOutput .= hd($fp).",".hd($fp).",\n";
+ }
$gOutput .= "\t";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",";
- $gOutput .= hd($fp).",".hd($fp).",\n";
+ for( ; $j+3 < $size; $j += 4 )
+ {
+ if( $j & 15 ) $gOutput .= ",";
+ $gOutput .= hd($fp);
+ }
+ if($j < $size) {
+ $tmp = "";
+ while($j ++ < $size)
+ $tmp .= fgetc($fp);
+ $tmp .= "\0\0\0";
+ $tmp = unpack("I", $tmp);
+ $gOutput .= "0x".dechex($tmp[1]);
+ }
}
- $gOutput .= "\t";
- for( ; $j < $size; $j ++ )
+ else
{
- if( $j & 15 ) $gOutput .= ",";
- $gOutput .= hd($fp);
+ $gOutput .= "Uint8 {$prefix}_{$i}_data[] = {\n";
+ for( $j = 0; $j + 16 < $size; $j += 16 ) {
+ $gOutput .= "\t";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",";
+ $gOutput .= hd8($fp).",".hd8($fp).",\n";
+ }
+ $gOutput .= "\t";
+ for( ; $j < $size; $j ++ ) {
+ if( $j & 15 ) $gOutput .= ",";
+ $gOutput .= hd8($fp);
+ }
}
fclose($fp);
$gOutput .= "\n};\n";
};
EOF;
-$fp = fopen($argv[2], "w");
+$fp = fopen($gOutputFile, "w");
fputs($fp, $gOutput);
fclose($fp);
+
+
+if($gDepFile !== false)
+{
+ $fp = fopen($gDepFile, "w");
+ $line = $gOutputFile.":\t".implode(" ", $gDependencies);
+ fputs($fp, $line);
+ fclose($fp);
+}
+
?>
-include ../Makefile.tpl
files.c: GenerateInitRD.php files.lst
- php GenerateInitRD.php files.lst files.c
+ php GenerateInitRD.php files.lst files.c files.c.d
+
+-include files.c.d
all: $(BIN)
clean:
- $(RM) $(BIN) $(BIN).dsm $(KOBJ) $(OBJ) $(DEPFILES)
+ $(RM) $(BIN) $(BIN).dsm $(KOBJ) $(OBJ) $(DEPFILES) $(EXTRA)
install: $(BIN)
ifneq ($(BUILDTYPE),static)
int USB_IOCtl(tVFS_Node *Node, int Id, void *Data);
// === GLOBALS ===
-MODULE_DEFINE(0, VERSION, USB, USB_Install, NULL, NULL);
+MODULE_DEFINE(0, VERSION, USB_Core, USB_Install, NULL, NULL);
tDevFS_Driver gUSB_DrvInfo = {
NULL, "usb", {
.NumACLs = 1,