/*
 *  linux/boot/head.S
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 *  head.S contains the 32-bit startup code.
 *
 *  1-Jan-96 Modified by Chris Brady for use as a boot/loader for MemTest-86.
 *  Setup the memory management for flat non-paged linear addressing.
 */

.text
.global idt
.global idt_descr
.global trap_regs

#include <linux/linkage.h>
#include "mtest.h"

#ifndef SYMBOL_NAME
#define SYMBOL_NAME(X) _/**/X
#endif

startup_32:
	cld
	cli
	movl $(KERNEL_DS),%eax
	mov %ax,%ds
	mov %ax,%es
	mov %ax,%fs
	mov %ax,%gs
	mov %ax,%ss
	mov $(TESTADR),%esp
/*
 * start system 32-bit setup. We need to re-do some of the things done
 * in 16-bit mode for the "real" operations.
 */
	xorl %eax,%eax
a20:	incl %eax		# check that A20 really IS enabled
	movl %eax,0x000000	# loop forever if it isn't
	cmpl %eax,0x100000
	je a20

        lgdt gdt_descr
        ljmp $(KERNEL_CS),$flush
flush:  movl $(KERNEL_DS),%eax  # reload all the segment registers
        mov %ax,%ds             # after changing gdt.
        mov %ax,%es
        mov %ax,%fs
        mov %ax,%gs
	mov %ax,%ss

/*
 * Setup and exception handler
 */
        lea SYMBOL_NAME(idt),%edi

        lea vec0,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec1,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec2,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec3,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec4,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec5,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec6,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec7,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec8,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec9,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec10,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec11,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec12,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec13,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec14,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec15,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec16,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec17,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        lea vec18,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi

        call SYMBOL_NAME(do_test)

vec0:
	movl $0,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec1:
	movl $1,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec2:
	movl $2,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec3:
	movl $3,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec4:
	movl $4,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec5:
	movl $5,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec6:
	movl $6,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec7:
	movl $7,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec8:
	movl $8,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec9:
	movl $9,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec10:
	movl $10,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec11:
	movl $11,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec12:
	movl $12,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec13:
	movl $13,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec14:
	movl $14,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec15:
	movl $15,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec16:
	movl $16,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec17:
	movl $17,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
vec18:
	movl $18,%eax
        lea trap_regs,%edi
	movl %eax,(%edi)
	jp int_hand
	
int_hand:
	popl %eax
	movl %eax,16(%edi)
	popl %eax
	movl %eax,12(%edi)
	popl %eax
	movl %eax,8(%edi)
	popl %eax
	movl %eax,4(%edi)
        call SYMBOL_NAME(inter)

trap_regs:
	.long 0		# Vector
	.long 0		# Eflag
	.long 0		# CS
	.long 0		# EIP
	.long 0		# Error Code

/*
 * The interrupt descriptor table has room for 32 idt's
 */
.align 4        
.word 0
idt_descr:
        .word 20*8-1           # idt contains 32 entries
        .long SYMBOL_NAME(idt)

idt:
        .fill 20,8,0           # idt is uninitialized

gdt_descr:
        .word (16)*8-1
        .long _gdt

.align 4
_gdt:
        .quad 0x0000000000000000        /* NULL descriptor */
        .quad 0x0000000000000000        /* not used */
        .quad 0x00cf9a000000ffff        /* 0x10 main 4gb code at 0x000000 */
        .quad 0x00cf92000000ffff        /* 0x18 main 4gb data at 0x000000 */
        .quad 0x00cf9a100000ffff        /* 0x20 relo 4gb code at 0x100000 */
        .quad 0x00cf92100000ffff        /* 0x28 relo 4gb data at 0x100000 */
