-BUILD_NUM = 2243
+BUILD_NUM = 2263
POP_GPR
add rsp, 8*2
- xchg bx, bx
+ ;xchg bx, bx
iretq
[extern Proc_Scheduler]
typedef Uint64 tPAddr;
typedef Uint64 tVAddr;
-//typedef unsigned int size_t;
typedef Uint64 size_t;
typedef volatile int tSpinlock;
#define IS_LOCKED(lockptr) (!!(*(tSpinlock*)lockptr))
#define LOCK(lockptr) do {int v=1;\
while(v)\
- __asm__ __volatile__("lock xchgl %%eax, (%%rdi)":"=a"(v):"a"(1),"D"(lockptr));\
+ __asm__ __volatile__("lock xchgl %0, (%2)":"=r"(v):"r"(1),"r"(lockptr));\
}while(0)
-#define RELEASE(lockptr) __asm__ __volatile__("lock andl $0, (%%rdi)"::"D"(lockptr));
+#define RELEASE(lockptr) __asm__ __volatile__("lock andl $0, (%0)"::"r"(lockptr));
#define HALT() __asm__ __volatile__ ("hlt")
// Systemcall Registers
* 9000 00000000 - 9800 00000000 43 8 TiB Module Space
* 9800 00000000 - 9A00 00000000 41 2 TiB Kernel VFS
* A000 00000000 - B000 00000000 44 16 TiB Kernel Stacks
- * D000 00000000 - E000 00000000 44 16 TiB Hardware Mappings
- * E000 00000000 - E080 00000000 39 512 GiB Per-Process Data
- * E080 00000000 - E100 00000000 39 512 GiB Kernel Supplied User Code
+ * C000 00000000 - D000 00000000 44 16 TiB Hardware Mappings
+ * D000 00000000 - D080 00000000 39 512 GiB Per-Process Data
+ * D080 00000000 - D100 00000000 39 512 GiB Kernel Supplied User Code
+ * E000 00000000 - E400 00000000 42 4 TiB Physical Page Reference Counts (2**40 = 2**52 bytes)
+ * FD00 00000000 - FD80 00000000 39 512 GiB Local APIC
* FE00 00000000 - FE80 00000000 39 512 GiB Fractal Mapping (PML4 510)
* FE80 00000000 - FF00 00000000 39 512 GiB Temp Fractal Mapping
*/
#define MM_USER_MAX 0x00008FFF##FFFFF000
//#define KERNEL_BASE 0xFFF8000##00000000
#define MM_KHEAP_BASE (KERNEL_BASE|(0x8000##80000000))
-#define MM_KHEAP_MAX (KERNEL_BASE|(0x8001##00000000))
+#define MM_KHEAP_MAX (KERNEL_BASE|(0x9000##00000000))
#define MM_MODULE_MIN (KERNEL_BASE|(0x9000##00000000))
#define MM_MODULE_MAX (KERNEL_BASE|(0x9800##00000000))
#define MM_KERNEL_VFS (KERNEL_BASE|(0x9800##00000000))
#define MM_KSTACK_BASE (KERNEL_BASE|(0xA000##00000000))
-#define MM_KSTACK_TOP (KERNEL_BASE|(0xC000##00000000))
+#define MM_KSTACK_TOP (KERNEL_BASE|(0xB000##00000000))
-#define MM_HWMAP_BASE (KERNEL_BASE|(0xD000##00000000))
-#define MM_HWMAP_TOP (KERNEL_BASE|(0xE000##00000000))
-#define MM_PPD_BASE (KERNEL_BASE|(0xE000##00000000))
+#define MM_HWMAP_BASE (KERNEL_BASE|(0xC000##00000000))
+#define MM_HWMAP_TOP (KERNEL_BASE|(0xD000##00000000))
+#define MM_PPD_BASE (KERNEL_BASE|(0xD000##00000000))
#define MM_PPD_CFG MM_PPD_BASE
-#define MM_PPD_VFS (KERNEL_BASE|(0xE008##00000000))
-#define MM_USER_CODE (KERNEL_BASE|(0xE080##00000000))
+#define MM_PPD_VFS (KERNEL_BASE|(0xD008##00000000))
+#define MM_USER_CODE (KERNEL_BASE|(0xD080##00000000))
+#define MM_PAGE_COUNTS (KERNEL_BASE|(0xE000##00000000))
#define MM_LOCALAPIC (KERNEL_BASE|(0xFD00##00000000))
#define MM_FRACTAL_BASE (KERNEL_BASE|(0xFE00##00000000))
* Acess2 x86_64 Project
*/
#include <acess.h>
+#include <mboot.h>
// === IMPORTS ===
extern void Desctab_Init(void);
extern void MM_InitVirt(void);
+extern void Heap_Install(void);
+extern void Threads_Init(void);
+//extern void Time_Setup(void);
+extern void System_Init(char *Commandline);
+
+extern void MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
// === PROTOTYPES ===
// === GLOBALS ==
+char *gsBootCmdLine = NULL;
// === CODE ===
void kmain(Uint MbMagic, void *MbInfoPtr)
{
- *(Uint16*)(0xB8000) = 0x1F00|'A';
+ tMBoot_Info *mbInfo;
Desctab_Init();
- *(Uint16*)(0xB8000) = 0x1F00|'B';
MM_InitVirt();
- *(Uint16*)(0xB8000) = 0x1F00|'B';
+ *(Uint16*)(0xB8000) = 0x1F00|'C';
+
+ switch(MbMagic)
+ {
+ // Multiboot 1
+ case MULTIBOOT_MAGIC:
+ // Adjust Multiboot structure address
+ mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
+ gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
+
+ MM_InitPhys_Multiboot( mbInfo ); // Set up physical memory manager
+ break;
+ default:
+ Panic("Multiboot magic invalid %08x, expected %08x\n",
+ MbMagic, MULTIBOOT_MAGIC);
+ return ;
+ }
+
+ *(Uint16*)(0xB8000) = 0x1F00|'D';
+ Heap_Install();
+
+ *(Uint16*)(0xB8000) = 0x1F00|'E';
+ Log_Log("Arch", "Starting threading...");
+ Threads_Init();
+
+ //Time_Setup();
+ *(Uint16*)(0xB8000) = 0x1F00|'F';
+
+ Log_Log("Arch", "Starting VFS...");
+ // Load Virtual Filesystem
+ VFS_Init();
+
+ *(Uint16*)(0xB8000) = 0x1F00|'G';
+
+ // Pass on to Independent Loader
+ Log_Log("Arch", "Starting system");
+ System_Init(gsBootCmdLine);
+ // Sleep forever (sleeping beauty)
for(;;)
- __asm__ __volatile__ ("hlt");
+ Threads_Sleep();
}
void Arch_LoadBootModules(void)
*/
#include <acess.h>
#include <mboot.h>
-//#include <mm_phys.h>
+#include <mm_virt.h>
enum eMMPhys_Ranges
{
NUM_MM_PHYS_RANGES
};
+// === IMPORTS ===
+extern void gKernelEnd;
+
// === GLOBALS ===
tSpinlock glPhysicalPages;
Uint64 *gaSuperBitmap; // 1 bit = 64 Pages
-Uint64 *gaPrimaryBitmap; // 1 bit = 64 Pages
-Uint32 *gaiPageReferences; // Reference Counts
+Uint32 *gaiPageReferences = (void*)MM_PAGE_COUNTS; // Reference Counts
tPAddr giFirstFreePage; // First possibly free page
Uint64 giPhysRangeFree[NUM_MM_PHYS_RANGES]; // Number of free pages in each range
Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES]; // First free page in each range
Uint64 giMaxPhysPage = 0; // Maximum Physical page
// === CODE ===
-void MM_InitPhys(tMBoot_Info *MBoot)
+void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
{
tMBoot_MMapEnt *mmapStart;
tMBoot_MMapEnt *ent;
Uint64 maxAddr = 0;
+ int numPages;
+
+ Log("MM_InitPhys_Multiboot: (MBoot=%p)", MBoot);
// Scan the physical memory map
+ // Looking for the top of physical memory
mmapStart = (void *)( KERNEL_BASE | MBoot->MMapAddr );
+ Log(" MM_InitPhys_Multiboot: mmapStart = %p", mmapStart);
ent = mmapStart;
while( (Uint)ent < (Uint)mmapStart + MBoot->MMapLength )
{
// Adjust for the size of the entry
ent->Size += 4;
+ Log(" MM_InitPhys_Multiboot: ent={Type:%i,Base:0x%x,Length:%x",
+ ent->Type, ent->Base, ent->Length);
// If entry is RAM and is above `maxAddr`, change `maxAddr`
if(ent->Type == 1 && ent->Base + ent->Length > maxAddr)
maxAddr = ent->Base + ent->Length;
+
// Go to next entry
ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size );
}
+ // Did we find a valid end?
if(maxAddr == 0) {
+ // No, darn, let's just use the HighMem hack
giMaxPhysPage = (MBoot->HighMem >> 2) + 256; // HighMem is a kByte value
}
else {
+ // Goodie, goodie gumdrops
giMaxPhysPage = maxAddr >> 12;
}
+ Log(" MM_InitPhys_Multiboot: giMaxPhysPage = 0x%x", giMaxPhysPage);
+
+ // Find a contigous section of memory to hold it in
+ // - Starting from the end of the kernel
+ // - We also need a region for the super bitmap
+ numPages = (giMaxPhysPage + 7) * sizeof(*gaiPageReferences);
+ numPages = (numPages + 0xFFF) >> 12;
+ Log(" MM_InitPhys_Multiboot: numPages = %i", numPages);
+ if(maxAddr == 0)
+ {
+ // Ok, naieve allocation, just put it after the kernel
+ tVAddr vaddr = MM_PAGE_COUNTS;
+ tPAddr paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
+ while(numPages --)
+ {
+ MM_Map(vaddr, paddr);
+ vaddr += 0x1000;
+ paddr += 0x1000;
+ }
+ // Allocate the super bitmap
+ gaSuperBitmap = (void*) MM_MapHWPages(
+ paddr,
+ ((giMaxPhysPage+64*8-1)/(64*8) + 0xFFF) >> 12
+ );
+ }
+ // Scan for a nice range
+ else
+ {
+
+ }
+
+ // Fill the bitmaps
+ // - initialise to one, then clear the avaliable areas
+ memset(gaSuperBitmap, -1, (giMaxPhysPage+64*8-1)/(64*8));
+ memset(gaiPageReferences, -1, giMaxPhysPage*sizeof(*gaiPageReferences));
+ // - Clear all Type=1 areas
+ for(
+ ent = mmapStart;
+ (Uint)ent < (Uint)mmapStart + MBoot->MMapLength;
+ ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size )
+ )
+ {
+ // Check if the type is RAM
+ if(ent->Type != 1) continue;
+ // Clear the range
+ memset(
+ &gaiPageReferences[ ent->Base >> 12 ],
+ 0,
+ (ent->Size>>12)*sizeof(*gaiPageReferences)
+ );
+ }
}
/**
int rangeID;
int nFree = 0, i;
+ Log("MM_AllocPhysRange: (Num=%i,Bits=%i)", Num, Bits);
+
if( Bits <= 0 ) // Speedup for the common case
rangeID = MM_PHYS_MAX;
else if( Bits > 32 )
else
rangeID = MM_PHYS_16BIT;
+ Log(" MM_AllocPhysRange: rangeID = %i", rangeID);
+
LOCK(&glPhysicalPages);
+ Log(" MM_AllocPhysRange: i has lock");
// Check if the range actually has any free pages
while(giPhysRangeFree[rangeID] == 0 && rangeID)
rangeID --;
+ Log(" MM_AllocPhysRange: rangeID = %i", rangeID);
+
// What the? Oh, man. No free pages
if(giPhysRangeFree[rangeID] == 0) {
RELEASE(&glPhysicalPages);
// TODO: Page out
// ATM. Just Warning
+ Warning(" MM_AllocPhysRange: Out of free pages");
Log_Warning("Arch",
"Out of memory (unable to fulfil request for %i pages), zero remaining",
Num
// until a free range is found)
nFree = 1;
addr = giPhysRangeLast[ rangeID ];
+ // TODO
RELEASE(&glPhysicalPages);
// TODO: Page out
// ATM. Just Warning
);
return 0;
}
+ Log(" MM_AllocPhysRange: nFree = %i, addr = 0x%08x", nFree, addr);
// Mark pages as allocated
addr -= Num;
for( i = 0; i < Num; i++ )
{
gaiPageReferences[addr] = 1;
- gaPrimaryBitmap[addr>>6] |= 1 << (addr & 63);
- if( gaPrimaryBitmap[addr>>6] == -1 )
- gaSuperBitmap[addr>>12] |= 1 << ((addr >> 6) & 64);
if(addr >> 32) rangeID = MM_PHYS_MAX;
else if(addr >> 24) rangeID = MM_PHYS_32BIT;
else if(addr >> 0) rangeID = MM_PHYS_16BIT;
giPhysRangeFree[ rangeID ] --;
}
+ // Fill super bitmap
+ Num += addr & (64-1);
+ addr &= ~(64-1);
+ Num = (Num + (64-1)) & ~(64-1);
+ for( i = 0; i < Num/64; i++ )
+ {
+ int j, bFull = 1;
+ for( j = 0; j < 64; j ++ ) {
+ if( gaiPageReferences[addr+i*64+j] ) {
+ bFull = 0;
+ break;
+ }
+ }
+ if( bFull )
+ gaSuperBitmap[addr>>12] |= 1 << ((addr >> 6) & 64);
+ }
RELEASE(&glPhysicalPages);
- return addr;
+ return addr << 12;
}
/**
*/
void MM_RefPhys(tPAddr PAddr)
{
+ int bIsFull, j;
if( PAddr >> 12 > giMaxPhysPage ) return ;
gaiPageReferences[ PAddr >> 12 ] ++;
- gaPrimaryBitmap[PAddr >> 18] |= 1 << ((PAddr>>12) & 63);
- if( gaPrimaryBitmap[PAddr >> 18] == -1 )
+ bIsFull = 1;
+ for( j = 0; j < 64; j++ ) {
+ if( gaiPageReferences[ PAddr >> 12 ] == 0 ) {
+ bIsFull = 0;
+ break;
+ }
+ }
+ if( bIsFull )
gaSuperBitmap[PAddr >> 24] |= 1 << ((PAddr >> 18) & 64);
}
gaiPageReferences[ PAddr >> 12 ] --;
if( gaiPageReferences[ PAddr >> 12 ] )
{
- gaPrimaryBitmap[PAddr >> 18] &= ~(1 << ((PAddr >> 12) & 63));
gaSuperBitmap[PAddr >> 24] &= ~(1 << ((PAddr >> 18) & 64));
}
}
{
tPAddr ret;
+ Log("MM_Allocate: (VAddr=%x)", VAddr);
+ Log("MM_Allocate: MM_AllocPhys()");
ret = MM_AllocPhys();
+ Log("MM_Allocate: ret = %x", ret);
if(!ret) return 0;
if( !MM_Map(VAddr, ret) )
{
+ Warning("MM_Allocate: Unable to map", ret);
MM_DerefPhys(ret);
return 0;
}
[section .text]
[global start]
start:
+ mov [gMultibootMagic - KERNEL_BASE], eax
+ mov [gMultibootPtr - KERNEL_BASE], ebx
+
; Check for Long Mode support
mov eax, 0x80000000
cpuid
[global gGDT]
gGDT:
dd 0,0
- dd 0x00000000, 0x00209800 ; 0x08: 64-bit Code
- dd 0x00000000, 0x00009000 ; 0x10: 64-bit Data
- dd 0x00000000, 0x00209800 ; 0x18: 64-bit User Code
- dd 0x00000000, 0x00209000 ; 0x20: 64-bit User Data
- dd 0x00000000, 0x00209800 ; 0x38: 32-bit User Code
- dd 0x00000000, 0x00209000 ; 0x30: 32-bit User Data
+ dd 0x00000000, 0x00209A00 ; 0x08: 64-bit Code
+ dd 0x00000000, 0x00009200 ; 0x10: 64-bit Data
+ dd 0x00000000, 0x0020FA00 ; 0x18: 64-bit User Code
+ dd 0x00000000, 0x0000F200 ; 0x20: 64-bit User Data
+ dd 0x00000000, 0x0040FA00 ; 0x38: 32-bit User Code
+ dd 0x00000000, 0x0040F200 ; 0x30: 32-bit User Data
times MAX_CPUS dd 0, 0, 0, 0 ; 0x38+16*n: TSS 0
gGDTPtr:
dw $-gGDT-1
dd gGDT-KERNEL_BASE
dd 0
+[global gMultibootPtr]
+[global gMultibootMagic]
+gMultibootMagic:
+ dd 0
+gMultibootPtr:
+ dd 0
[section .padata]
[global gInitialPML4]
; Acess2 x86_64 Port
;
[bits 64]
+KERNEL_BASE equ 0xFFFF800000000000
[extern kmain]
+[extern gMultibootPtr]
+[extern gMultibootMagic]
+
[section .text]
[global start64]
start64:
mov rsp, gInitialKernelStack
; Call main
+ mov edi, [gMultibootMagic - KERNEL_BASE]
+ mov esi, [gMultibootPtr - KERNEL_BASE]
call kmain
cli
void Heap_Dump();
// === GLOBALS ===
- int glHeap;
+tSpinlock glHeap;
void *gHeapStart;
void *gHeapEnd;