Rename almost all occurences of LinuxBIOS to coreboot.
[coreboot.git] / src / arch / i386 / init / crt0.S.lb
1 /* -*- asm -*-
2  * $ $
3  *
4  */
5
6 /* 
7  * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
8  *
9  * This file is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * Originally this code was part of ucl the data compression library
15  * for upx the ``Ultimate Packer of eXecutables''.
16  *
17  * - Converted to gas assembly, and refitted to work with etherboot.
18  *   Eric Biederman 20 Aug 2002
19  * - Merged the nrv2b decompressor into crt0.base of coreboot
20  *   Eric Biederman 26 Sept 2002
21  */
22
23
24 #include <arch/asm.h>
25 #include <arch/intel.h>
26 #include <console/loglevel.h>   
27
28 /*
29  * This is the entry code the code in .reset section
30  * jumps to this address.
31  *
32  */
33 .section ".rom.data", "a", @progbits
34 .section ".rom.text", "ax", @progbits
35
36         intel_chip_post_macro(0x01)             /* delay for chipsets */
37
38 #include "crt0_includes.h"
39
40 #if USE_DCACHE_RAM == 0
41 #ifndef CONSOLE_DEBUG_TX_STRING
42         /* uses:         esp, ebx, ax, dx */
43 # define __CRT_CONSOLE_TX_STRING(string) \
44         mov     string, %ebx    ; \
45         CALLSP(crt_console_tx_string)
46
47 # if defined(TTYS0_BASE) && (ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG)
48 #  define CONSOLE_DEBUG_TX_STRING(string)        __CRT_CONSOLE_TX_STRING(string)
49 # else
50 #  define CONSOLE_DEBUG_TX_STRING(string)
51 # endif
52 #endif
53
54         /* clear boot_complete flag */
55         xorl    %ebp, %ebp
56 __main:
57         CONSOLE_DEBUG_TX_STRING($str_copying_to_ram)
58
59         /*
60          *      Copy data into RAM and clear the BSS. Since these segments
61          *      isn\'t really that big we just copy/clear using bytes, not
62          *      double words.
63          */
64         intel_chip_post_macro(0x11)             /* post 11 */
65
66         cld                             /* clear direction flag */
67         
68         /* copy coreboot from it's initial load location to 
69          * the location it is compiled to run at.
70          * Normally this is copying from FLASH ROM to RAM.
71          */
72 #if !CONFIG_COMPRESS
73         movl    $_liseg, %esi
74         movl    $_iseg,  %edi
75         movl    $_eiseg, %ecx
76         subl    %edi, %ecx
77         rep     movsb
78 #else
79         leal    4+_liseg, %esi
80         leal    _iseg, %edi
81         movl    %ebp, %esp      /* preserve %ebp */
82         movl    $-1, %ebp       /* last_m_off = -1 */
83         jmp     dcl1_n2b
84
85 /* ------------- DECOMPRESSION -------------
86
87  Input:
88    %esi - source
89    %edi - dest
90    %ebp - -1
91    cld
92
93  Output:
94    %eax - 0
95    %ecx - 0
96 */
97
98 .macro getbit bits
99 .if     \bits == 1
100         addl    %ebx, %ebx
101         jnz     1f
102 .endif
103         movl    (%esi), %ebx
104         subl    $-4, %esi       /* sets carry flag */
105         adcl    %ebx, %ebx
106 1:
107 .endm
108
109 decompr_literals_n2b:
110         movsb
111
112 decompr_loop_n2b:
113         addl    %ebx, %ebx
114         jnz     dcl2_n2b
115 dcl1_n2b:
116         getbit  32
117 dcl2_n2b:
118         jc      decompr_literals_n2b
119         xorl    %eax, %eax
120         incl    %eax            /* m_off = 1 */
121 loop1_n2b:
122         getbit  1
123         adcl    %eax, %eax      /* m_off = m_off*2 + getbit() */
124         getbit  1
125         jnc     loop1_n2b       /* while(!getbit()) */
126         xorl    %ecx, %ecx
127         subl    $3, %eax
128         jb      decompr_ebpeax_n2b      /* if (m_off == 2) goto decompr_ebpeax_n2b ? */
129         shll    $8, %eax        
130         movb    (%esi), %al     /* m_off = (m_off - 3)*256 + src[ilen++] */
131         incl    %esi
132         xorl    $-1, %eax       
133         jz      decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */
134         movl    %eax, %ebp      /* last_m_off = m_off ?*/
135 decompr_ebpeax_n2b:
136         getbit  1               
137         adcl    %ecx, %ecx      /* m_len = getbit() */
138         getbit  1
139         adcl    %ecx, %ecx      /* m_len = m_len*2 + getbit()) */
140         jnz     decompr_got_mlen_n2b    /* if (m_len == 0) goto decompr_got_mlen_n2b */
141         incl    %ecx            /* m_len++ */
142 loop2_n2b:
143         getbit  1       
144         adcl    %ecx, %ecx      /* m_len = m_len*2 + getbit() */
145         getbit  1
146         jnc     loop2_n2b       /* while(!getbit()) */
147         incl    %ecx
148         incl    %ecx            /* m_len += 2 */
149 decompr_got_mlen_n2b:
150         cmpl    $-0xd00, %ebp
151         adcl    $1, %ecx        /* m_len = m_len + 1 + (last_m_off > 0xd00) */
152         movl    %esi, %edx
153         leal    (%edi,%ebp), %esi       /* m_pos = dst + olen + -m_off  */
154         rep
155         movsb                   /* dst[olen++] = *m_pos++ while(m_len > 0) */
156         movl    %edx, %esi
157         jmp     decompr_loop_n2b
158 decompr_end_n2b:
159         intel_chip_post_macro(0x12)             /* post 12 */
160
161         movl    %esp, %ebp
162 #endif
163
164         CONSOLE_DEBUG_TX_STRING($str_pre_main)
165         leal    _iseg, %edi
166         jmp     *%edi
167
168 .Lhlt:  
169         intel_chip_post_macro(0xee)     /* post fe */
170         hlt
171         jmp     .Lhlt
172
173 #ifdef __CRT_CONSOLE_TX_STRING
174         /* Uses esp, ebx, ax, dx  */
175 crt_console_tx_string:
176         mov     (%ebx), %al
177         inc     %ebx
178         cmp     $0, %al
179         jne     9f
180         RETSP
181 9:
182 /* Base Address */
183 #ifndef TTYS0_BASE
184 #define TTYS0_BASE      0x3f8
185 #endif
186 /* Data */
187 #define TTYS0_RBR (TTYS0_BASE+0x00)
188
189 /* Control */
190 #define TTYS0_TBR TTYS0_RBR
191 #define TTYS0_IER (TTYS0_BASE+0x01)
192 #define TTYS0_IIR (TTYS0_BASE+0x02)
193 #define TTYS0_FCR TTYS0_IIR
194 #define TTYS0_LCR (TTYS0_BASE+0x03)
195 #define TTYS0_MCR (TTYS0_BASE+0x04)
196 #define TTYS0_DLL TTYS0_RBR
197 #define TTYS0_DLM TTYS0_IER
198
199 /* Status */
200 #define TTYS0_LSR (TTYS0_BASE+0x05)
201 #define TTYS0_MSR (TTYS0_BASE+0x06)
202 #define TTYS0_SCR (TTYS0_BASE+0x07)
203         
204         mov     %al, %ah
205 10:     mov     $TTYS0_LSR, %dx
206         inb     %dx, %al
207         test    $0x20, %al
208         je      10b
209         mov     $TTYS0_TBR, %dx
210         mov     %ah, %al
211         outb    %al, %dx
212
213         jmp crt_console_tx_string
214 #endif /* __CRT_CONSOLE_TX_STRING */
215
216 #if defined(CONSOLE_DEBUG_TX_STRING) && (ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG)
217 .section ".rom.data"
218 str_copying_to_ram:  .string "Copying coreboot to RAM.\r\n"
219 str_pre_main:        .string "Jumping to coreboot.\r\n"
220 .previous
221
222 #endif /* ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG */
223
224 #endif /* USE_DCACHE_RAM */