#include "assym.h"
#include "ksyms.h"
#include <machine/param.h>
#include <machine/pte.h>
#include <machine/specialreg.h>
#include <dev/isa/isareg.h>
#define ALIGN_DATA .align 4
#define ALIGN_TEXT .align 4,0x90
#define _ALIGN_TEXT ALIGN_TEXT
#include <machine/asm.h>
.data
.space 512,0xcc
tmpstk:
#define RELOC(x) ((x) - KERNBASE)
.text
.globl start
.globl kernel_text
kernel_text = KERNTEXTOFF
start: movw $0x1234,0x472 # warm boot
movl 4(%esp),%eax
movl %eax,RELOC(boothowto)
movl 8(%esp),%eax
movl %eax,RELOC(bootdev)
movl 16(%esp),%eax
testl %eax,%eax
jz 1f
addl $KERNBASE,%eax
1: movl %eax,RELOC(esym)
movl $__kernel_bss_end, RELOC(ssym)
movl 12(%esp),%eax
movl %eax,RELOC(bootapiver)
movl 28(%esp), %eax
movl %eax, RELOC(bootargc)
movl 32(%esp), %eax
movl %eax, RELOC(bootargv)
pushl $PSL_MBO
popfl
xorl %eax,%eax
movw %ax,%fs
movw %ax,%gs
.Ltry486:
pushfl
popl %eax
movl %eax,%ecx
xorl $PSL_ID,%eax
pushl %eax
popfl
pushfl
popl %eax
xorl %ecx,%eax
andl $PSL_ID,%eax
pushl %ecx
popfl
testl %eax,%eax
jnz .Ltry586
.Lis486:
jmp 2f
.Ltry586:
xorl %eax,%eax
cpuid
movl %eax,RELOC(cpuid_level)
movl %ebx,RELOC(cpu_vendor) # store vendor string
movl %edx,RELOC(cpu_vendor)+4
movl %ecx,RELOC(cpu_vendor)+8
movl $0, RELOC(cpu_vendor)+12
movl $0x1, RELOC(cpu_meltdown)
movl $0x0, RELOC(pg_g_kern)
cmpl $0x756e6547,%ebx # "Genu"
jne .Lcpu_secure
cmpl $0x6c65746e,%ecx # "ntel"
jne .Lcpu_secure
cmpl $0x49656e69,%edx # "ineI"
jne .Lcpu_secure
movl $0x0,%eax
cpuid
cmpl $0x7,%eax
jl .Lcpu_check_finished
movl $0x7,%eax
cpuid
testl $SEFF0EDX_ARCH_CAP,%edx
jz .Lcpu_check_finished
movl $MSR_ARCH_CAPABILITIES,%ecx
rdmsr
testl $ARCH_CAP_RDCL_NO,%eax
jz .Lcpu_check_finished
.Lcpu_secure:
movl $0x0, RELOC(cpu_meltdown)
movl $PG_G, RELOC(pg_g_kern)
.Lcpu_check_finished:
movl $1,%eax
xorl %ecx,%ecx
cpuid
movl %eax,RELOC(cpu_id) # store cpu_id and features
movl %ebx,RELOC(cpu_miscinfo)
movl %edx,RELOC(cpu_feature)
movl %ecx,RELOC(cpu_ecxfeature)
movl RELOC(cpuid_level),%eax
cmp $2,%eax
jl 1f
movl $2,%eax
cpuid
movl %eax,RELOC(cpu_cache_eax)
movl %ebx,RELOC(cpu_cache_ebx)
movl %ecx,RELOC(cpu_cache_ecx)
movl %edx,RELOC(cpu_cache_edx)
movl $0x0a,%eax
cpuid
movl %eax,RELOC(cpu_perf_eax)
movl %ebx,RELOC(cpu_perf_ebx)
movl %edx,RELOC(cpu_perf_edx)
1:
movl $0x80000000,%eax
cpuid
cmpl $0x80000000,%eax
jbe 2f
movl $0x80000001,%eax
cpuid
movl %eax,RELOC(ecpu_eaxfeature)
movl %edx,RELOC(ecpu_feature)
movl %ecx,RELOC(ecpu_ecxfeature)
movl $0x80000002,%eax
cpuid
movl %eax,RELOC(cpu_brandstr)
movl %ebx,RELOC(cpu_brandstr)+4
movl %ecx,RELOC(cpu_brandstr)+8
movl %edx,RELOC(cpu_brandstr)+12
movl $0x80000003,%eax
cpuid
movl %eax,RELOC(cpu_brandstr)+16
movl %ebx,RELOC(cpu_brandstr)+20
movl %ecx,RELOC(cpu_brandstr)+24
movl %edx,RELOC(cpu_brandstr)+28
movl $0x80000004,%eax
cpuid
movl %eax,RELOC(cpu_brandstr)+32
movl %ebx,RELOC(cpu_brandstr)+36
movl %ecx,RELOC(cpu_brandstr)+40
andl $0x00ffffff,%edx
movl %edx,RELOC(cpu_brandstr)+44
movl $0x80000007,%eax
cpuid
movl %edx,RELOC(cpu_apmi_edx)
2:
movl $RELOC(tmpstk),%esp # bootstrap stack end location
#define PROC0STACK ((0) * NBPG)
#define PROC0PDIR (( UPAGES) * NBPG)
#define SYSMAP ((4+UPAGES) * NBPG)
#define TABLESIZE ((4+UPAGES) * NBPG)
movl $RELOC(end),%edi
#if (NKSYMS || defined(DDB))
movl RELOC(esym),%eax
testl %eax,%eax
jz 1f
subl $KERNBASE,%eax
movl %eax,%edi
1:
#endif
movl %edi,%esi # edi = esym ? esym : end
addl $PGOFSET, %esi # page align up
andl $~PGOFSET, %esi
movl RELOC(nkpde),%ecx # get nkpde
cmpl $NKPTP_MIN,%ecx # larger than min?
jge 1f
movl $NKPTP_MIN,%ecx # set at min
jmp 2f
1: cmpl RELOC(nkptp_max),%ecx # larger than max?
jle 2f
movl RELOC(nkptp_max),%ecx
2: movl %ecx,RELOC(nkpde) # and store it back
shll $PGSHIFT,%ecx
addl $TABLESIZE,%ecx
addl %esi,%ecx # end of tables
subl %edi,%ecx # size of tables
shrl $2,%ecx
xorl %eax, %eax
rep
stosl
#define fillkpt \
1: movl %eax,(%ebx) ; \
addl $NBPG,%eax ; \
addl $4,%ebx ; \
loop 1b ;
leal (RELOC(etext)+PGOFSET),%edx
andl $~PGOFSET,%edx
movl $RELOC(KERNTEXTOFF),%eax
movl %eax,%ecx
shrl $PGSHIFT,%ecx
leal (SYSMAP)(%esi,%ecx,4),%ebx
movl %edx,%ecx
subl %eax,%ecx
shrl $PGSHIFT,%ecx
orl $(PG_V|PG_KR),%eax
fillkpt
leal (PG_V|PG_KW)(%edx),%eax
movl RELOC(nkpde),%ecx
shll $PGSHIFT,%ecx
addl $TABLESIZE,%ecx
addl %esi,%ecx # end of tables
subl %edx,%ecx # subtract end of text
shrl $PGSHIFT,%ecx
fillkpt
movl $(IOM_BEGIN|PG_V|PG_KW),%eax # having these bits set
movl $(IOM_SIZE>>PGSHIFT),%ecx # for this many pte s,
fillkpt
movl RELOC(nkpde),%ecx # count of pdes,
leal (PROC0PDIR+0*4)(%esi),%ebx # where temp maps!
leal (SYSMAP+PG_V|PG_KW|PG_U|PG_M)(%esi),%eax # pte for KPT in proc 0
fillkpt
movl RELOC(nkpde),%ecx # count of pde s,
leal (PROC0PDIR+PDSLOT_KERN*4)(%esi),%ebx # map them high
leal (SYSMAP+PG_V|PG_KW|PG_U|PG_M)(%esi),%eax # pte for KPT in proc 0
fillkpt
leal (PROC0PDIR+PG_V|PG_KW|PG_U|PG_M)(%esi),%eax # pte for ptd
movl %eax,(PROC0PDIR+PDSLOT_PTE*4)(%esi) # recursive PD slot
addl $NBPG, %eax # pte for ptd[1]
movl %eax,(PROC0PDIR+(PDSLOT_PTE+1)*4)(%esi) # recursive PD slot
leal (PROC0PDIR)(%esi),%eax # phys address of ptd in proc 0
movl %eax,RELOC(PTDpaddr)
movl %eax,%cr3 # load ptd addr into mmu
movl %cr0,%eax # get control word
orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP),%eax
movl %eax,%cr0 # and let's page NOW!
pushl $begin # jump to high mem
ret
begin:
movl nkpde,%ecx # for this many pde s,
leal (PROC0PDIR+0*4)(%esi),%ebx # which is where temp maps!
addl $(KERNBASE), %ebx # now use relocated address
1: movl $0,(%ebx)
addl $4,%ebx # next pde
loop 1b
movl nkpde,%edx
shll $PGSHIFT,%edx
addl $(TABLESIZE+KERNBASE),%edx
addl %esi,%edx
movl %edx,atdevbase
leal (PROC0STACK+KERNBASE)(%esi),%eax
movl %eax,proc0paddr
leal (USPACE-FRAMESIZE)(%eax),%esp
leal (PROC0PDIR)(%esi),%ebx # phys address of ptd in proc 0
movl %ebx,PCB_CR3(%eax) # pcb->pcb_cr3
xorl %ebp,%ebp # mark end of frames
movl nkpde,%eax
shll $PGSHIFT,%eax
addl $TABLESIZE,%eax
addl %esi,%eax # skip past stack and page tables
pushl %eax
call init386 # wire 386 chip for unix operation
addl $4,%esp
call main