TempleOSCDV4.03.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:47:01 +02:00
1 parent 1541d7328d
commit 0f1a4a5d65
115 files changed
+5618 -4863

No files matched your search

+202
View File
@@ -0,0 +1,202 @@
//This file is required by $LK,"::/Demo/Lectures/Mem/Uncached.CPP"$.
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-MEM_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<<MEM_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)>>MEM_PAGE_BITS) {
j=1<<(21-MEM_PAGE_BITS)-i;
if (result->pages<num+j)
m=result;
else if (result->pages==num+j) {
result->pages-=num;
result(U8 *)+=result->pages<<MEM_PAGE_BITS;
result->pages=num;
goto am_done;
} else {
m1=result;
result(U8 *)+=j<<MEM_PAGE_BITS;
result->pages=num;
m=result(U8 *)+num<<MEM_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<<MEM_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<<MEM_PAGE_BITS;
bp->used_u8s+=i;
num>>=21-MEM_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-MEM_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
}
}
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)+MEM_PAGE_SIZE-1)&
~(MEM_PAGE_SIZE-1);
num=(bp(U8 *)+pages512<<MEM_PAGE_BITS-m(U8 *))>>MEM_PAGE_BITS;
bp->alloced_u8s=(pages512-num)<<MEM_PAGE_BITS;
BlkPoolAdd(bp,m,num);
return hc;
}
/* PCI hardware devices, when they require uncached memory buffers, need
this code. TempleOS, however, has a law requiring only IN/OUT port hardware
access except VGA, handled here: $LK,"::/Kernel/Mem/PageTables.CPP"$.
*/
+47
View File
@@ -0,0 +1,47 @@
/*What's funner than page tables for programmers to play with!!
This changes a page table entry for VGA graphics memory.
TempleOS keeps a cached copy of VGA memory in
$LK,"gr.screen_image",A="MN:CGrGlbls"$. See $LK,"GrUpdateVGAGraphics",A="MN:GrUpdateVGAGraphics"$.
TempleOS used 4096 size pages for memory below addr 2 Meg
and 2 Meg pages above two Meg. See $LK,"MemPageSize",A="MN:MemPageSize"$() and $LK,"INIT_MEMORY",A="FF:::/Kernel/Mem/PageTables.CPP,SYS_INIT_MEM"$.
*/
U0 PageTableDemo1()
{
I64 *pte=MemPageTable(VGAM_GRAPHICS),p0,p1;
"Page table entries for VGA screen memory\n";
DocD(pte);
PressAKey;
p0=pte[0];
p1=pte[1];
pte[0]=p1;
pte[1]=p0;
InvlPg(VGAM_GRAPHICS); //Invalidate translation look aside buffer (TLB).
InvlPg(VGAM_GRAPHICS+0x1000);
//Use this if you wish to change
//the page table reg.
// SetRAX(0x100000+0x1000*(MEM_NUM_PML1+MEM_NUM_PML2+MEM_NUM_PML3));
// MOV_CR3_EAX
//<CTRL-ALT-v> will flush screen VGA cache.
VGAFlush;
PressAKey;
pte[0]=p0;
pte[1]=p1;
InvlPg(VGAM_GRAPHICS);
InvlPg(VGAM_GRAPHICS+0x1000);
//<CTRL-ALT-v> will flush screen VGA cache.
VGAFlush;
}
PageTableDemo1;
//See $LK,"CBlkPool",A="MN:CBlkPool"$, $LK,"CHeapCtrl",A="MN:CHeapCtrl"$, $LK,"sys_code_bp",A="MN:sys_code_bp"$ and $LK,"sys_data_bp",A="MN:sys_data_bp"$.
//See $LK,"Memory Overview",A="FI:::/Doc/MemOverview.TXT"$ and $LK,"Memory Routines",A="HI:Memory"$.
+37
View File
@@ -0,0 +1,37 @@
I64 *addr=VGAM_GRAPHICS,
*pte_addr=MemPageTable(addr),
err_code=0,
*reported_fault_addr;
/*
0[RBP]=old base ptr
8[RBP]=err code
16[RBP]=RIP
24[RBP]=RIP_SELECTOR
32[RBP]=RFLAGS
40[RBP]=RSP
48[RBP]=STK_SELECTOR
*/
interrupt haserrcode U0 IntPageFault()
{
I64 reg *rbp=GetRBP;
*pte_addr|=1;
InvlPg(addr);
err_code=rbp[1];
MOV_RAX_CR2
reported_fault_addr=GetRAX;
}
U0 PageTableDemo2()
{
U8 *old_idte=IntEntrySet(I_PAGE_FAULT,&IntPageFault,IDTET_IRQ);
err_code=0;
*pte_addr &=~1; //Not present
InvlPg(addr);
WinMgrSync; //wait for VGA update
WinMgrSync;
IntEntrySet(I_PAGE_FAULT,old_idte,IDTET_IRQ);
"Err Code:%X Addr:%X\n",err_code,reported_fault_addr;
}
PageTableDemo2;
+46
View File
@@ -0,0 +1,46 @@
// Requires $LK,"::/Demo/Lectures/Mem/Mem2Meg.CPP"$.
Cd(__DIR__);;
#include "Mem2Meg"
#define SAMPLE_SIZE 100000
U0 TimeIns()
{
I64 i,start,end;
I64 *cached_I64=MAlloc(sizeof(I64)),
shared_blks,*uncached_I64;
CBlkPool *bp;
CHeapCtrl *hc;
"$$RED$$Now, this demo seems broken, perhaps,\n"
"because I run in a virtual machine.$$FG$$\n\n";
CPURep;
shared_blks=1;
bp=Mem2MegUncachedAlloc(&shared_blks);
hc=HeapCtrlBPInit(bp,shared_blks<<12);
uncached_I64=MAlloc(sizeof(I64),hc);
//Measure cached time
start=GetTSC;
for (i=0;i<SAMPLE_SIZE;i++)
*cached_I64=i;
end=GetTSC;
" Cached Cycles: %10,d\n",end-start;
//Measure uncached time
start=GetTSC;
for (i=0;i<SAMPLE_SIZE;i++)
*uncached_I64=i;
end=GetTSC;
"Uncached Cycles: %10,d\n",end-start;
"$$GREEN$$The difference is even greater\n"
"because the loop overhead was not subtracted.$$FG$$\n\n";
Free(cached_I64);
Free(uncached_I64);
Mem2MegFree(bp,shared_blks);
}
TimeIns;