Project: OSMain
asm {
USE16
        JMP     U2 LOSETHOS_START2
// ************************************
//  ASM Global variables required for 16-bit start-up

//Must match OSMainStruct
        ALIGN   4,OC_NOP
SYS_BOOT_BASE::         DU4     ?;      //Fixed offset from start used by reboot
SYS_BOOT_HEADER_BASE::  DU4     ?;
#exe {StreamPrintF("SYS_COMPILE_TIME:: DU8 0x%X;",GetCurTimeLTDate);}

//See BootCdProbe
#assert SYS_COMPILE_TIME+8+16<CD_BLK_SIZE

SYS_OS_32START::        DU4     INIT_OS;
SYS_BOOT_CODE::         DU4     0xFF;
SYS_MEM_E801::          DU2     0,0;
SYS_MEM_E820::          DU1     NUM_MEM_E820_ENTRIES*MEM_E820_ENTRY_SIZE DUP (0);

        ALIGN   16,OC_NOP
SYS_GDTTAB:: //See SELECTORS
GDT_NULL:               DU8     0,0;
GDT_BOOT_DS:            DU8     0,0; //gets filled-in
GDT_BOOT_CS:            DU8     0,0; //gets filled-in
GDT_CS:                 DU8     0x00CF9A000000FFFF,0;
GDT_CS64:               DU8     0x00209A0000000000,0;
GDT_ZERO_DS:            DU8     0x00CF92000000FFFF,0;
GDT_CPU_TRS:            DU1     MP_MAX_PROCESSORS*16 DUP(0); //gets filled-in

SYS_GR_MODE::           DU2     0;
SYS_PCI_BUSSES::        DU2     0;
        ALIGN   8,OC_NOP
SYS_ADAM_TASK::         DU1     TASK_STRUCT_SIZE DUP(0);
SYS_ADAM_HC::           DU1     HC_STRUCT_SIZE DUP(0);
SYS_TEMP_PTR::          DU4     0,0,0;
SYS_RUN_LEVEL::         DU4     0;

// ************************************
//EBX is SYS_BOOT_CODE (value passed from boot blk)
LOSETHOS_START2::
        MOV     AX,(BOOT_RAM_LIMIT-BOOT_STK_SIZE)/16
        MOV     SS,AX
        MOV     SP,BOOT_STK_SIZE
        PUSH    EBX             //will be SYS_BOOT_CODE
        MOV     AX,VGA_TEXT_MEM_BASE/16
        MOV     ES,AX
        MOV     U4 ES:[0],'L'+0x1000+('T'+0x2000)<<16
        MOV     U4 ES:[4],0

//      MOV     ECX,1000000
//      CALL    BUSY_WAIT

        CALL    U2 GET_IP
GET_IP:
        POP     BX
        SUB     BX,GET_IP
        SHR     BX,4
        MOV     AX,CS
        ADD     AX,BX
        PUSH    AX
        PUSH    U2 LOSETHOS_START3
        RETF
LOSETHOS_START3::
//XSUM OSMain
        MOV     AX,CS
        DEC     AX
        MOV     DS,AX
        XOR     ESI,ESI
        MOV     ECX,U4 8[ESI]   //Get length
        SHR     ECX,4
        MOV     EBX,LT_XSUM
@@2:    LODSD
        XOR     EBX,EAX
        LODSD
        XOR     EBX,EAX
        LODSD
        XOR     EBX,EAX
        LODSD
        XOR     EBX,EAX
        XOR     ESI,ESI
        MOV     AX,DS
        INC     AX
        MOV     DS,AX
        LOOP    @@2

//If you debug, use text video mem
        MOV     U4 ES:[4],'O'+65536*'K'+0xF000F000

//      MOV     ECX,1000000
//      CALL    BUSY_WAIT

        OR      EBX,EBX
        JZ      LOSETHOS_CONT_START

//XSUM Error
        MOV     U4 ES:[4],'X'+65536*'M'+0xF000F000

//      MOV     ECX,1000000
//      CALL    BUSY_WAIT

@@3:    JMP     @@3

BUSY_WAIT::
@@1:    IN      AL,0x21
        DEC     ECX
        JNZ     @@1
        RET
// ************************************
LOSETHOS_CONT_START:
        STI
        MOV     AX,CS
        MOV     DS,AX

        MOV     U4 [SYS_RUN_LEVEL],RLF_16BIT

#exe {StreamPrintF("MOV BX,%d\r\n",osmain_cfg->new_gr_mode);};
        MOV     U2 [SYS_GR_MODE],BX
        MOV     AX,0x4F02
#exe {
  if (!osmain_cfg->opts[CFG_TEXT_MODE])
    StreamPutS("INT 0x10");  //Enable VGA
};
        CMP     AX,0x004F
        JE      @@10
        MOV     U2 [SYS_GR_MODE],0 //failed
@@10:

/****
//Enable mouse
        MOV     AX,0xC200 //Enable
        MOV     BX,0x0100
        INT     0x15
        MOV     AX,0xC201 //Reset
        INT     0x15
        MOV     AX,0xC200 //Enable
        MOV     BX,0x0100
        INT     0x15
        MOV     AX,0xC202 //Sample
        MOV     BX,0x0500 //100
        INT     0x15
        MOV     AX,0xC203 //Resolution
        MOV     BX,0x0300 //8 per mm
        INT     0x15
        MOV     AX,0xC205 //pkt size
        MOV     BX,0x0300
        INT     0x15
        MOV     AX,0xC200 //Enable
        MOV     BX,0x0100
        INT     0x15
****/

//Get mem maps
        MOV     AX,0xE801
        INT     0x15
        MOV     U2 [SYS_MEM_E801],CX
        MOV     U2 [SYS_MEM_E801+2],DX

        MOV     CX,NUM_MEM_E820_ENTRIES-1 //Leave one to terminate
        XOR     EBX,EBX
        MOV     AX,DS
        MOV     ES,AX
        MOV     DI,SYS_MEM_E820
@@20:   PUSH    CX
        MOV     EAX,0xE820
        MOV     ECX,MEM_E820_ENTRY_SIZE
        MOV     EDX,'PAMS'
        INT     0x15
        JC      @@21
        CMP     EAX,'PAMS'
        JNE     @@21
        OR      EBX,EBX
        JZ      @@21
        ADD     DI,MEM_E820_ENTRY_SIZE
        POP     CX
        LOOP    @@20
        JMP     @@22
@@21:   ADD     SP,2

//Get PCI Bus Info
@@22:   MOV     U2 [SYS_PCI_BUSSES],256
        XOR     DX,DX
        MOV     AX,0xB101
        INT     0x1A
        CMP     DX,'P'+'C'*256
        JNE     @@30
        MOV     CH,0
        INC     CX
        MOV     U2 [SYS_PCI_BUSSES],CX
@@30:

        CLI
//Enable A20
        IN      AL,0x92
        OR      AL,2
        OUT     0x92,AL

        CLD                     //Start with known registers
        MOV     AX,CS
        MOV     DS,AX
        MOV     ES,AX
        MOV     FS,AX
        MOV     GS,AX
        XOR     EAX,EAX
        XOR     EBX,EBX
        XOR     ECX,ECX
        XOR     EDX,EDX
        XOR     ESI,ESI
        XOR     EDI,EDI
        XOR     EBP,EBP

        XOR     EAX,EAX
        MOV     AX,CS
        SHL     EAX,4
        MOV     U4 [SYS_BOOT_BASE],EAX

        POP     U4 [SYS_BOOT_CODE]

        MOV     BX,CS
        DEC     BX
        MOV     GS,BX
        MOV     EBX,U4 GS:[4]
        ADD     EAX,EBX
        SUB     EAX,16
        MOV     U4 [SYS_BOOT_HEADER_BASE],EAX

        MOV     U4 [GDT_BOOT_DS],0x0000FFFF
        MOV     U4 [GDT_BOOT_DS+4],0x0CF9200
        MOV     U4 [GDT_BOOT_CS],0x0000FFFF
        MOV     U4 [GDT_BOOT_CS+4],0x0CF9A00
        MOV     EAX,U4 [SYS_BOOT_BASE]
        ADD     U4 [GDT_BOOT_DS+2],EAX
        ADD     U4 [GDT_BOOT_CS+2],EAX

                                        // SETUP PTR TO LIMIT AND BASE
                                        //OF GDT.  USE ENTRY (0) BECAUSE IT IS
                                        //INVALID.
        MOV     U2 [SYS_TEMP_PTR],GDTTAB_SIZE-1
        MOV     EAX,U4 [SYS_BOOT_BASE]
        ADD     EAX,SYS_GDTTAB
        MOV     U4 [SYS_TEMP_PTR+2],EAX
        MOV     U2 [SYS_TEMP_PTR+6],0

        LGDT    U4 [SYS_TEMP_PTR]
        MOV     EAX,SYS_START_CR0
        MOV_CR0_EAX

/*
The assembler doesn't support far jumps so we hand code it.
16-bit code is not important enough for me to implement
16-bit mode in the assembler fully.

To complete the switch to 32-bit mode, we have to load
the code segment with a far jump.
*/
        DU1     0x66,0xEA;               //JMP SYS_CS_SEL:INIT_OS
        DU4     INIT_OS;
        DU2     SYS_BOOT_CS_SEL;

#assert $+16<=0xFFFF
USE32
// ************************************
//  ASM Global variables not required for 16-bit start-up
        ALIGN   8,OC_NOP
SYS_HEAP_BASE::         DU8     0x100000+0x1000*(NUM_PML1+NUM_PML2+NUM_PML3+NUM_PML4);
SYS_HEAP_LIMIT::        DU8     0;

#exe {
  StreamPrintF(
"SYS_MEM_INIT_FLAG::    DU1     %d;"
"SYS_MEM_INIT_VAL::     DU1     %d;"
"SYS_HEAP_INIT_FLAG::   DU1     %d;"
"SYS_HEAP_INIT_VAL::    DU1     %d;"
"SYS_VAR_INIT_FLAG::    DU1     %d;"
"SYS_VAR_INIT_VAL::     DU1     %d;",
osmain_cfg->opts[CFG_MEM_INIT], osmain_cfg->mem_init_val,
osmain_cfg->opts[CFG_HEAP_INIT],osmain_cfg->heap_init_val,
osmain_cfg->opts[CFG_VAR_INIT], osmain_cfg->var_init_val);
};
SYS_HEAP_DBG_FLAG::             DU1     _CFG_HEAP_DBG;
                        DU1     0; //pad

SYS_CTRL_ALT_FLAGS::    DU8     0;

SYS_CUR_SCAN_CODE::     DU8     0;
SYS_EXTERN_TABLE::      DU8     0;

SYS_BP_START::
SYS_BP_LOCKED_FLAGS::   DU8     0;
SYS_BP_SIZE::           DU8     0;
SYS_BP_MEM_FREE_LIST::          DU8     0;
SYS_BP_MEM_FREE_2MEG_LIST::     DU8     0;
SYS_BP_FREE_PAGE_HASH:: DU8     FREE_PAGE_HASH_SIZE DUP(0);
SYS_BP_FREE_PAGE_HASH2::        DU8     64 DUP(0);

SYS_CODE_BP::           DU8     0;
SYS_DATA_BP::           DU8     0;

SYS_PROGRESS_VALS::
SYS_PROGRESS1::         DU8     0;
SYS_PROGRESS2::         DU8     0;
SYS_PROGRESS3::         DU8     0;
SYS_PROGRESS4::         DU8     0;

SYS_PROGRESS_MAXES::
SYS_PROGRESS1_MAX::     DU8     0;
SYS_PROGRESS2_MAX::     DU8     0;
SYS_PROGRESS3_MAX::     DU8     0;
SYS_PROGRESS4_MAX::     DU8     0;

SYS_PROGRESS_DESCS::
SYS_PROGRESS1_DESC::    DU8     0;
SYS_PROGRESS2_DESC::    DU8     0;
SYS_PROGRESS3_DESC::    DU8     0;
SYS_PROGRESS4_DESC::    DU8     0;


SYS_CUR_FOCUS_TASK::    DU8     0;
SYS_TASK_BEING_SCREEN_UPDATED:: DU8     0;
SYS_TIMER::             DU8     1;
SYS_JIFFIES::           DU8     1;
SYS_CPU_STRUCTS::       DU8     0;
SYS_MP_CNT::            DU8     1;
SYS_MP_CNT_LOCK::       DU8     0;
SYS_TEMP_CPU0_STRUCT::  DU1     CPU_STRUCT_SIZE DUP (0);

        ALIGN   DEFAULT_CACHE_LINE_WIDTH,OC_NOP
SYS_CACHE_LINE_WIDTH::  DU8     DEFAULT_CACHE_LINE_WIDTH;
//Align to cache-line boundary,
// compensating for 16 byte segment header
        DU1     DEFAULT_CACHE_LINE_WIDTH-16-8 DUP(0);
SYS_SEMA_IRQS::         DU1     NUM_IRQ_SEMAS*SEMA_STRUCT_SIZE DUP(0);
SYS_SEMAS::             DU1     NUM_SYS_SEMAS*SEMA_STRUCT_SIZE DUP(0);
        ALIGN   16,OC_NOP
SYS_INIT_FPU_MMX::      DU1     sizeof(FPUState) DUP(0);
// ************************************
        ALIGN   16,OC_NOP
INIT_OS:: //Entry point for RAM reboots.
        PUSH    U4 SYS_START_RFLAGS
        POPFD
        MOV     EAX,SYS_START_CR0
        MOV_CR0_EAX

        MOV     AL,0xFF
        OUT     0x21,AL //mask interrupts
        OUT     0xA1,AL

        MOV     AX,SYS_BOOT_DS_SEL      //LOAD DS SELECTOR
        MOV     DS,AX
        MOV     ES,AX

        MOV     EAX,U4 [SYS_RUN_LEVEL]
        AND     EAX,RLF_16BIT
        OR      EAX,RLF_32BIT
        MOV     U4 [SYS_RUN_LEVEL],EAX

//Patch absolute addresses
        MOV     ESI,U4 [SYS_BOOT_HEADER_BASE]
        MOV     EDI,U4 [SYS_BOOT_BASE]
        MOV     AX,ZERO_DS_SEL
        MOV     DS,AX
        MOV     ES,AX
        MOV     ECX,U4 1+1+4+1[ESI]
        LEA     ESI,U4 1+4+1+1+4+1[ESI]
@@10:   LODSD
        ADD     EAX,EDI
        ADD     U4 [EAX],EDI
        LOOP    @@10

        MOV     AX,ZERO_DS_SEL
        MOV     DS,AX
        MOV     ES,AX
        MOV     FS,AX
        MOV     GS,AX
        MOV     SS,AX
        MOV     ESP,BOOT_RAM_LIMIT //Temp Stack

        DU1     0xEA; //JMP SYS_CS_SEL:CONT_INIT_OS
        DU4     CONT_INIT_OS;
        DU2     SYS_CS_SEL;

CONT_INIT_OS::
        LOCK
        BTS     U4 [SYS_RUN_LEVEL],RLf_PATCHED

        XOR     EAX,EAX
        MOV     U4 [SYS_CTRL_ALT_FLAGS],EAX
        MOV     U4 [SYS_CTRL_ALT_FLAGS+4],EAX
        MOV     EDI,U4 SYS_SEMAS
        MOV     ECX,NUM_SYS_SEMAS*SEMA_STRUCT_SIZE/4
        REP_STOSD
        
        CALL    FIND_BIOS32_SERVICE_DIR
        CALL    FIND_PCI_SERVICES

        MOV     U4 [SYS_HEAP_BASE],0x100000+0x1000*(NUM_PML1+NUM_PML2+NUM_PML3+NUM_PML4)
        CALL    INIT_MEM

        PUSH    U4 0
        CALL    INIT_EM64T
USE64
        LOCK
        BTS     U4 [SYS_RUN_LEVEL],RLf_64BIT

        FNINIT
        FXSAVE  U8 [SYS_INIT_FPU_MMX]

//INIT CPU0 STRUCT
        PUSH    U4 SYS_TEMP_CPU0_STRUCT
        PUSH    0
        CALL    _INIT_CPU_STRUCT
        ADD     RSP,16

        PUSH    RAX
        CALL    _SET_GS_BASE
        ADD     RSP,8

//INIT ADAM TASK
        MOV     RDI,U4 SYS_ADAM_TASK
        MOV     RCX,TASK_STRUCT_SIZE
        XOR     RAX,RAX
        REP_STOSB

//INIT ADAM HC
        MOV     RDI,U4 SYS_ADAM_HC
        MOV     RCX,HC_STRUCT_SIZE
        XOR     RAX,RAX
        REP_STOSB
        MOV     RDI,U4 SYS_ADAM_HC
        MOV     RAX,U4 SYS_BP_START
        MOV     U8 HC_BP[RDI],RAX
        MOV     U4 HC_SIGNATURE[RDI],HEAP_CTRL_SIGNATURE_VAL

        
        LEA     RAX,U8 HC_NEXT_UM-UM_NEXT[RDI]
        MOV     U8 HC_NEXT_UM[RDI],RAX
        MOV     U8 HC_LAST_UM[RDI],RAX

        MOV     RAX,U4 SYS_ADAM_TASK
        MOV     U8 HC_MEM_TASK[RDI],RAX
        MOV     U8 TASK_CODE_HEAP[RAX],RDI
        MOV     U8 TASK_DATA_HEAP[RAX],RDI
        MOV     U4 TASK_SIGNATURE[RAX],TASK_SIGNATURE_VAL
        MOV     U4 TASK_IN_QUEUE_SIGNATURE[RAX],TASK_IN_QUEUE_SIGNATURE_VAL
        
        LOCK
        BTS     U4 [SYS_RUN_LEVEL],RLf_BOOT_HEAP

        PUSH    ADAM_STACK
        PUSH    U4 SYS_ADAM_TASK
        CALL    _INIT_TASK
        ADD     RSP,16
        CALL    SET_FS_BASE
        MOV     RSP,U8 TASK_RSP[RAX]

        CALL    _INIT_IDT
        JMP     I4 _OS_MAIN
//Continues _OS_MAIN

// ************************************
USE32
INIT_EM64T:
        MOV_EAX_CR4
        OR      EAX,0xB0
        MOV_CR4_EAX

        MOV     EAX,0x100000+0x1000*(NUM_PML1+NUM_PML2+NUM_PML3)
        MOV_CR3_EAX

        MOV     ECX,IA32_EFER
        XOR     EDX,EDX
        MOV     EAX,IA32F_LME
        WRMSR

        MOV_EAX_CR0
        OR      EAX,0x80000000  //enable paging
        MOV_CR0_EAX

        DU1     0xEA;      //JMP SYS_CS64_SEL:EM64T_PART3
        DU4     EM64T_PART3;
        DU2     SYS_CS64_SEL;

USE64
EM64T_PART3:
        RET

// ************************************
SYS_RESTART_OSMAIN::
        XOR     RDI,RDI
        MOV     EDI,U4 SYS_BOOT_BASE
        MOV     EDI,U4 [RDI]
        XOR     RSI,RSI
        MOV     ESI,U4 SYS_OS_32START
        MOV     ESI,U4 [RSI]
        ADD     ESI,EDI

        PUSH    U4 ZERO_DS_SEL  //STACKSEG
        PUSH    U4 0x9C000      //STACK
        PUSH    U4 0            //FLAGS
        PUSH    U4 SYS_CS_SEL
        CALL    @@2
@@2:    POP     RAX
        ADD     RAX,@@3-@@2
        PUSH    RAX
        IRET
USE32
@@3:
        WBINVD
//disable paging
        MOV_EAX_CR0
        BTR     EAX,31
        MOV_CR0_EAX

        MOV     ECX,IA32_EFER
        XOR     EDX,EDX
        XOR     EAX,EAX
        WRMSR

        MOV     EBX,BOOT_CODE_RAM
        JMP     ESI
USE64
SYS_RESTART_OSMAIN_END::
}
Historical capture: 2010-01-29. Home | Power on LoseThos | Sources and changes