133965Sjdp/* $NetBSD: startprog32.S,v 1.3 2023/04/20 00:42:24 manu Exp $ */ 233965Sjdp/* NetBSD: startprog.S,v 1.4 2016/12/04 08:21:08 maxv Exp */ 333965Sjdp 433965Sjdp/* 533965Sjdp * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 633965Sjdp * 733965Sjdp * Mach Operating System 833965Sjdp * Copyright (c) 1992, 1991 Carnegie Mellon University 933965Sjdp * All Rights Reserved. 1033965Sjdp * 1133965Sjdp * Permission to use, copy, modify and distribute this software and its 1233965Sjdp * documentation is hereby granted, provided that both the copyright 1333965Sjdp * notice and this permission notice appear in all copies of the 1433965Sjdp * software, derivative works or modified versions, and any portions 1533965Sjdp * thereof, and that both notices appear in supporting documentation. 1633965Sjdp * 1733965Sjdp * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 1833965Sjdp * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1933965Sjdp * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 2077298Sobrien * 2177298Sobrien * Carnegie Mellon requests users of this software to return to 2277298Sobrien * 2333965Sjdp * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 2433965Sjdp * School of Computer Science 2533965Sjdp * Carnegie Mellon University 2633965Sjdp * Pittsburgh PA 15213-3890 2733965Sjdp * 2833965Sjdp * any improvements or extensions that they make and grant Carnegie Mellon 2933965Sjdp * the rights to redistribute these changes. 3033965Sjdp */ 3133965Sjdp 3233965Sjdp/* 3333965Sjdp * Copyright 1988, 1989, 1990, 1991, 1992 3433965Sjdp * by Intel Corporation, Santa Clara, California. 3533965Sjdp * 3633965Sjdp * All Rights Reserved 3733965Sjdp * 3833965Sjdp * Permission to use, copy, modify, and distribute this software and 3933965Sjdp * its documentation for any purpose and without fee is hereby 4033965Sjdp * granted, provided that the above copyright notice appears in all 4133965Sjdp * copies and that both the copyright notice and this permission notice 4260484Sobrien * appear in supporting documentation, and that the name of Intel 4333965Sjdp * not be used in advertising or publicity pertaining to distribution 4433965Sjdp * of the software without specific, written prior permission. 4533965Sjdp * 4633965Sjdp * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 4733965Sjdp * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 4833965Sjdp * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 4960484Sobrien * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 5038889Sjdp * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 5138889Sjdp * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 5233965Sjdp * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 5360484Sobrien */ 5433965Sjdp 5533965Sjdp#include <machine/asm.h> 5633965Sjdp#include <machine/specialreg.h> 5733965Sjdp 5833965Sjdp#define CODE_SEGMENT 0x08 5933965Sjdp#define DATA_SEGMENT 0x10 6060484Sobrien 6138889Sjdp .align 16 6233965Sjdp .globl _C_LABEL(startprog32) 6333965Sjdp_C_LABEL(startprog32): 6460484Sobrien .quad 0 6533965Sjdp 6633965Sjdp .globl _C_LABEL(startprog32_size) 6777298Sobrien_C_LABEL(startprog32_size): 6877298Sobrien .long startprog32_end - _C_LABEL(startprog32_start) 6977298Sobrien 7077298Sobrien .text 7177298Sobrien .p2align 4,,15 7277298Sobrien 7377298Sobrien/* 7477298Sobrien * startprog32(entry,argc,argv,stack,kern_start,kern_load,kern_size,loadaddr) 7577298Sobrien */ 7677298SobrienENTRY(startprog32_start) 7777298Sobrienstart: 7877298Sobrien pushl %ebp 7977298Sobrien movl %esp, %ebp 8077298Sobrien 8177298Sobrien /* 8277298Sobrien * 8(%ebp): kernel entry address 8377298Sobrien * 12(%ebp): argc 8477298Sobrien * 16(%ebp): argv 8577298Sobrien * 20(%ebp): stack address 8677298Sobrien * 24(%ebp): kernel start address 8777298Sobrien * 28(%ebp): loaded kernel address 8877298Sobrien * 32(%ebp): loaded kernel size 8977298Sobrien * 36(%ebp): loaded start address 9077298Sobrien */ 9177298Sobrien 9233965Sjdp cli 9333965Sjdp 9433965Sjdp movl 8(%ebp), %ebx /* %ebx: entry address */ 9533965Sjdp movl 36(%ebp), %edx /* %edx: loaded start address */ 9633965Sjdp 9733965Sjdp /* Prepare a new stack */ 9833965Sjdp movl 20(%ebp), %eax /* stack */ 9933965Sjdp subl $4, %eax 10033965Sjdp movl %eax, %edi 10133965Sjdp 10277298Sobrien /* Push some number of args onto the stack */ 10333965Sjdp movl 12(%ebp), %ecx /* argc */ 10433965Sjdp movl %ecx, %eax 10533965Sjdp decl %eax 10633965Sjdp shl $2, %eax 10733965Sjdp addl 16(%ebp), %eax /* ptr to last arg */ 10860484Sobrien movl %eax, %esi 10960484Sobrien 11060484Sobrien std /* backwards */ 11160484Sobrien rep 11260484Sobrien movsl /* copy %ds:(%esi) -> %es:(%edi) */ 11360484Sobrien cld 11460484Sobrien mov %edi, %esp /* set new stack pointer */ 11560484Sobrien 11660484Sobrien /* Copy kernel */ 11760484Sobrien movl 24(%ebp), %edi /* dest */ 11877298Sobrien movl 28(%ebp), %esi /* src */ 11960484Sobrien movl 32(%ebp), %ecx /* size */ 12060484Sobrien 12160484Sobrien /* skip copy if same source and destination */ 12260484Sobrien cmpl %edi,%esi 12360484Sobrien jz .Lcopy_done 12433965Sjdp 12533965Sjdp#if defined(NO_OVERLAP) 12633965Sjdp movl %ecx, %eax 12733965Sjdp#else 12833965Sjdp movl %edi, %eax 12933965Sjdp subl %esi, %eax 13033965Sjdp cmpl %ecx, %eax /* overlapping? */ 13133965Sjdp movl %ecx, %eax 13233965Sjdp jb .Lbackwards 13333965Sjdp#endif 13433965Sjdp /* nope, copy forwards. */ 13533965Sjdp shrl $2, %ecx /* copy by words */ 13633965Sjdp rep 13777298Sobrien movsl 13833965Sjdp and $3, %eax /* any bytes left? */ 13933965Sjdp jnz .Ltrailing 14033965Sjdp jmp .Lcopy_done 141 142.Ltrailing: 143 cmp $2, %eax 144 jb 1f 145 movw (%esi), %ax 146 movw %ax, (%edi) 147 je .Lcopy_done 148 movb 2(%esi), %al 149 movb %al, 2(%edi) 150 jmp .Lcopy_done 1511: movb (%esi), %al 152 movb %al, (%edi) 153 jmp .Lcopy_done 154 155#if !defined(NO_OVERLAP) 156.Lbackwards: 157 addl %ecx, %edi /* copy backwards. */ 158 addl %ecx, %esi 159 and $3, %eax /* any fractional bytes? */ 160 jnz .Lback_align 161.Lback_aligned: 162 shrl $2, %ecx 163 subl $4, %esi 164 subl $4, %edi 165 std 166 rep 167 movsl 168 cld 169 jmp .Lcopy_done 170 171.Lback_align: 172 sub %eax, %esi 173 sub %eax, %edi 174 cmp $2, %eax 175 jb 1f 176 je 2f 177 movb 2(%esi), %al 178 movb %al, 2(%edi) 1792: movw (%esi), %ax 180 movw %ax, (%edi) 181 jmp .Lback_aligned 1821: movb (%esi), %al 183 movb %al, (%edi) 184 jmp .Lback_aligned 185#endif 186 /* End of copy kernel */ 187.Lcopy_done: 188 cld /* LynxOS depends on it */ 189 190 /* Prepare jump address */ 191 lea (start32a - start)(%edx), %eax 192 movl %eax, (start32r - start)(%edx) 193 194 /* Setup GDT */ 195 lea (gdt - start)(%edx), %eax 196 movl %eax, (gdtrr - start)(%edx) 197 lgdt (gdtr - start)(%edx) 198 199 /* Jump to set %cs */ 200 ljmp *(start32r - start)(%edx) 201 202 .align 4 203start32a: 204 movl $DATA_SEGMENT, %eax 205 movw %ax, %ds 206 movw %ax, %es 207 movw %ax, %fs 208 movw %ax, %gs 209 movw %ax, %ss 210 211 /* Already set new stack pointer */ 212 movl %esp, %ebp 213 214 /* Disable Paging in CR0 */ 215 movl %cr0, %eax 216 andl $(~CR0_PG), %eax 217 movl %eax, %cr0 218 219 /* Disable PAE in CR4 */ 220 movl %cr4, %eax 221 andl $(~CR4_PAE), %eax 222 movl %eax, %cr4 223 224 jmp start32b 225 226 .align 4 227start32b: 228 xor %eax, %eax 229 movl %ebx, (start32r - start)(%edx) 230 ljmp *(start32r - start)(%edx) 231 232 .align 16 233start32r: 234 .long 0 235 .long CODE_SEGMENT 236 .align 16 237gdt: 238 .long 0, 0 239 .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00 240 .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 241gdtr: 242 .word gdtr - gdt 243gdtrr: 244 .quad 245start32end: 246 /* Space for the stack */ 247 .align 16 248 .space 8192 249startprog32_end: 250