TempleOSCDV3.12.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:46:35 +02:00
1 parent ed64d7e3b8
commit 046e83368d
62 files changed
+2371 -2298

No files matched your search

+1 -1
View File
@@ -94,7 +94,7 @@ U0 WinDerivedValsUpdate(CTask *task=NULL)
{//Those things calculated from other variables.
if (!task) task=Fs;
//Assert: This is called with TASKLf_TASK_LOCK set
//Assert: This is called with TASKf_TASK_LOCK set
PUSHFD
CLI
task->win_width =task->win_right-task->win_left+1;
+6 -11
View File
@@ -334,13 +334,6 @@ U0 Dr(CTask *task=NULL)
"RIP:%016X\n",task->rip;
}
U0 OverRideSingleUserSwap()
{//You never need this, probably.
Bool old_single=SingleUser(OFF);
Yield;
SingleUser(old_single);
}
U8 *SysGetStr2(I64)
{
U8 buf[512];
@@ -458,7 +451,7 @@ U0 G(U8 *ip=INVALID_PTR,CTask *task=NULL)
">B2;\t\t\t//Clear all break points\n"
">G2;\t\t\t//Clear all break points and Go\n\n"
"After resuming, <CTRL-ALT-t> changes focus task\n"
"After resuming, <CTRL-ALT-f> flushes screen VGA cache\n";
"After resuming, <CTRL-ALT-v> flushes screen VGA cache\n";
else {
LBtr(&task->task_flags,TASKf_DISABLE_BPTS);
LBtr(&task->rflags,RFLAGf_TRAP);//No single step
@@ -534,12 +527,12 @@ U0 DbgHelp()
">G2;\t\t\t\t//B2;VGAFlush;WinFocus;G;\n"
">Exit;\t\t\t\t//Exit (kill) task.\n\n"
"After resuming, <CTRL-ALT-t> changes focus task.\n"
"After resuming, <CTRL-ALT-f> flushes screen VGA cache.\n\n";
"After resuming, <CTRL-ALT-v> flushes screen VGA cache.\n\n";
}
U0 Dbg2()
{
Bool old_win_inhibit,old_waiting_msg;
Bool old_win_inhibit,old_waiting_msg,old_single;
I64 i,old_getstr2;
U8 buf[200];
if (IsRaw) {
@@ -555,8 +548,10 @@ U0 Dbg2()
kbd.scan_code=0;
old_getstr2=fp_getstr2;
fp_getstr2=&SysGetStr2;
old_single=SingleUser(OFF);
while (!mouse.install_attempts)
OverRideSingleUserSwap;
Yield;
SingleUser(old_single);
UserTaskCont;
fp_getstr2=old_getstr2;
Fs->win_inhibit=old_win_inhibit;
+5 -3
View File
@@ -67,6 +67,8 @@ U0 SysGlblsInit()
U0 SysGrInit()
{
text.font=sys_font_8x8;
text.aux_font=MAlloc(256*FONT_HEIGHT);
MemCpy(text.aux_font,text.font,256*FONT_HEIGHT);
if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
text.cols=80;
text.rows=25;
@@ -133,7 +135,7 @@ U0 KernelMain()
{//Continued from $LK,"Kernel",A="FF:::/Kernel/KStart.CPP,I32 &Kernel"$
OutU8(0x61,InU8(0x61)&~3); //Snd(0);
adam_task=Fs;
HeapsInit;
BlkPoolsInit;
LBts(&sys_run_level,RLf_FULL_HEAP);
SysGlblsInit;
Mem32DevInit;
@@ -148,7 +150,7 @@ U0 KernelMain()
TaskDerivedValsUpdate;
SysDefinesLoad;
BSPInit;
Core0Init;
IntInit1;
//Before this point use $LK,"Snd",A="MN:Snd"$() and $LK,"BusyWait",A="MN:BusyWait"$()
@@ -184,7 +186,7 @@ U0 KernelMain()
#exe {
if (!kernel_cfg->opts[CFG_NO_MP])
StreamPrint("\"MultiCore Start\\n\\n\";"
"BSPStartMP;"
"Core0StartMP;"
"LBts(&sys_run_level,RLf_MP);");
};
+3
View File
@@ -8,6 +8,7 @@ import Bool DocUnlock(CDoc *doc);
import Bool Ed(U8 *link_st,I64 edf_dof_flags=0);
extern U0 AdamErr(U8 *fmt,...);
extern U0 AdamLog(U8 *fmt,...);
extern I64 BIOSTotalMem();
extern I64 BlkDevAdd(CBlkDev *bd,Bool one_drv,Bool make_free);
extern U0 BlkDevChk(CBlkDev *bd);
extern Bool BlkDevLock(CBlkDev *bd);
@@ -47,6 +48,8 @@ extern I64 FileWrite(U8 *filename,U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0);
extern I64 FlushMsgs(CTask *task=NULL);
extern I64 GetChar(I64 *scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE);
extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE);
extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,
CTask *task=NULL,CBlkPool *bp);
extern Bool ISO1FileFind(CDrv *dv,I64 cur_dir_cluster,U8 *name,
CDirEntry *_result,I64 fuf_flags=0);
extern Bool ISODrvInit(CDrv *dv,I64 blk);
+1 -3
View File
@@ -45,9 +45,7 @@ IRQ_TIMER:: //I_TIMER
MOV EAX,U32 LAPIC_EOI
MOV U32 [RAX],0
JMP @@25
@@20: CALL &IntCore0TimerHandler //Only Core 0 calls this.
@@25: JMP I32 RESTORE_RSI_TASK
//************************************
INT_FAULT::
@@ -80,7 +78,7 @@ INT_FAULT::
PUSH U64 CTask.fault_num[RSI]
MOV RSI,CTask.rsi[RSI]
CALL &Fault2 //See $LK,"Fault2",A="FF:::/Kernel/KDbg.CPP,Fault2"$
JMP I32 RESTORE_FS_TASK_WITH_KEY_CHECK
JMP I32 RESTORE_FS_TASK
INT_FAULT_ERR_CODE_BITMAP::
DU32 0x00027D00,0,0,0,0,0,0,0;
+2 -2
View File
@@ -244,12 +244,12 @@ Bool Raw(Bool val)
{//Switches to direct screen, non-windowed output.
if (!val)
VGAFlush;
return !LBEqu(&Fs->task_flags,TASKf_NOT_RAW,!val);
return !LBEqu(&Fs->display_flags,DISPLAYf_NOT_RAW,!val);
}
Bool IsRaw()
{//Are we in BLACK & WHITE raw screen mode?
return !Bt(&Fs->task_flags,TASKf_NOT_RAW);
return !Bt(&Fs->display_flags,DISPLAYf_NOT_RAW);
}
Bool SingleUser(Bool val)
+6 -6
View File
@@ -16,7 +16,7 @@ because it is #included first. $LK,"Kernel.PRJ",A="FF:::/Kernel/Kernel.PRJ,KSta
*/
USE16
SYS_KERNEL:: //This must match $LK,"CKernel",A="MN:CKernel"$.
JMP U16 BSP_16BIT_INIT
JMP U16 CORE0_16BIT_INIT
//************************************
// ASM Global vars required for 16-bit start-up
@@ -52,7 +52,7 @@ SYS_PCI_BUSSES:: DU16 0;
#assert $$-SYS_KERNEL==sizeof(CKernel)-sizeof(CBinFile)
//************************************
BSP_16BIT_INIT::
CORE0_16BIT_INIT::
//EBX is $LK,"SYS_BOOT_SRC",A="FF:::/Kernel/KStart.CPP,[SYS_BOOT_SRC]"$. (Val passed from boot blk, $LK,"BootHD",A="FF:::/Adam/Opt/Boot/BootHD.CPP,BOOT_SRC_HARDDRV"$, $LK,"BootDVD",A="FF:::/Adam/Opt/Boot/BootDVD.CPP,BOOT_SRC_DVD"$, & $LK,"BootRAM",A="FF:::/Adam/Opt/Boot/Reboot.CPP,BOOT_SRC_RAM"$.)
MOV AX,(BOOT_RAM_LIMIT-BOOT_STK_SIZE)/16
MOV SS,AX
@@ -172,8 +172,8 @@ The assembler doesn't support far jumps so we hand code it.
To complete the switch to 32-bit mode, we have to load
the code segment with a far jump.
*/
DU8 0x66,0xEA; //JMP CGDT.boot_cs:BSP_32BIT_INIT
DU32 BSP_32BIT_INIT;
DU8 0x66,0xEA; //JMP CGDT.boot_cs:CORE0_32BIT_INIT
DU32 CORE0_32BIT_INIT;
DU16 CGDT.boot_cs;
#assert $$+16<=0xFFFF
@@ -231,7 +231,7 @@ SYS_CACHE_LINE_WIDTH:: DU64 DFT_CACHE_LINE_WIDTH;
SYS_SEMAS:: DU8 NUM_SYS_SEMAS*SEMA_STRUCT_SIZE DUP(0);
//************************************
ALIGN 16,OC_NOP
BSP_32BIT_INIT:: //Entry point for $LK,"RAMReboot",A="MN:RAMReboot"$.
CORE0_32BIT_INIT:: //Entry point for $LK,"RAMReboot",A="MN:RAMReboot"$.
PUSH U32 RFLAGG_START
POPFD
MOV EAX,SYS_START_CR0
@@ -367,7 +367,7 @@ USE32
WRMSR
MOV EBX,BOOT_SRC_RAM
MOV EAX,I32 BSP_32BIT_INIT
MOV EAX,I32 CORE0_32BIT_INIT
JMP EAX
SYS_RAM_REBOOT_END::
USE64
+4 -4
View File
@@ -251,14 +251,14 @@ U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE)
if (!task) task=Fs;
PUSHFD
CLI
while (LBts(&task->locked_flags,TASKLf_TASK_LOCK))
while (LBts(&task->task_flags,TASKf_TASK_LOCK))
PAUSE
WinDerivedValsUpdate(task);
if (fp_update_ctrls)
(*fp_update_ctrls)(task);
if (update_z_buf && Bt(&task->display_flags,DISPLAYf_SHOW))
LBts(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0);
LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
LBtr(&task->task_flags,TASKf_TASK_LOCK);
POPFD
}
@@ -442,7 +442,7 @@ I64 TaskEnd()
if (LBtr(&task->display_flags,DISPLAYf_SHOW))
LBts(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0);
while (LBts(&task->locked_flags,TASKLf_TASK_LOCK))
while (LBts(&task->task_flags,TASKf_TASK_LOCK))
PAUSE
while (LBts(&task->srv_ctrl.flags,SVCRf_LOCKED))
PAUSE
@@ -478,7 +478,7 @@ I64 TaskEnd()
TaskQueRem(task);
LBtr(&task->srv_ctrl.flags,SVCRf_LOCKED);
LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
LBtr(&task->task_flags,TASKf_TASK_LOCK);
if (sys_winmgr_task) {
task->next_task=Gs->dying_task_lst;
+1237 -1230
View File
File diff suppressed because it is too large. Load diff
+1 -3
View File
@@ -23,12 +23,10 @@
#include "KernelB.HPP"
#include "KExts"
#include "StrA"
#include "MemA"
#include "KGlbls"
#include "MemB"
#include "KMathB"
#include "Sched"
#include "MemC"
#include "Mem/MakeMem"
#include "Font8x8"
#include "StrB"
#include "KHashA"
+19 -23
View File
@@ -2071,8 +2071,6 @@ class CAOTCtrl
#define TK_INS_BINARY_SIZE 0x126
#define TK_NUM_TK 0x127
#define LEX_MAX_IDENT 134 //Max is 132
class CLexHashTableContext
{
CLexHashTableContext *next;
@@ -3219,26 +3217,26 @@ public class CTaskSettings
};
#help_index "Task"
//Border ATTR src
//CTask.border_src
#define BDS_CONST 0
#define BDS_CUR_DRV 1
#define BDS_ED_FILENAME_DRV 2
//Task title src
//CTask.title_src
#define TTS_CONST 0
#define TTS_LOCKED_CONST 1 //This is not strictly enforced
#define TTS_TASK_NAME 2
#define TTS_ED_FILENAME 3
#define TTS_CUR_LEX 4
// TASK task flags
#define TASKf_KILL_TASK 0
#define TASKf_SUSPENDED 1
#define TASKf_IDLE 2
#define TASKf_INPUT_FILTER_TASK 3
#define TASKf_FILTER_INPUT 4
#define TASKf_HAS_SONG 5
#define TASKf_NOT_RAW 6
//CTask.task_flags
#define TASKf_TASK_LOCK 0
#define TASKf_KILL_TASK 1
#define TASKf_SUSPENDED 2
#define TASKf_IDLE 3
#define TASKf_INPUT_FILTER_TASK 4
#define TASKf_FILTER_INPUT 5
#define TASKf_HAS_SONG 6
#define TASKf_DISABLE_BPTS 7
#define TASKf_AWAITING_MSG 8
#define TASKf_BREAK_LOCKED 9
@@ -3247,14 +3245,13 @@ public class CTaskSettings
#define TASKf_KILL_AFTER_DBG 12
#define TASKf_NONTIMER_RAND 13
//locked flags
#define TASKLf_TASK_LOCK 0
//CTask.display_flags
#define DISPLAYf_SHOW 0
#define DISPLAYf_SILENT 1
#define DISPLAYf_NO_BORDER 2
#define DISPLAYf_WIN_ON_TOP 3
#define DISPLAYf_CHILDREN_NOT_ON_TOP 4
#define DISPLAYf_NOT_RAW 1
#define DISPLAYf_SILENT 2
#define DISPLAYf_NO_BORDER 3
#define DISPLAYf_WIN_ON_TOP 4
#define DISPLAYf_CHILDREN_NOT_ON_TOP 5
#define TASK_SIGNATURE_VAL 'TskS'
#define TASK_NAME_LEN 31
@@ -3268,9 +3265,8 @@ class CTaskStk
public class CTask //The Fs segment reg points to current CTask.
{
CTask *addr; //Self-addressed ptr
U32 task_signature,pad;
I64 task_flags,locked_flags;
U32 display_flags,win_inhibit;
U32 task_signature;
U32 task_flags,display_flags,win_inhibit;
I64 wake_jiffy;
CHeapCtrl *code_heap,*data_heap;
@@ -3554,7 +3550,7 @@ public class CTextGlbls
I64 raw_col,raw_flags;
U8 *raw_screen_image;
I64 rows,cols; //Use TEXT_ROWS,TEXT_COLS
U64 *font;
U64 *font,*aux_font;
};
#define FONT_WIDTH 8
+1 -1
View File
@@ -232,7 +232,7 @@ public _extern SYS_PROGRESSES
#help_file "::/Doc/MultiCore"
public _extern SYS_CPU_STRUCTS CCPU *cpu_structs; //$LK,"Gs",A="MN:Gs"$ points to cur $LK,"CCPU",A="MN:CCPU"$.
public _extern SYS_MP_CNT I64 mp_cnt; //Count of cores
_extern SYS_MP_CNT_INITIAL I64 mp_cnt_initial; //only used during $LK,"BSPStartMP",A="MN:BSPStartMP"$
_extern SYS_MP_CNT_INITIAL I64 mp_cnt_initial; //only used during $LK,"Core0StartMP",A="MN:Core0StartMP"$
_extern SYS_MP_CNT_LOCK I64 mp_cnt_lock;
_extern SYS_SEMAS CSema sys_semas[NUM_SYS_SEMAS];
+2 -3
View File
@@ -581,8 +581,8 @@ public extern U0 QSortI64(I64 *base,I64 num,
public extern U0 ProgressBarsRst();
#help_index "MultiCore"
extern U0 APSethTask();
extern U0 BSPStartMP();
extern U0 Core0StartMP();
extern U0 CoreAPSethTask();
public extern U0 MPInt(U8 num,I64 cpu_num=1);
public extern U0 MPIntAll(U8 num);
public extern U0 MPNMInt();
@@ -666,7 +666,6 @@ public extern U0 SleepUntil(I64 wake_jiffy);
#help_index "Task/Misc"
extern U0 (*fp_update_ctrls)(CTask *task);
public extern U0 OverRideSingleUserSwap();
public extern U0 TSSBusy(I64 tr,Bool val=OFF);
public extern U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE);
public extern U0 WinDerivedValsUpdate(CTask *task=NULL);
+8 -2
View File
@@ -150,7 +150,7 @@ U0 CtrlAltE(I64)
U0 CtrlAltF(I64)
{
VGAFlush;
SwapI64(&text.font,&text.aux_font);
}
U0 CtrlAltM(I64)
@@ -163,6 +163,11 @@ U0 CtrlAltT(I64)
LBts(sys_ctrl_alt_flags,SYSf_CTRL_ALT_TAB);
}
U0 CtrlAltV(I64)
{
VGAFlush;
}
U0 CtrlAltX(I64)
{
LBts(sys_ctrl_alt_flags,SYSf_CTRL_ALT_X);
@@ -204,8 +209,9 @@ U0 KeyDevInit()
CtrlAltCBSet('C',&CtrlAltC,"Cmd /Break Execution",,TRUE);
CtrlAltCBSet('D',&CtrlAltD,"Cmd /Enter Debugger",,TRUE);
CtrlAltCBSet('E',&CtrlAltE,"Cmd /Spawn New User Task");
CtrlAltCBSet('F',&CtrlAltF,"Cmd /VGA Flush",,TRUE);
CtrlAltCBSet('F',&CtrlAltF,"Cmd /Toggle Aux Font");
CtrlAltCBSet('M',&CtrlAltM,"Cmd /Toggle Mute");
CtrlAltCBSet('T',&CtrlAltT,"Cmd /Switch Focus to Next Task",,TRUE);
CtrlAltCBSet('V',&CtrlAltV,"Cmd /VGA Flush",,TRUE);
CtrlAltCBSet('X',&CtrlAltX,"Cmd /Kill Focused Task",,TRUE);
}
+72
View File
@@ -0,0 +1,72 @@
U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pages512)
{//Add mem to BlkPool.
if (sys_mem_init_flag)
MemSet(m,sys_mem_init_val,pages512*512);
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
m->next=bp->mem_free_lst;
m->pages=pages512;
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
bp->alloced_u8s+=pages512<<PAGE_BITS;
bp->mem_free_lst=m;
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
}
U0 BlkPoolInit(CBlkPool *bp,I64 pages512)
{//Make mem chunk into a BlkPool.
I64 num;
CMemBlk *m;
MemSet(bp,0,sizeof(CBlkPool));
m=(bp(U8 *)+sizeof(CBlkPool)+PAGE_SIZE-1)&~(PAGE_SIZE-1);
num=(bp(U8 *)+pages512<<PAGE_BITS-m(U8 *))>>PAGE_BITS;
bp->alloced_u8s=(pages512-num)<<PAGE_BITS; //Compensate before num added.
BlkPoolAdd(bp,m,num);
}
U0 BlkPoolsInit()
{
I64 i,total,lo,hi,code_heap_limit;
CMemE820 *m20=SYS_MEM_E820;
Bool first=TRUE;
total=BIOSTotalMem;
if (total<=0x80000000)
code_heap_limit=total;
else if (total<=0x100000000)
code_heap_limit=total/4;
else
code_heap_limit=0x80000000;
i=code_heap_limit-0x1000000;
BlkPoolAdd(sys_code_bp,0x1000000,i>>PAGE_BITS);
sys_heap_limit=i+0x1000000-1;
if (code_heap_limit<total) {
while (m20->type) {
if (m20->type==1) {
lo=m20->base;
hi=m20->base+m20->len;
if (lo<code_heap_limit) {
if (hi>code_heap_limit)
lo=code_heap_limit;
else
hi=lo; //cancel
}
if (code_heap_limit<=lo<hi) {
if (first) {
BlkPoolInit(lo,(hi-lo)>>PAGE_BITS);
sys_data_bp=lo;
Fs->data_heap=HeapCtrlInit(,Fs,sys_data_bp);
first=FALSE;
} else
BlkPoolAdd(sys_data_bp,lo,(hi-lo)>>PAGE_BITS);
}
}
m20++;
}
}
}
+45
View File
@@ -0,0 +1,45 @@
CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,CTask *task=NULL,CBlkPool *bp)
{//Called by $LK,"Adam Task",A="FF:::/Kernel/KStart.CPP,CHeapCtrl.bp"$.
if (!hc)
hc=ACAlloc(sizeof(CHeapCtrl));
hc->hc_signature=HEAP_CTRL_SIGNATURE_VAL;
hc->mem_task=task;
hc->bp=bp;
QueInit(&hc->next_mem_blk);
hc->next_um=hc->last_um=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
return hc;
}
CHeapCtrl *HeapCtrlBPInit(CBlkPool *bp,I64 pages512)
{//Make mem chunk into HeapCtrl and BlkPool.
I64 num;
CMemBlk *m;
CHeapCtrl *hc;
MemSet(bp,0,sizeof(CBlkPool)+sizeof(CHeapCtrl));
hc=HeapCtrlInit(bp(U8 *)+sizeof(CBlkPool),,bp);
m=(bp(U8 *)+sizeof(CBlkPool)+sizeof(CHeapCtrl)+PAGE_SIZE-1)&~(PAGE_SIZE-1);
num=(bp(U8 *)+pages512<<PAGE_BITS-m(U8 *))>>PAGE_BITS;
bp->alloced_u8s=(pages512-num)<<PAGE_BITS;
BlkPoolAdd(bp,m,num);
return hc;
}
U0 HeapCtrlDel(CHeapCtrl *hc)
{//Free all blks alloced to a HeapCtrl.
CMemBlk *m,*m1;
if (hc) {
PUSHFD
CLI
while (LBts(&hc->locked_flags,HClf_LOCKED))
PAUSE
m=hc->next_mem_blk;
while (m!=&hc->next_mem_blk) {
m1=m->next;
Mem512TaskFree(m,hc);
m=m1;
}
LBtr(&hc->locked_flags,HClf_LOCKED);
POPFD
Free(hc);
}
}
@@ -1,5 +1,6 @@
asm {
//************************************
//See $LK,"::/Doc/Credits.TXT"$.
_MALLOC::
// Throws 'OutMem'
PUSH RBP
@@ -206,7 +207,7 @@ MALLOC_FINAL_EXIT:
RET1 16
//************************************
_FREE::
//Be aware of $LK,"heap_hash",A="FF:::/Kernel/MemB.CPP,heap_hash"$ in $LK,"Mem512TaskAlloc",A="MN:Mem512TaskAlloc"$().
//Be aware of $LK,"heap_hash",A="FF:::/Kernel/Mem/MAllocFree.CPP,heap_hash"$ in $LK,"Mem512TaskAlloc",A="MN:Mem512TaskAlloc"$().
PUSH RBP
MOV RBP,RSP
PUSH RSI
+9
View File
@@ -0,0 +1,9 @@
#exe {Cd(__DIR__);};
#include "PageTables"
#include "Mem2Meg"
#include "Mem512"
#include "BlkPool"
#include "MAllocFree"
#include "HeapCtrl"
#include "MemPhysical"
#exe {Cd("..");};
+180
View File
@@ -0,0 +1,180 @@
U8 *Mem2MegAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL)
{/*Alloc 2Meg pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
I64 i,j,*pte,num=*_pages2Meg;
CMemBlk *result=NULL,*m,*m1;
if (!bp) bp=sys_code_bp;
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
num<<=21-PAGE_BITS;
m=&bp->mem_free_2meg_lst;
while (TRUE) {
if (!(result=m->next))
break;
if (result->pages<num)
m=result;
else {
if (result->pages==num) {
m->next=result->next;
goto am_done;
} else {
result->pages-=num;
result(U8 *)+=result->pages<<PAGE_BITS;
result->pages=num;
goto am_done;
}
}
}
m=&bp->mem_free_lst;
while (TRUE) {
if (!(result=m->next)) {
num=0;
result=NULL; //Out of memory
goto am_done;
}
if (result->pages<num)
m=result;
else {
if (result->pages==num) {
if (result(U8 *)&0x1FFFFF)
m=result;
else {
m->next=result->next;
goto am_done;
}
} else {
if (i=(result(U8 *)&0x1FFFFF)>>PAGE_BITS) {
j=1<<(21-PAGE_BITS)-i;
if (result->pages<num+j)
m=result;
else if (result->pages==num+j) {
result->pages-=num;
result(U8 *)+=result->pages<<PAGE_BITS;
result->pages=num;
goto am_done;
} else {
m1=result;
result(U8 *)+=j<<PAGE_BITS;
result->pages=num;
m=result(U8 *)+num<<PAGE_BITS;
m->pages=m1->pages-num-j;
m1->pages=j;
m->next=m1->next;
m1->next=m;
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
goto am_done;
}
} else {
m=m->next=result(U8 *)+num<<PAGE_BITS;
m->next=result->next;
m->pages=result->pages-num;
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
result->pages=num;
goto am_done;
}
}
}
}
am_done:
i=num<<PAGE_BITS;
bp->used_u8s+=i;
num>>=21-PAGE_BITS;
*_pages2Meg=num;
m=result;
m1=m(U8 *)+i;
while (m<m1) {
pte=MemPageTable(m);
*pte &= ~0x18;
InvlPg(m);
m(U8 *)+=MemPageSize(m);
}
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
return result;
}
U8 *Mem2MegUncachedAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL)
{/*Alloc 2Meg pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It will be marked uncached. It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
CMemBlk *result,*m,*m1;
I64 num=*_pages2Meg,*pte;
if (result=Mem2MegAlloc(_pages2Meg,bp)) {
num=*_pages2Meg;
m=result;
m1=m(U8 *)+num<<21;
while (m<m1) {
pte=MemPageTable(m);
*pte= *pte& ~0x18 |0x10;
InvlPg(m);
m(U8 *)+=MemPageSize(m);
}
}
return result;
}
U8 *Mem2MegWriteThruAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL)
{/*Alloc 2Meg pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It will be marked write-through. It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
CMemBlk *result,*m,*m1;
I64 num=*_pages2Meg,*pte;
if (result=Mem2MegAlloc(_pages2Meg,bp)) {
num=*_pages2Meg;
m=result;
m1=m(U8 *)+num<<21;
while (m<m1) {
pte=MemPageTable(m);
*pte= *pte& ~0x18 |8;
InvlPg(m);
m(U8 *)+=MemPageSize(m);
}
}
return result;
}
U0 Mem2MegFree(CMemBlk *m,I64 pages2Meg,CBlkPool *bp=NULL)
{//Return non-task 2Meg pages to BlkPool.
I64 *pte;
CMemBlk *m1,*m2;
if (m) {
if (!bp) bp=sys_code_bp;
m2=m;
m1=m(U8 *)+pages2Meg<<21;
while (m2<m1) {
pte=MemPageTable(m2);
*pte=*pte & ~0x18;
InvlPg(m2);
m2(U8 *)+=MemPageSize(m2);
}
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
m->pages=pages2Meg<<(21-PAGE_BITS);
bp->used_u8s-=pages2Meg<<21;
m->next=bp->mem_free_2meg_lst;
bp->mem_free_2meg_lst=m;
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
}
}
+169
View File
@@ -0,0 +1,169 @@
U0 SysBadFree(I64 *ptr)
{
Dbg("Bad Free:",ptr);
}
U0 SysBadMAlloc(I64 *ptr)
{
Dbg("Bad MAlloc:",ptr);
}
U8 *Mem512Alloc(I64 *_pages512,CBlkPool *bp=NULL)
{/*Alloc 512Byte pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
CMemBlk *result=NULL,*m;
I64 i,num=*_pages512;
if (!bp) bp=sys_code_bp;
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
if (num<FREE_PAGE_HASH_SIZE) {
if (result=bp->free_page_hash[num]) {
bp->free_page_hash[num]=result->next;
goto at_done;
}
i=Bsr(FREE_PAGE_HASH_SIZE)+1;
} else {
//We'll now round-up to a power of two.
//There is some overhead on allocations and
//we wouldn't want to round to the next
//power of two if a power of two was requested.
//So we use a little more than a power of two.
num-=2;
i=Bsr(num)+1;
num=1<<i+2;
if (result=bp->free_page_hash2[i]) {
bp->free_page_hash2[i]=result->next;
goto at_done;
}
}
m=&bp->mem_free_lst;
while (TRUE) {
if (!(result=m->next)) {
//We're probably out of luck, but lets search for a
//freed larger size block... and, screw-it, return the whole thing.
do {
if (result=bp->free_page_hash2[++i]) {
num=1<<i+2;
bp->free_page_hash2[i]=result->next;
goto at_done;
}
} while (i<64-PAGE_BITS-1);
num=0;
result=NULL; //Out of memory
goto at_done;
}
if (result->pages<num)
m=result;
else {
if (result->pages==num) {
m->next=result->next;
goto at_done;
} else {
result->pages-=num;
result(U8 *)+=result->pages<<PAGE_BITS;
result->pages=num;
goto at_done;
}
}
}
at_done:
*_pages512=num;
bp->used_u8s+=num<<PAGE_BITS;
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
return result;
}
U0 Mem512Free(CMemBlk *m,I64 pages512,CBlkPool *bp=NULL)
{//Return non-task 512Byte pages to BlkPool.
I64 i;
if (m) {
if (!bp) bp=sys_code_bp;
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
m->pages=pages512;
bp->used_u8s-=pages512<<PAGE_BITS;
if (pages512<FREE_PAGE_HASH_SIZE) {
m->next=bp->free_page_hash[pages512];
bp->free_page_hash[pages512]=m;
} else {
//We'll now round-up to a power of two.
//There is some overhead on allocations and
//we wouldn't want to round to the next
//power of two if a power of two was requested.
//So we use a little more than a power of two.
pages512-=2;
i=Bsr(pages512);
m->next=bp->free_page_hash2[i];
bp->free_page_hash2[i]=m;
}
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
}
}
CMemBlk *Mem512TaskAlloc(I64 *_pages512,CHeapCtrl *hc)
{/*hc must be locked. Interrupts should probably be off
Currently, this is only called from $LK,"MAlloc",A="MN:MAlloc"$().
Return: NULL if out of memory.
*/
CMemBlk *result;
I64 threshold,cnt,size;
CMemUnused *uum,**_uum,**_ptr;
if (result=Mem512Alloc(_pages512,hc->bp)) {
QueIns(result,hc->last_mem_blk);
result->mb_signature=MBS_USED_SIGNATURE_VAL;
hc->alloced_u8s+=*_pages512<<PAGE_BITS;
//Tidy-up free lst (Move into heap hash)
//because if free lst gets long, delay causes crash
threshold=HEAP_HASH_SIZE>>4;
#assert HEAP_HASH_SIZE>>4>=sizeof(U8 *)
do {
cnt=0;
_uum=&hc->malloc_free_lst;
while (uum=*_uum) {
#assert !offset(CMemUnused.next)
size=uum->size;
if (size<threshold) {
*_uum=uum->next;
_ptr=(&hc->heap_hash)(U8 *)+size;
uum->next=*_ptr;
*_ptr=uum;
} else {
cnt++;
_uum=uum;
}
}
threshold<<=1;
} while (cnt>8 && threshold<=HEAP_HASH_SIZE);
}
return result;
}
U0 Mem512TaskFree(CMemBlk *m,CHeapCtrl *hc)
{//hc must be locked
if (m) {
PUSHFD
CLI
if (m->mb_signature!=MBS_USED_SIGNATURE_VAL)
SysBadFree(m);
else {
QueRem(m);
hc->alloced_u8s-=m->pages<<PAGE_BITS;
Mem512Free(m,m->pages,hc->bp);
}
POPFD
}
}
@@ -1,77 +1,3 @@
U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pages512)
{//Add mem to BlkPool.
if (sys_mem_init_flag)
MemSet(m,sys_mem_init_val,pages512*512);
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
m->next=bp->mem_free_lst;
m->pages=pages512;
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
bp->alloced_u8s+=pages512<<PAGE_BITS;
bp->mem_free_lst=m;
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
}
U0 BlkPoolInit(CBlkPool *bp,I64 pages512)
{//Make mem chunk into a BlkPool.
I64 num;
CMemBlk *m;
MemSet(bp,0,sizeof(CBlkPool));
m=(bp(U8 *)+sizeof(CBlkPool)+PAGE_SIZE-1)&~(PAGE_SIZE-1);
num=(bp(U8 *)+pages512<<PAGE_BITS-m(U8 *))>>PAGE_BITS;
bp->alloced_u8s=(pages512-num)<<PAGE_BITS; //Compensate before num added.
BlkPoolAdd(bp,m,num);
}
CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,CTask *task=NULL,CBlkPool *bp)
{//Called by $LK,"Adam Task",A="FF:::/Kernel/KStart.CPP,CHeapCtrl.bp"$.
if (!hc)
hc=ACAlloc(sizeof(CHeapCtrl));
hc->hc_signature=HEAP_CTRL_SIGNATURE_VAL;
hc->mem_task=task;
hc->bp=bp;
QueInit(&hc->next_mem_blk);
hc->next_um=hc->last_um=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
return hc;
}
CHeapCtrl *HeapCtrlBPInit(CBlkPool *bp,I64 pages512)
{//Make mem chunk into HeapCtrl and BlkPool.
I64 num;
CMemBlk *m;
CHeapCtrl *hc;
MemSet(bp,0,sizeof(CBlkPool)+sizeof(CHeapCtrl));
hc=HeapCtrlInit(bp(U8 *)+sizeof(CBlkPool),,bp);
m=(bp(U8 *)+sizeof(CBlkPool)+sizeof(CHeapCtrl)+PAGE_SIZE-1)&~(PAGE_SIZE-1);
num=(bp(U8 *)+pages512<<PAGE_BITS-m(U8 *))>>PAGE_BITS;
bp->alloced_u8s=(pages512-num)<<PAGE_BITS;
BlkPoolAdd(bp,m,num);
return hc;
}
U0 HeapCtrlDel(CHeapCtrl *hc)
{//Free all blks alloced to a HeapCtrl.
CMemBlk *m,*m1;
if (hc) {
PUSHFD
CLI
while (LBts(&hc->locked_flags,HClf_LOCKED))
PAUSE
m=hc->next_mem_blk;
while (m!=&hc->next_mem_blk) {
m1=m->next;
Mem512TaskFree(m,hc);
m=m1;
}
LBtr(&hc->locked_flags,HClf_LOCKED);
POPFD
Free(hc);
}
}
Bool Mem32DevIns(CMemRange *tempmr)
{
CMemRange *tempmr1=dev.mem32_root.next,*tempmr2;
@@ -258,51 +184,6 @@ I64 BIOSTotalMem()
return MaxI64(r01,r20);
}
U0 HeapsInit()
{
I64 i,total,lo,hi,code_heap_limit;
CMemE820 *m20=SYS_MEM_E820;
Bool first=TRUE;
total=BIOSTotalMem;
if (total<=0x80000000)
code_heap_limit=total;
else if (total<=0x100000000)
code_heap_limit=total/4;
else
code_heap_limit=0x80000000;
i=code_heap_limit-0x1000000;
BlkPoolAdd(sys_code_bp,0x1000000,i>>PAGE_BITS);
sys_heap_limit=i+0x1000000-1;
if (code_heap_limit<total) {
while (m20->type) {
if (m20->type==1) {
lo=m20->base;
hi=m20->base+m20->len;
if (lo<code_heap_limit) {
if (hi>code_heap_limit)
lo=code_heap_limit;
else
hi=lo; //cancel
}
if (code_heap_limit<=lo<hi) {
if (first) {
BlkPoolInit(lo,(hi-lo)>>PAGE_BITS);
sys_data_bp=lo;
Fs->data_heap=HeapCtrlInit(,Fs,sys_data_bp);
first=FALSE;
} else
BlkPoolAdd(sys_data_bp,lo,(hi-lo)>>PAGE_BITS);
}
}
m20++;
}
}
}
I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024)
{//Helps pick DiskCache and RAMDisk sizes.
//Can be used in $LK,"MakeOSDrvBootInstall",A="MN:MakeOSDrvBootInstall"$() config scripts.
+180
View File
@@ -0,0 +1,180 @@
asm {
// $LK,"::/Doc/MemOverview.TXT"$
USE32
SYS_INIT_MEM::
//Set page tables to identity map everything.
MOV EDI,SYS_FIXED_AREA
XOR EAX,EAX
MOV ECX,sizeof(CSysFixedArea)/4
REP_STOSD //Init entire SYS_FIXED_AREA to zero
//PML1
MOV EAX,0x107
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml1
MOV ECX,MEM_NUM_PML1*0x200
@@05: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@05
//0xA0000-0xBFFFF: video ram=write thru
MOV EAX,0xF
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml1+0xA0*8
MOV ECX,0xC0-0xA0
@@10: OR U32 [EDI],EAX
ADD EDI,4
OR U32 [EDI],EDX
ADD EDI,4
LOOP @@10
//PML2
MOV EAX,SYS_FIXED_AREA+CSysFixedArea.pml1+7
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml2
MOV ECX,MEM_NUM_PML1
@@15: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@15
MOV EAX,MEM_NUM_PML1*0x200000+0x87 //bit 7 is page size (1==2Meg)
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml2+8*MEM_NUM_PML1
MOV ECX,MEM_NUM_PML2*0x200-MEM_NUM_PML1
@@20: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x200000
ADC EDX,0
LOOP @@20
//0xE0000000-0xFFFFFFFF: PCI Devs
MOV EAX,0x17 //Cache disabled
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml2+8*0x700
MOV ECX,0x800-0x700
@@25: OR U32 [EDI],EAX
ADD EDI,4
OR U32 [EDI],EDX
ADD EDI,4
LOOP @@25
//PML3
MOV EAX,SYS_FIXED_AREA+CSysFixedArea.pml2+7
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml3
MOV ECX,MEM_NUM_PML2
@@30: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@30
//PML4
MOV EAX,SYS_FIXED_AREA+CSysFixedArea.pml3+7
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml4
MOV ECX,MEM_NUM_PML3
@@35: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@35
MOV U32 [SYS_CODE_BP],SYS_FIXED_AREA+CSysFixedArea.adam_bp
MOV U32 [SYS_CODE_BP+4],0
MOV U32 [SYS_DATA_BP],0
MOV U32 [SYS_DATA_BP+4],0
XOR EAX,EAX
MOV AX,U16 [SYS_MEM_E801] //1 Kb blks between 1M and 16M
SHL EAX,10
ADD EAX,0x100000
MOV EBX,U32 [SYS_HEAP_BASE] //SYS_FIXED_AREA+sizeof(CSysFixedArea)
SUB EAX,EBX
/*$AN,"ExpandHeap",A="ExpandHeap"$
TempleOS initializes the heap to the val
of the BIOS E801 lowest 16Meg val. It
later adds the rest to the heap. There
are a few allocations which occur while
it is set to this small val.
At some point, it might be nice to
initialize to the full val but it is a
pain without MAlloc up-and-running.
*/
#define CONSERVATIVE_16MEG_SIZE 0xF00000
#define ESTIMATED_MISC_ALLOCS 0x100000
#assert CONSERVATIVE_16MEG_SIZE-
(SYS_FIXED_AREA+sizeof(CSysFixedArea))>ADAM_STK+ESTIMATED_MISC_ALLOCS
//EBX=BASE EAX=SIZE
TEST U8 [SYS_MEM_INIT_FLAG],1
JZ @@40
PUSH EAX
MOV EDI,EBX
MOV ECX,EAX
MOV AL,U8 [SYS_MEM_INIT_VAL]
REP_STOSB
POP EAX
@@40: SHR EAX,PAGE_BITS
MOV ESI,SYS_FIXED_AREA+CSysFixedArea.adam_bp
MOV EDI,U32 CBlkPool.mem_free_lst[ESI]
MOV U32 CMemBlk.next[EBX],EDI
MOV U32 CMemBlk.next+4[EBX],0
MOV U32 CBlkPool.mem_free_lst[ESI],EBX
MOV U32 CBlkPool.mem_free_lst+4[ESI],0
MOV U32 CMemBlk.mb_signature[EBX],MBS_UNUSED_SIGNATURE_VAL
MOV U32 CMemBlk.pages[EBX],EAX
SHL EAX,PAGE_BITS
ADD U32 CBlkPool.alloced_u8s[ESI],EAX
RET
}
I64 MemPageSize(U8 *a)
{//Size of page table at addr.Either 4K or 2Meg.
if (a<MEM_NUM_PML1*0x1000*0x200)
return 0x1000;
else
return 0x200000;
}
I64 *MemPageTable(U8 *a)
{//Point to page table entry for addr.
if (a<MEM_NUM_PML1*0x1000*0x200)
return SYS_FIXED_AREA+offset(CSysFixedArea.pml1)+a>>12*8;
else
return SYS_FIXED_AREA+offset(CSysFixedArea.pml2)+a>>21*8;
}
Bool MemPagePresentMark(U8 *a,Bool val)
{//Mark an addr's page present or not-present.
I64 *pte=MemPageTable(a);
Bool result=*pte&1;
if (val)
*pte=*pte|1; //Mark present
else
*pte=*pte&~1; //Mark not present
InvlPg(a);
return result;
}
-532
View File
@@ -1,532 +0,0 @@
asm {
/*See $LK,"::/Doc/Credits.TXT"$.
See $LK,"::/Doc/MemOverview.TXT"$
*/
USE32
SYS_INIT_MEM::
//Set page tables to identity map everything.
MOV EDI,SYS_FIXED_AREA
XOR EAX,EAX
MOV ECX,sizeof(CSysFixedArea)/4
REP_STOSD //Init entire SYS_FIXED_AREA to zero
//PML1
MOV EAX,0x107
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml1
MOV ECX,MEM_NUM_PML1*0x200
@@05: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@05
//0xA0000-0xBFFFF: video ram=write thru
MOV EAX,0xF
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml1+0xA0*8
MOV ECX,0xC0-0xA0
@@10: OR U32 [EDI],EAX
ADD EDI,4
OR U32 [EDI],EDX
ADD EDI,4
LOOP @@10
//PML2
MOV EAX,SYS_FIXED_AREA+CSysFixedArea.pml1+7
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml2
MOV ECX,MEM_NUM_PML1
@@15: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@15
MOV EAX,MEM_NUM_PML1*0x200000+0x87 //bit 7 is page size (1==2Meg)
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml2+8*MEM_NUM_PML1
MOV ECX,MEM_NUM_PML2*0x200-MEM_NUM_PML1
@@20: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x200000
ADC EDX,0
LOOP @@20
//0xE0000000-0xFFFFFFFF: PCI Devs
MOV EAX,0x17 //Cache disabled
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml2+8*0x700
MOV ECX,0x800-0x700
@@25: OR U32 [EDI],EAX
ADD EDI,4
OR U32 [EDI],EDX
ADD EDI,4
LOOP @@25
//PML3
MOV EAX,SYS_FIXED_AREA+CSysFixedArea.pml2+7
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml3
MOV ECX,MEM_NUM_PML2
@@30: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@30
//PML4
MOV EAX,SYS_FIXED_AREA+CSysFixedArea.pml3+7
XOR EDX,EDX
MOV EDI,SYS_FIXED_AREA+CSysFixedArea.pml4
MOV ECX,MEM_NUM_PML3
@@35: MOV U32 [EDI],EAX
ADD EDI,4
MOV U32 [EDI],EDX
ADD EDI,4
ADD EAX,0x1000
ADC EDX,0
LOOP @@35
MOV U32 [SYS_CODE_BP],SYS_FIXED_AREA+CSysFixedArea.adam_bp
MOV U32 [SYS_CODE_BP+4],0
MOV U32 [SYS_DATA_BP],0
MOV U32 [SYS_DATA_BP+4],0
XOR EAX,EAX
MOV AX,U16 [SYS_MEM_E801] //1 Kb blks between 1M and 16M
SHL EAX,10
ADD EAX,0x100000
MOV EBX,U32 [SYS_HEAP_BASE] //SYS_FIXED_AREA+sizeof(CSysFixedArea)
SUB EAX,EBX
/*$AN,"ExpandHeap",A="ExpandHeap"$
TempleOS initializes the heap to the val
of the BIOS E801 lowest 16Meg val. It
later adds the rest to the heap. There
are a few allocations which occur while
it is set to this small val.
At some point, it might be nice to
initialize to the full val but it is a
pain without MAlloc up-and-running.
*/
#define CONSERVATIVE_16MEG_SIZE 0xF00000
#define ESTIMATED_MISC_ALLOCS 0x100000
#assert CONSERVATIVE_16MEG_SIZE-
(SYS_FIXED_AREA+sizeof(CSysFixedArea))>ADAM_STK+ESTIMATED_MISC_ALLOCS
//EBX=BASE EAX=SIZE
TEST U8 [SYS_MEM_INIT_FLAG],1
JZ @@40
PUSH EAX
MOV EDI,EBX
MOV ECX,EAX
MOV AL,U8 [SYS_MEM_INIT_VAL]
REP_STOSB
POP EAX
@@40: SHR EAX,PAGE_BITS
MOV ESI,SYS_FIXED_AREA+CSysFixedArea.adam_bp
MOV EDI,U32 CBlkPool.mem_free_lst[ESI]
MOV U32 CMemBlk.next[EBX],EDI
MOV U32 CMemBlk.next+4[EBX],0
MOV U32 CBlkPool.mem_free_lst[ESI],EBX
MOV U32 CBlkPool.mem_free_lst+4[ESI],0
MOV U32 CMemBlk.mb_signature[EBX],MBS_UNUSED_SIGNATURE_VAL
MOV U32 CMemBlk.pages[EBX],EAX
SHL EAX,PAGE_BITS
ADD U32 CBlkPool.alloced_u8s[ESI],EAX
RET
}
U0 SysBadFree(I64 *ptr)
{
Dbg("Bad Free:",ptr);
}
U0 SysBadMAlloc(I64 *ptr)
{
Dbg("Bad MAlloc:",ptr);
}
I64 MemPageSize(U8 *a)
{//Size of page table at addr.Either 4K or 2Meg.
if (a<MEM_NUM_PML1*0x1000*0x200)
return 0x1000;
else
return 0x200000;
}
I64 *MemPageTable(U8 *a)
{//Point to page table entry for addr.
if (a<MEM_NUM_PML1*0x1000*0x200)
return SYS_FIXED_AREA+offset(CSysFixedArea.pml1)+a>>12*8;
else
return SYS_FIXED_AREA+offset(CSysFixedArea.pml2)+a>>21*8;
}
Bool MemPagePresentMark(U8 *a,Bool val)
{//Mark an addr's page present or not-present.
I64 *pte=MemPageTable(a);
Bool result=*pte&1;
if (val)
*pte=*pte|1; //Mark present
else
*pte=*pte&~1; //Mark not present
InvlPg(a);
return result;
}
U8 *Mem512Alloc(I64 *_pages512,CBlkPool *bp=NULL)
{/*Alloc 512Byte pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
CMemBlk *result=NULL,*m;
I64 i,num=*_pages512;
if (!bp) bp=sys_code_bp;
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
if (num<FREE_PAGE_HASH_SIZE) {
if (result=bp->free_page_hash[num]) {
bp->free_page_hash[num]=result->next;
goto at_done;
}
i=Bsr(FREE_PAGE_HASH_SIZE)+1;
} else {
//We'll now round-up to a power of two.
//There is some overhead on allocations and
//we wouldn't want to round to the next
//power of two if a power of two was requested.
//So we use a little more than a power of two.
num-=2;
i=Bsr(num)+1;
num=1<<i+2;
if (result=bp->free_page_hash2[i]) {
bp->free_page_hash2[i]=result->next;
goto at_done;
}
}
m=&bp->mem_free_lst;
while (TRUE) {
if (!(result=m->next)) {
//We're probably out of luck, but lets search for a
//freed larger size block... and, screw-it, return the whole thing.
do {
if (result=bp->free_page_hash2[++i]) {
num=1<<i+2;
bp->free_page_hash2[i]=result->next;
goto at_done;
}
} while (i<64-PAGE_BITS-1);
num=0;
result=NULL; //Out of memory
goto at_done;
}
if (result->pages<num)
m=result;
else {
if (result->pages==num) {
m->next=result->next;
goto at_done;
} else {
result->pages-=num;
result(U8 *)+=result->pages<<PAGE_BITS;
result->pages=num;
goto at_done;
}
}
}
at_done:
*_pages512=num;
bp->used_u8s+=num<<PAGE_BITS;
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
return result;
}
U0 Mem512Free(CMemBlk *m,I64 pages512,CBlkPool *bp=NULL)
{//Return non-task 512Byte pages to BlkPool.
I64 i;
if (m) {
if (!bp) bp=sys_code_bp;
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
m->pages=pages512;
bp->used_u8s-=pages512<<PAGE_BITS;
if (pages512<FREE_PAGE_HASH_SIZE) {
m->next=bp->free_page_hash[pages512];
bp->free_page_hash[pages512]=m;
} else {
//We'll now round-up to a power of two.
//There is some overhead on allocations and
//we wouldn't want to round to the next
//power of two if a power of two was requested.
//So we use a little more than a power of two.
pages512-=2;
i=Bsr(pages512);
m->next=bp->free_page_hash2[i];
bp->free_page_hash2[i]=m;
}
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
}
}
U8 *Mem2MegAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL)
{/*Alloc 2Meg pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
I64 i,j,*pte,num=*_pages2Meg;
CMemBlk *result=NULL,*m,*m1;
if (!bp) bp=sys_code_bp;
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
num<<=21-PAGE_BITS;
m=&bp->mem_free_2meg_lst;
while (TRUE) {
if (!(result=m->next))
break;
if (result->pages<num)
m=result;
else {
if (result->pages==num) {
m->next=result->next;
goto am_done;
} else {
result->pages-=num;
result(U8 *)+=result->pages<<PAGE_BITS;
result->pages=num;
goto am_done;
}
}
}
m=&bp->mem_free_lst;
while (TRUE) {
if (!(result=m->next)) {
num=0;
result=NULL; //Out of memory
goto am_done;
}
if (result->pages<num)
m=result;
else {
if (result->pages==num) {
if (result(U8 *)&0x1FFFFF)
m=result;
else {
m->next=result->next;
goto am_done;
}
} else {
if (i=(result(U8 *)&0x1FFFFF)>>PAGE_BITS) {
j=1<<(21-PAGE_BITS)-i;
if (result->pages<num+j)
m=result;
else if (result->pages==num+j) {
result->pages-=num;
result(U8 *)+=result->pages<<PAGE_BITS;
result->pages=num;
goto am_done;
} else {
m1=result;
result(U8 *)+=j<<PAGE_BITS;
result->pages=num;
m=result(U8 *)+num<<PAGE_BITS;
m->pages=m1->pages-num-j;
m1->pages=j;
m->next=m1->next;
m1->next=m;
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
goto am_done;
}
} else {
m=m->next=result(U8 *)+num<<PAGE_BITS;
m->next=result->next;
m->pages=result->pages-num;
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
result->pages=num;
goto am_done;
}
}
}
}
am_done:
i=num<<PAGE_BITS;
bp->used_u8s+=i;
num>>=21-PAGE_BITS;
*_pages2Meg=num;
m=result;
m1=m(U8 *)+i;
while (m<m1) {
pte=MemPageTable(m);
*pte &= ~0x18;
InvlPg(m);
m(U8 *)+=MemPageSize(m);
}
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
return result;
}
U8 *Mem2MegUncachedAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL)
{/*Alloc 2Meg pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It will be marked uncached. It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
CMemBlk *result,*m,*m1;
I64 num=*_pages2Meg,*pte;
if (result=Mem2MegAlloc(_pages2Meg,bp)) {
num=*_pages2Meg;
m=result;
m1=m(U8 *)+num<<21;
while (m<m1) {
pte=MemPageTable(m);
*pte= *pte& ~0x18 |0x10;
InvlPg(m);
m(U8 *)+=MemPageSize(m);
}
}
return result;
}
U8 *Mem2MegWriteThruAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL)
{/*Alloc 2Meg pages from BlkPool. Don't link to task.
(Linking to a task means they will be freed when the task dies.)
It will be marked write-through. It might give you more than you asked for
so a ptr to a page count is passed.
Return: NULL if out of memory.
*/
CMemBlk *result,*m,*m1;
I64 num=*_pages2Meg,*pte;
if (result=Mem2MegAlloc(_pages2Meg,bp)) {
num=*_pages2Meg;
m=result;
m1=m(U8 *)+num<<21;
while (m<m1) {
pte=MemPageTable(m);
*pte= *pte& ~0x18 |8;
InvlPg(m);
m(U8 *)+=MemPageSize(m);
}
}
return result;
}
U0 Mem2MegFree(CMemBlk *m,I64 pages2Meg,CBlkPool *bp=NULL)
{//Return non-task 2Meg pages to BlkPool.
I64 *pte;
CMemBlk *m1,*m2;
if (m) {
if (!bp) bp=sys_code_bp;
m2=m;
m1=m(U8 *)+pages2Meg<<21;
while (m2<m1) {
pte=MemPageTable(m2);
*pte=*pte & ~0x18;
InvlPg(m2);
m2(U8 *)+=MemPageSize(m2);
}
PUSHFD
CLI
while (LBts(&bp->locked_flags,BPlf_LOCKED))
PAUSE
m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
m->pages=pages2Meg<<(21-PAGE_BITS);
bp->used_u8s-=pages2Meg<<21;
m->next=bp->mem_free_2meg_lst;
bp->mem_free_2meg_lst=m;
LBtr(&bp->locked_flags,BPlf_LOCKED);
POPFD
}
}
CMemBlk *Mem512TaskAlloc(I64 *_pages512,CHeapCtrl *hc)
{/*hc must be locked. Interrupts should probably be off
Currently, this is only called from $LK,"MAlloc",A="MN:MAlloc"$().
Return: NULL if out of memory.
*/
CMemBlk *result;
I64 threshold,cnt,size;
CMemUnused *uum,**_uum,**_ptr;
if (result=Mem512Alloc(_pages512,hc->bp)) {
QueIns(result,hc->last_mem_blk);
result->mb_signature=MBS_USED_SIGNATURE_VAL;
hc->alloced_u8s+=*_pages512<<PAGE_BITS;
//Tidy-up free lst (Move into heap hash)
//because if free lst gets long, delay causes crash
threshold=HEAP_HASH_SIZE>>4;
#assert HEAP_HASH_SIZE>>4>=sizeof(U8 *)
do {
cnt=0;
_uum=&hc->malloc_free_lst;
while (uum=*_uum) {
#assert !offset(CMemUnused.next)
size=uum->size;
if (size<threshold) {
*_uum=uum->next;
_ptr=(&hc->heap_hash)(U8 *)+size;
uum->next=*_ptr;
*_ptr=uum;
} else {
cnt++;
_uum=uum;
}
}
threshold<<=1;
} while (cnt>8 && threshold<=HEAP_HASH_SIZE);
}
return result;
}
U0 Mem512TaskFree(CMemBlk *m,CHeapCtrl *hc)
{//hc must be locked
if (m) {
PUSHFD
CLI
if (m->mb_signature!=MBS_USED_SIGNATURE_VAL)
SysBadFree(m);
else {
QueRem(m);
hc->alloced_u8s-=m->pages<<PAGE_BITS;
Mem512Free(m,m->pages,hc->bp);
}
POPFD
}
}
+13 -13
View File
@@ -5,7 +5,7 @@ USE16
//This code gets copied to $LK,"MP_VECT_ADDR",A="MN:MP_VECT_ADDR"$.
//See $LK,"MemCpy(MP_VECT_ADDR",A="FF:::/Kernel/MultiProc.CPP,MemCpy(mp:2"$.
AP_16BIT_INIT::
COREAP_16BIT_INIT::
JMP @@05
ALIGN 4,OC_NOP
@@ -23,7 +23,7 @@ AP_GDT_PTR: DU16 sizeof(CGDT)-1;
DU8 0x66,0xEA; //JMP CGDT.cs32:AP_32BIT_INIT
DU32 AP_32BIT_INIT;
DU16 CGDT.cs32;
AP_16BIT_INIT_END::
COREAP_16BIT_INIT_END::
USE32
AP_32BIT_INIT:
@@ -121,7 +121,7 @@ CCPU *CPUStructInit(I64 num,CCPU *c,CTask *seth_task)
c->idle_factor=0.01;
if (Bt(&sys_run_level,RLf_BOOT_HEAP)) {
c->idle_task=Spawn(0,NULL,"Idle Task",,Fs,,0);
Bts(&c->idle_task->task_flags,TASKf_IDLE);
LBts(&c->idle_task->task_flags,TASKf_IDLE);
c->tss=TSSNew(num);
}
c->seth_task=seth_task;// It waits for this to be filled-in: $LK,"seth_task",A="FF:::/Kernel/MultiProc.CPP,seth_task"$
@@ -188,7 +188,7 @@ U0 MPWake(I64 target_cpu)
U0 MPAPICInit()
{//Called by adam during start-up
//and other cores during initialization
//after $LK,"BSPStartMP",A="MN:BSPStartMP"$().
//after $LK,"Core0StartMP",A="MN:Core0StartMP"$().
*LAPIC_SVR(U32 *)|=LAPICF_APIC_ENABLED;
dev.mp_apic_ids[Gs->num]=*LAPIC_APIC_ID(U32 *)>>24;
*LAPIC_LDR(U32 *)=dev.mp_apic_ids[Gs->num]<<24;
@@ -208,7 +208,7 @@ U0 MPAPICInit()
#assert !offset(CSrvCtrl.next_waiting)
U0 APSethTask()
U0 CoreAPSethTask()
{
CSrvCtrl *my_ctrl=&Fs->srv_ctrl;
CSrvCmd *tempc,*tempc1=&my_ctrl->next_waiting;
@@ -289,17 +289,17 @@ CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,
return result;
}
U0 APSethInit()
{//Called by multicore's seth task after $LK,"BSPStartMP",A="MN:BSPStartMP"$()
U0 CoreAPSethInit()
{//Called by multicore's seth task after $LK,"Core0StartMP",A="MN:Core0StartMP"$()
//as the first thing a CPU does before waiting for jobs.
MPAPICInit;
Fs->rip=&APSethTask;
Fs->rip=&CoreAPSethTask;
Fs->time_slice_start=GetTSC;
TaskContextRestore;
}
U0 BSPStartMP()
{//Called by adam during $LK,"start-up",A="FF:::/Kernel/KEnd.CPP,BSPStartMP"$.
U0 Core0StartMP()
{//Called by adam during $LK,"start-up",A="FF:::/Kernel/KEnd.CPP,Core0StartMP"$.
CTask *task;
U8 buf[STR_LEN];
CAP16BitInit *mp=MP_VECT_ADDR;
@@ -327,7 +327,7 @@ U0 BSPStartMP()
//When you start-up other cores, they jump to an addr
//specified by a byte vect number, $LK,"MPN_VECT",A="MN:MPN_VECT"$ which corresponds
//to a location 4096*vect number, $LK,"MP_VECT_ADDR",A="MN:MP_VECT_ADDR"$$WW,0$.
MemCpy(mp,AP_16BIT_INIT,AP_16BIT_INIT_END-AP_16BIT_INIT);
MemCpy(mp,COREAP_16BIT_INIT,COREAP_16BIT_INIT_END-COREAP_16BIT_INIT);
MemCpy(&mp->ap_gdt_ptr,SYS_GDT_PTR,sizeof(CSysLimitBase));
mp_cnt_initial=mp_cnt=1;
mp_cnt_lock=0;
@@ -352,7 +352,7 @@ U0 BSPStartMP()
for (i=1;i<my_mp_cnt;i++) {
StrPrint(buf,"Seth Task CPU#%d",i);
task=Spawn(&APSethInit,NULL,buf,,,SETH_STK,0);
task=Spawn(&CoreAPSethInit,NULL,buf,,,SETH_STK,0);
task->rflags=RFLAGG_START;
//$LK,"CTask",A="MN:CTask"$ alloced off this core's seth_task's heap (Which is Adam)
CPUStructInit(i,&cpu_structs[i],task);
@@ -370,7 +370,7 @@ U0 BSPStartMP()
mp_cnt=my_mp_cnt; //Finalize cnt
}
U0 BSPInit()
U0 Core0Init()
{//Called by adam during start-up
CRAXRBCRCXRDX ee;
CPUId(0x1,&ee);
+44 -68
View File
@@ -32,11 +32,26 @@ The scheduler checks for a few keys:
Each core has its own circular task queue.
For AP processors, they have a "Seth" task
which stays in a loop waiting for jobs or
requests to spawn tasks. See $LK,"APSethTask",A="MN:APSethTask"$().
requests to spawn tasks. See $LK,"CoreAPSethTask",A="MN:CoreAPSethTask"$().
$HL,1$*/
U0 TaskFocusNext()
{
CTask *task,*_task=sys_focus_task;
sys_focus_task=NULL;
if (!_task) _task=adam_task;
task=_task->next_task;
do {
if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
sys_focus_task=task;
CallExtNum(EXT_WIN_TO_TOP,task,TRUE);
return;
}
task=task->next_task;
} while (task!=_task);
}
asm {
//************************************
TASK_CONTEXT_SAVE::
//OUT: RSI=FS
PUSH RSI
@@ -147,15 +162,7 @@ _TASK_END_NOW::
CALL &TaskEnd
MOV RSI,RAX
CALL SET_FS_BASE
JMP I8 RESTORE_RSI_TASK_WITH_KEY_CHECK
RESTORE_RSI_TASK:
BT U32 [SYS_CTRL_ALT_FLAGS],SYSf_CTRL_ALT_DEL
JC I32 HANDLE_SWAP_KEY_EVENT
XOR RAX,RAX
CMP U64 GS:CCPU.idle_task[RAX],RSI
JNE RESTORE_RSI_TASK_NO_KEY_CHECK
JMP I32 SWAP_IN_SETH_TASK_IF_READY
JMP I8 RESTORE_RSI_TASK
_YIELD::
PUSHFD
@@ -189,12 +196,12 @@ _YIELD::
MOV U64 CTask.rsp[RSI],RSP
MOV RSI,U64 CTask.next_task[RSI]
RESTORE_RSI_TASK_WITH_KEY_CHECK:
RESTORE_RSI_TASK:
TEST U64 [SYS_CTRL_ALT_FLAGS],1<<SYSf_CTRL_ALT_DEL|
1<<SYSf_CTRL_ALT_TAB|1<<SYSf_CTRL_ALT_X|1<<SYSf_CTRL_ALT_C
JNZ HANDLE_SWAP_KEY_EVENT
JNZ HANDLE_SYSF_KEY_EVENT
RESTORE_RSI_TASK_NO_KEY_CHECK:
RESTORE_RSI_TASK2:
@@20: BT U64 CTask.task_flags[RSI],TASKf_KILL_TASK
JC I32 END_RSI_TASK
TEST U64 CTask.task_flags[RSI],
@@ -219,117 +226,86 @@ RESTORE_RSI_TASK_NO_KEY_CHECK:
MOV RSP,U64 CTask.stk[RAX]
ADD RSP,DFT_STK+CTaskStk.stk_base //Rst to top
CALL SET_FS_BASE
STI //Swap-in idle task so we can unmask IRQs.
STI //Restore idle task so we can unmask IRQs.
HLT
SYS_IDLE_PT::
CLI
SWAP_IN_SETH_TASK_IF_READY:
RESTORE_SETH_TASK_IF_READY:
XOR RAX,RAX
MOV RSI,GS:CCPU.seth_task[RAX]
JMP RESTORE_RSI_TASK_WITH_KEY_CHECK
JMP RESTORE_RSI_TASK
HANDLE_SWAP_KEY_EVENT:
HANDLE_SYSF_KEY_EVENT:
MOV RAX,RSI
CALL SET_FS_BASE
XOR RAX,RAX
MOV RAX,GS:CCPU.num[RAX]
XOR RBX,RBX
MOV RAX,GS:CCPU.num[RBX]
TEST RAX,RAX
JNZ I32 RESTORE_RSI_TASK_NO_KEY_CHECK
JNZ I32 RESTORE_RSI_TASK2
MOV EAX,U32 SYS_CTRL_ALT_FLAGS
LOCK
BTR U32 [RAX],SYSf_CTRL_ALT_DEL
JC I32 &Reboot
CMP U64 GS:CCPU.idle_task[RBX],RSI
JE RESTORE_SETH_TASK_IF_READY
LOCK
BTR U32 [RAX],SYSf_CTRL_ALT_TAB
JNC @@05
PUSH RSI
MOV RSI,U64 [SYS_FOCUS_TASK]
MOV U64 [SYS_FOCUS_TASK],0
CALL FOCUS_RSI_NEXT_USER
POP RSI
JMP I32 RESTORE_FS_TASK_WITH_KEY_CHECK
CALL &TaskFocusNext
JMP I32 RESTORE_FS_TASK
@@05: LOCK
BTR U32 [RAX],SYSf_CTRL_ALT_X
JC END_FOCUS_USER
LOCK
BTR U32 [RAX],SYSf_CTRL_ALT_C
JNC I32 RESTORE_RSI_TASK_WITH_KEY_CHECK
JNC I32 RESTORE_RSI_TASK
BREAK_FOCUS_USER:
MOV RSI,U64 [SYS_FOCUS_TASK]
TEST RSI,RSI
JZ SWAP_IN_SETH_TASK_IF_READY
JZ RESTORE_SETH_TASK_IF_READY
BT U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
JC I32 RESTORE_RSI_TASK_NO_KEY_CHECK
JC I32 RESTORE_RSI_TASK
LOCK
BTR U64 CTask.task_flags[RSI],TASKf_BREAK_LOCKED
JNC @@10
LOCK
BTS U64 CTask.task_flags[RSI],TASKf_PENDING_BREAK
JMP I32 RESTORE_RSI_TASK_NO_KEY_CHECK
JMP I32 RESTORE_RSI_TASK
@@10: MOV RAX,&SysThrowBreak
MOV U64 CTask.rip[RSI],RAX
BT U64 CTask.task_flags[RSI],TASKf_BREAK_TO_SHIFT_ESC
JC @@15
JC I32 RESTORE_RSI_TASK
//Do these now, in case interrupt happens.
MOV U64 CTask.wake_jiffy[RSI],0
PUSH RSI
CALL &TaskRstAwaitingMsg
@@15: JMP I32 RESTORE_RSI_TASK_NO_KEY_CHECK
JMP I32 RESTORE_RSI_TASK
END_FOCUS_USER:
MOV RSI,U64 [SYS_FOCUS_TASK]
MOV U64 [SYS_FOCUS_TASK],0
PUSH RSI
CALL FOCUS_RSI_NEXT_USER
POP RSI
CALL &TaskFocusNext
TEST RSI,RSI
JZ I32 SWAP_IN_SETH_TASK_IF_READY
JZ I32 RESTORE_SETH_TASK_IF_READY
MOV RAX,RSI
CALL SET_FS_BASE
BT U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
JC I32 RESTORE_RSI_TASK_WITH_KEY_CHECK
JC I32 RESTORE_RSI_TASK
LOCK
BTS U64 CTask.task_flags[RSI],TASKf_KILL_TASK
JMP I32 END_RSI_TASK
RESTORE_FS_TASK_WITH_KEY_CHECK:
RESTORE_FS_TASK:
XOR RSI,RSI
MOV RSI,FS:CTask.addr[RSI]
JMP I32 RESTORE_RSI_TASK_WITH_KEY_CHECK
FOCUS_RSI_NEXT_USER:
TEST RSI,RSI
JNZ @@20
MOV ESI,U32 SYS_FIXED_AREA+CSysFixedArea.adam
@@20: MOV RDI,RSI
MOV RSI,U64 CTask.next_task[RSI]
@@25: BT U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
JC @@30
CMP U64 [SYS_FOCUS_TASK],RSI
JE @@30
MOV U64 [SYS_FOCUS_TASK],RSI
MOV RAX,U64 [SYS_EXTERN_TABLE]
MOV RAX,U64 EXT_WIN_TO_TOP*8[RAX]
TEST RAX,RAX
JZ @@35
PUSH TRUE
PUSH RSI
CALL RAX
JMP @@35
@@30: MOV RSI,U64 CTask.next_task[RSI]
CMP RSI,RDI
JNE @@25
MOV U64 [SYS_FOCUS_TASK],0
@@35: RET
JMP I32 RESTORE_RSI_TASK
}
_extern _TASK_CONTEXT_RESTORE U0 TaskContextRestore(); //Restore a task context.