2020-02-15 20:01:48 +00:00
|
|
|
asm {
|
|
|
|
ALIGN 16,OC_NOP
|
|
|
|
USE16
|
2020-02-15 21:11:16 +00:00
|
|
|
//See $LK,"ZenithOS MultiCore",A="FI:::/Doc/MultiCore.DD"$.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
//This code gets copied to $LK,"MP_VECT_ADDR",A="MN:MP_VECT_ADDR"$.
|
2020-02-16 04:57:03 +00:00
|
|
|
//See $LK,"MemCopy(MP_VECT_ADDR",A="FF:::/Kernel/MultiProc.CC,MemCopy(mp:2"$.
|
2020-02-15 20:01:48 +00:00
|
|
|
COREAP_16BIT_INIT::
|
|
|
|
JMP @@05
|
|
|
|
|
|
|
|
ALIGN 4,OC_NOP
|
|
|
|
AP_GDT_PTR: DU16 sizeof(CGDT)-1;
|
|
|
|
DU64 0;
|
|
|
|
|
|
|
|
@@05: CLI
|
|
|
|
WBINVD
|
|
|
|
MOV AX,MP_VECT_ADDR/16
|
|
|
|
MOV DS,AX
|
2020-02-16 04:57:03 +00:00
|
|
|
LGDT U32 [CAP16BitInit.ap_gdt_ptr] //See $LK,"mp->ap_gdt_ptr",A="FF:::/Kernel/MultiProc.CC,mp->ap_gdt_ptr:2"$
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
MOV EAX,SYS_START_CR0
|
|
|
|
MOV_CR0_EAX
|
|
|
|
DU8 0x66,0xEA; //JMP CGDT.cs32:AP_32BIT_INIT
|
|
|
|
DU32 AP_32BIT_INIT;
|
|
|
|
DU16 CGDT.cs32;
|
|
|
|
COREAP_16BIT_INIT_END::
|
|
|
|
|
|
|
|
USE32
|
|
|
|
AP_32BIT_INIT:
|
|
|
|
MOV AX,CGDT.ds
|
|
|
|
MOV DS,AX
|
|
|
|
MOV ES,AX
|
|
|
|
MOV FS,AX
|
|
|
|
MOV GS,AX
|
|
|
|
MOV SS,AX
|
|
|
|
|
|
|
|
@@05: LOCK
|
2020-02-16 01:19:05 +00:00
|
|
|
BTS U32 [SYS_MP_COUNT_LOCK],0
|
2020-02-15 20:01:48 +00:00
|
|
|
JC @@05
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
MOV ESI,U32 [SYS_MP_COUNT_INITIAL]
|
2020-02-15 20:01:48 +00:00
|
|
|
LOCK
|
2020-02-16 01:19:05 +00:00
|
|
|
INC U32 [SYS_MP_COUNT_INITIAL]
|
2020-02-15 20:01:48 +00:00
|
|
|
LOCK
|
2020-02-16 01:19:05 +00:00
|
|
|
BTR U32 [SYS_MP_COUNT_LOCK],0
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
CMP ESI,MP_PROCESSORS_NUM
|
|
|
|
JAE I32 _SYS_HLT
|
|
|
|
|
|
|
|
IMUL2 ESI,sizeof(CCPU)
|
|
|
|
ADD ESI,U32 [SYS_CPU_STRUCTS]
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
LEA ESP,U32 CCPU.start_stack+sizeof(CCPU.start_stack)[ESI]
|
2020-02-15 20:01:48 +00:00
|
|
|
PUSH U32 RFLAGG_START
|
|
|
|
POPFD
|
|
|
|
PUSH U32 0 //Return from next call will be 64-bit
|
|
|
|
CALL SYS_ENTER_LONG_MODE
|
|
|
|
USE64
|
|
|
|
FNINIT
|
|
|
|
MOV RAX,RSI
|
|
|
|
CALL SET_GS_BASE
|
2020-02-16 20:28:10 +00:00
|
|
|
@@10: MOV RAX,U64 CCPU.daemon_task[RSI]
|
2020-02-15 20:01:48 +00:00
|
|
|
TEST RAX,RAX
|
|
|
|
JZ @@10
|
|
|
|
MOV U64 CTask.gs[RAX],RSI
|
|
|
|
CALL SET_FS_BASE
|
|
|
|
|
|
|
|
JMP I32 _TASK_CONTEXT_RESTORE
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 TSSBusy(I64 tr,Bool val=OFF)
|
2020-02-16 04:57:03 +00:00
|
|
|
{//See $LK,"::/Demo/Lectures/Ring3.CC"$.
|
2020-02-16 03:41:28 +00:00
|
|
|
LBEqual((&sys_gdt)(U8 *)+tr+4,9,val);
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CTSS *TSSNew(I64 cpu_num)
|
|
|
|
{
|
|
|
|
U32 *d,*d1;
|
|
|
|
CTSS *tss=CAlloc(sizeof(CTSS));
|
|
|
|
tss->io_map_offset=offset(CTSS.io_map);
|
|
|
|
MemSet(tss->io_map,0xFF,0x10000/8);
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
tss->st0=MAlloc(MEM_INTERRUPT_STACK);
|
2020-02-15 20:01:48 +00:00
|
|
|
tss->rsp0=tss->st0(U8 *)+MSize(tss->st0);
|
2020-02-16 01:19:05 +00:00
|
|
|
tss->st1=MAlloc(MEM_INTERRUPT_STACK);
|
2020-02-15 20:01:48 +00:00
|
|
|
tss->rsp1=tss->st1(U8 *)+MSize(tss->st1);
|
2020-02-16 01:19:05 +00:00
|
|
|
tss->st2=MAlloc(MEM_INTERRUPT_STACK);
|
2020-02-15 20:01:48 +00:00
|
|
|
tss->rsp2=tss->st2(U8 *)+MSize(tss->st2);
|
|
|
|
|
|
|
|
tss->tr =offset(CGDT.tr)+cpu_num*16;
|
|
|
|
tss->tr_ring3=offset(CGDT.tr_ring3)+cpu_num*16;
|
|
|
|
|
|
|
|
d=(&sys_gdt)(U8 *)+tss->tr;
|
|
|
|
d1=d(U8 *)+4;
|
|
|
|
*d =0x0000FFFF;
|
|
|
|
*d1=0x008F8900;
|
|
|
|
d(U8 *)+=2;
|
|
|
|
*d|=tss & 0x00FFFFFF;
|
|
|
|
*d1++|=tss & 0xFF000000;
|
|
|
|
*d1++=tss>>32;
|
|
|
|
*d1=0;
|
|
|
|
|
|
|
|
d=(&sys_gdt)(U8 *)+tss->tr_ring3;
|
|
|
|
d1=d(U8 *)+4;
|
|
|
|
*d =0x0000FFFF;
|
|
|
|
*d1=0x008FE900;
|
|
|
|
d(U8 *)+=2;
|
|
|
|
*d|=tss & 0x00FFFFFF;
|
|
|
|
*d1++|=tss & 0xFF000000;
|
|
|
|
*d1++=tss>>32;
|
|
|
|
*d1=0;
|
|
|
|
|
|
|
|
return tss;
|
|
|
|
}
|
|
|
|
|
2020-02-16 20:28:10 +00:00
|
|
|
CCPU *CPUStructInit(I64 num,CCPU *c,CTask *daemon_task)
|
|
|
|
{//Daemon is null when called by zenith on CSysFixedArea.boot_cpu0
|
2020-02-15 20:01:48 +00:00
|
|
|
MemSet(c,0,sizeof(CCPU));
|
|
|
|
c->addr=c;
|
|
|
|
c->num=num;
|
|
|
|
c->idle_factor=0.01;
|
2020-02-15 22:53:02 +00:00
|
|
|
QueueInit(&c->next_dying);
|
2020-02-15 22:25:33 +00:00
|
|
|
if (Bt(&sys_run_level,RLf_16MEG_ZENITH_HEAP_CTRL)) {
|
2020-02-15 20:01:48 +00:00
|
|
|
c->idle_task=Spawn(0,NULL,"Idle Task",,Fs,,0);
|
|
|
|
LBts(&c->idle_task->task_flags,TASKf_IDLE);
|
|
|
|
c->tss=TSSNew(num);
|
|
|
|
}
|
2020-02-16 20:28:10 +00:00
|
|
|
c->daemon_task=daemon_task;// It waits for this to be filled-in: $LK,"daemon_task",A="FF:::/Kernel/MultiProc.CC,daemon_task"$
|
2020-02-15 20:01:48 +00:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 MPInt(U8 num,I64 cpu_num=1)
|
|
|
|
{//Generate interrupt for specified core.
|
2020-02-16 00:20:04 +00:00
|
|
|
if (cpu_num>=mp_count) {
|
2020-02-15 20:01:48 +00:00
|
|
|
if (!Bt(&sys_run_level,RLf_MP))
|
|
|
|
return;
|
|
|
|
else
|
|
|
|
throw('MultCore');
|
|
|
|
}
|
|
|
|
PUSHFD
|
|
|
|
CLI //Multitasking safe because each core has a local apic and IRQ's are off
|
|
|
|
while (*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)&0x1000)
|
|
|
|
PAUSE
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_HIGH)(U32 *)=dev.mp_apic_ids[cpu_num]<<24;
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0x4000+num;
|
|
|
|
POPFD
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 MPIntAll(U8 num)
|
|
|
|
{//Generate interrupt for all but own core.
|
|
|
|
PUSHFD
|
|
|
|
CLI //Multitasking safe because each core has a local apic and IRQ's are off
|
|
|
|
while (*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)&0x1000)
|
|
|
|
PAUSE
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4800+num;
|
|
|
|
POPFD
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 MPNMInt()
|
|
|
|
{//Generate nonmaskable interrupt.
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4400;
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 MPHalt()
|
|
|
|
{//Halt all other cores.
|
2020-02-16 00:20:04 +00:00
|
|
|
mp_count=1;
|
2020-02-15 20:01:48 +00:00
|
|
|
MPNMInt;
|
|
|
|
Busy(10000);
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 MPAPICInit()
|
2020-02-15 22:25:33 +00:00
|
|
|
{//Called by zenith during start-up
|
2020-02-15 20:01:48 +00:00
|
|
|
//and other cores during initialization
|
|
|
|
//after $LK,"Core0StartMP",A="MN:Core0StartMP"$().
|
|
|
|
*(dev.uncached_alias+LAPIC_SVR)(U32 *)|=LAPICF_APIC_ENABLED;
|
|
|
|
dev.mp_apic_ids[Gs->num]=*(dev.uncached_alias+LAPIC_APIC_ID)(U32 *)>>24;
|
|
|
|
*(dev.uncached_alias+LAPIC_LDR)(U32 *)=dev.mp_apic_ids[Gs->num]<<24;
|
|
|
|
*(dev.uncached_alias+LAPIC_DFR)(U32 *)=0xF0000000;
|
|
|
|
|
|
|
|
// MemSet(dev.uncached_alias+LAPIC_IRR,0,0x20);
|
|
|
|
// MemSet(dev.uncached_alias+LAPIC_ISR,0,0x20);
|
|
|
|
// MemSet(dev.uncached_alias+LAPIC_TMR,0,0x20);
|
|
|
|
|
|
|
|
SetRAX(Gs->tss->tr);
|
|
|
|
LTR AX
|
|
|
|
if (Gs->num) {
|
|
|
|
IntInit1;
|
|
|
|
SetRFlags(RFLAGG_NORMAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#assert !offset(CJobCtrl.next_waiting)
|
|
|
|
|
2020-02-16 20:28:10 +00:00
|
|
|
U0 CoreAPDaemonTask()
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
2020-02-16 06:07:34 +00:00
|
|
|
CJobCtrl *ctrl=&Fs->server_ctrl;
|
2020-02-15 20:01:48 +00:00
|
|
|
while (TRUE) {
|
|
|
|
STI
|
|
|
|
do {
|
|
|
|
TaskKillDying;
|
|
|
|
do PAUSE
|
|
|
|
while (LBts(&ctrl->flags,JOBCf_LOCKED));
|
|
|
|
} while (ctrl->next_waiting!=ctrl && JobRunOne(GetRFlags,ctrl));
|
|
|
|
CLI
|
2020-02-15 23:56:05 +00:00
|
|
|
LBts(&Fs->task_flags,TASKf_AWAITING_MESSAGE);
|
2020-02-15 20:01:48 +00:00
|
|
|
LBtr(&ctrl->flags,JOBCf_LOCKED);
|
|
|
|
LBts(&Fs->task_flags,TASKf_IDLE);
|
|
|
|
Yield;
|
|
|
|
LBtr(&Fs->task_flags,TASKf_IDLE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-15 22:53:02 +00:00
|
|
|
CJob *JobQueue(I64 (*fp_addr)(U8 *data),U8 *data=NULL,
|
2020-02-15 20:01:48 +00:00
|
|
|
I64 target_cpu=1,I64 flags=1<<JOBf_FREE_ON_COMPLETE,
|
|
|
|
I64 job_code=JOBT_CALL,U8 *aux_str=NULL,I64 aux1=0,I64 aux2=0)
|
2020-02-16 20:28:10 +00:00
|
|
|
{//Queue multicore jobs, handled by Daemon tasks.
|
2020-02-15 20:01:48 +00:00
|
|
|
//Set flags to zero if you wish to get the res.
|
2020-02-16 04:57:03 +00:00
|
|
|
//See $LK,"::/Demo/MultiCore/Lock.CC"$
|
2020-02-15 20:01:48 +00:00
|
|
|
CJobCtrl *ctrl;
|
|
|
|
CJob *tmpc;
|
2020-02-16 20:28:10 +00:00
|
|
|
CTask *daemon;
|
2020-02-16 00:20:04 +00:00
|
|
|
if (!(0<=target_cpu<mp_count))
|
2020-02-15 20:01:48 +00:00
|
|
|
throw('MultCore');
|
2020-02-16 02:38:13 +00:00
|
|
|
tmpc=ZCAlloc(sizeof(CJob));
|
2020-02-15 20:01:48 +00:00
|
|
|
if (aux_str)
|
2020-02-16 02:38:13 +00:00
|
|
|
tmpc->aux_str=ZStrNew(aux_str);
|
2020-02-15 20:01:48 +00:00
|
|
|
tmpc->job_code=job_code;
|
|
|
|
tmpc->addr=fp_addr;
|
|
|
|
tmpc->fun_arg=data;
|
|
|
|
tmpc->flags=flags;
|
|
|
|
tmpc->aux1=aux1;
|
|
|
|
tmpc->aux2=aux2;
|
2020-02-16 20:28:10 +00:00
|
|
|
daemon=cpu_structs[target_cpu].daemon_task;
|
|
|
|
tmpc->ctrl=ctrl=&daemon->server_ctrl;
|
2020-02-15 20:01:48 +00:00
|
|
|
PUSHFD
|
|
|
|
CLI
|
|
|
|
while (LBts(&ctrl->flags,JOBCf_LOCKED))
|
|
|
|
Yield;
|
2020-02-16 20:28:10 +00:00
|
|
|
if (ctrl->next_waiting==ctrl && LBtr(&daemon->task_flags,TASKf_AWAITING_MESSAGE))
|
2020-02-15 20:01:48 +00:00
|
|
|
MPInt(I_WAKE,target_cpu);
|
2020-02-15 22:53:02 +00:00
|
|
|
QueueInsert(tmpc,ctrl->last_waiting);
|
2020-02-15 20:01:48 +00:00
|
|
|
LBtr(&ctrl->flags,JOBCf_LOCKED);
|
|
|
|
POPFD
|
|
|
|
return tmpc;
|
|
|
|
}
|
|
|
|
|
2020-02-15 22:53:02 +00:00
|
|
|
CTask *SpawnQueue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,
|
2020-02-15 22:25:33 +00:00
|
|
|
I64 target_cpu, CTask *parent=NULL, //NULL means zenith
|
2020-02-16 01:19:05 +00:00
|
|
|
I64 stack_size=0,I64 flags=1<<JOBf_ADD_TO_QUE)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CTask *res;
|
2020-02-15 22:53:02 +00:00
|
|
|
CJob *tmpc=JobQueue(fp_addr,data,target_cpu,
|
2020-02-16 01:19:05 +00:00
|
|
|
flags,JOBT_SPAWN_TASK,task_name,parent,stack_size);
|
2020-02-15 20:01:48 +00:00
|
|
|
CJobCtrl *ctrl;
|
|
|
|
|
|
|
|
while (!Bt(&tmpc->flags,JOBf_DONE)) {
|
|
|
|
LBts(&Fs->task_flags,TASKf_IDLE);
|
|
|
|
Yield;
|
|
|
|
}
|
|
|
|
LBtr(&Fs->task_flags,TASKf_IDLE);
|
|
|
|
|
|
|
|
res=tmpc->spawned_task;
|
|
|
|
ctrl=tmpc->ctrl;
|
|
|
|
PUSHFD
|
|
|
|
CLI
|
|
|
|
while (LBts(&ctrl->flags,JOBCf_LOCKED))
|
|
|
|
Yield;
|
2020-02-15 23:13:27 +00:00
|
|
|
QueueRemove(tmpc);
|
2020-02-15 20:01:48 +00:00
|
|
|
LBtr(&ctrl->flags,JOBCf_LOCKED);
|
|
|
|
POPFD
|
|
|
|
JobDel(tmpc);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2020-02-16 20:28:10 +00:00
|
|
|
U0 CoreAPDaemonInit()
|
|
|
|
{//Called by multicore's daemon dask after $LK,"Core0StartMP",A="MN:Core0StartMP"$()
|
2020-02-15 20:01:48 +00:00
|
|
|
//as the first thing a CPU does before waiting for jobs.
|
|
|
|
MPAPICInit;
|
2020-02-16 20:28:10 +00:00
|
|
|
Fs->rip=&CoreAPDaemonTask;
|
2020-02-15 20:01:48 +00:00
|
|
|
TaskContextRestore;
|
|
|
|
}
|
|
|
|
|
|
|
|
U0 Core0StartMP()
|
2020-02-16 04:57:03 +00:00
|
|
|
{//Called by zenith during $LK,"start-up",A="FF:::/Kernel/KMain.CC,Core0StartMP"$.
|
2020-02-15 20:01:48 +00:00
|
|
|
CTask *task;
|
|
|
|
U8 buf[STR_LEN];
|
|
|
|
CAP16BitInit *mp=MP_VECT_ADDR;
|
|
|
|
CCPU *c;
|
2020-02-16 00:20:04 +00:00
|
|
|
I64 i,my_mp_count;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
PUSHFD
|
|
|
|
CLI
|
2020-02-16 00:20:04 +00:00
|
|
|
if (mp_count>1) {
|
|
|
|
my_mp_count=mp_count;
|
|
|
|
MPHalt; //sets mp_count to 1
|
|
|
|
for (i=1;i<my_mp_count;i++) {
|
2020-02-15 20:01:48 +00:00
|
|
|
c=&cpu_structs[i];
|
2020-02-16 20:28:10 +00:00
|
|
|
JobQueueDel(&c->daemon_task->server_ctrl.next_waiting);
|
|
|
|
JobQueueDel(&c->daemon_task->server_ctrl.next_done);
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
MemSet(&cpu_structs[1],0,sizeof(CCPU)*(MP_PROCESSORS_NUM-1));
|
|
|
|
|
|
|
|
//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$.
|
2020-02-16 03:32:01 +00:00
|
|
|
MemCopy(mp,COREAP_16BIT_INIT,COREAP_16BIT_INIT_END-COREAP_16BIT_INIT);
|
|
|
|
MemCopy(&mp->ap_gdt_ptr,SYS_GDT_PTR,sizeof(CSysLimitBase));
|
2020-02-16 00:20:04 +00:00
|
|
|
mp_count_initial=mp_count=1;
|
|
|
|
mp_count_lock=0;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
*(dev.uncached_alias+LAPIC_LVT_ERR)(U32 *)=
|
|
|
|
*(dev.uncached_alias+LAPIC_LVT_ERR)(U32 *)&0xFFFFFF00+MPN_VECT;
|
2020-02-16 03:32:01 +00:00
|
|
|
WBINVD //Not sure why this is needed. Might just need delay. $LK,"MemCopy",A="MN:MemCopy"$ above?
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4500; //assert init IPI
|
|
|
|
Busy(10000);
|
|
|
|
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4600+MPN_VECT; //start-up
|
|
|
|
Busy(200);
|
|
|
|
*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4600+MPN_VECT;
|
|
|
|
|
|
|
|
Busy(100000);
|
|
|
|
for (i=0;i<10000;i++)
|
2020-02-16 00:20:04 +00:00
|
|
|
LBts(&mp_count_lock,0); //Don't let more through
|
|
|
|
my_mp_count=mp_count_initial;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
if (my_mp_count>MP_PROCESSORS_NUM)
|
|
|
|
my_mp_count=MP_PROCESSORS_NUM;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
for (i=1;i<my_mp_count;i++) {
|
2020-02-16 20:28:10 +00:00
|
|
|
StrPrint(buf,"Daemon Task CPU%02X",i);
|
|
|
|
task=Spawn(&CoreAPDaemonInit,NULL,buf,,,MEM_DAEMON_STACK,0);
|
2020-02-15 20:01:48 +00:00
|
|
|
task->rflags=RFLAGG_START;
|
2020-02-16 20:28:10 +00:00
|
|
|
//$LK,"CTask",A="MN:CTask"$ alloced off this core's daemon_task's heap (Which is Zenith)
|
2020-02-15 20:01:48 +00:00
|
|
|
CPUStructInit(i,&cpu_structs[i],task);
|
|
|
|
WBINVD //Not sure why this is needed. Might just need delay.
|
|
|
|
}
|
|
|
|
|
|
|
|
//Make sure they're all up-and-running
|
2020-02-16 21:00:55 +00:00
|
|
|
for (i = 1; i < my_mp_count;i++)
|
2020-02-16 20:28:10 +00:00
|
|
|
while (!Bt(&cpu_structs[i].daemon_task->task_flags,TASKf_AWAITING_MESSAGE))
|
2020-02-15 20:01:48 +00:00
|
|
|
PAUSE;
|
|
|
|
|
|
|
|
POPFD
|
2020-02-16 00:20:04 +00:00
|
|
|
mp_count=my_mp_count; //Finalize count
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
U0 Core0Init()
|
2020-02-15 22:25:33 +00:00
|
|
|
{//Called by zenith during start-up
|
2020-02-16 00:20:04 +00:00
|
|
|
mp_count_initial=mp_count=1;
|
|
|
|
mp_count_lock=0;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
2020-02-16 03:37:50 +00:00
|
|
|
debug.mp_crash=ZCAlloc(sizeof(CMPCrash));
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
//Must be in code heap because init code uses 32 bit addr of cpu_struct
|
2020-02-16 21:00:55 +00:00
|
|
|
zenith_task->gs=cpu_structs=CAlloc(sizeof(CCPU)*MP_PROCESSORS_NUM,Fs->code_heap);
|
2020-02-15 22:25:33 +00:00
|
|
|
CPUStructInit(0,cpu_structs,zenith_task);
|
2020-02-16 21:00:55 +00:00
|
|
|
//RAX has GS
|
|
|
|
IMPORT SET_GS_BASE;
|
|
|
|
CALL SET_GS_BASE
|
|
|
|
|
2020-02-19 09:08:21 +00:00
|
|
|
MPAPICInit;
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
interrupt U0 IntMPCrash()
|
|
|
|
{//Entering the debugger from another core causes an interrupt on Core0
|
|
|
|
//Which calls this routine.
|
|
|
|
*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
|
2020-02-16 00:20:04 +00:00
|
|
|
mp_count=1;
|
2020-02-15 20:01:48 +00:00
|
|
|
Raw(ON);
|
2020-02-19 09:08:21 +00:00
|
|
|
text.raw_flags|=RAWF_SHOW_DOLLAR;
|
2020-02-15 20:01:48 +00:00
|
|
|
"MP Crash CPU%02X Task:%08X\n"
|
2020-02-16 03:37:50 +00:00
|
|
|
"RIP:%P\n",debug.mp_crash->cpu_num,debug.mp_crash->task,debug.mp_crash->rip;
|
|
|
|
Panic(debug.mp_crash->message,debug.mp_crash->message_num);
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|