fcd7bdc04c0871f283a52741bc31099b77906a28
[coreboot.git] / src / cpu / amd / model_lx / cache_as_ram.inc
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #define LX_STACK_BASE           CONFIG_DCACHE_RAM_BASE          /* this is where the DCache will be mapped and be used as stack, It would be cool if it was the same base as coreboot normal stack */
21 #define LX_STACK_END            LX_STACK_BASE+(CONFIG_DCACHE_RAM_SIZE-1)
22
23 #define LX_NUM_CACHELINES       0x080   /* there are 128lines per way */
24 #define LX_CACHELINE_SIZE       0x020   /* there are 32bytes per line */
25 #define LX_CACHEWAY_SIZE        (LX_NUM_CACHELINES * LX_CACHELINE_SIZE)
26 #define CR0_CD                          0x40000000      /* bit 30 = Cache Disable */
27 #define CR0_NW                          0x20000000      /* bit 29 = Not Write Through */
28 #include <cpu/amd/lxdef.h>
29 /***************************************************************************
30 /**
31 /**     DCacheSetup
32 /**
33 /**     Setup data cache for  use as RAM for a stack.
34 /**
35 /***************************************************************************/
36 DCacheSetup:
37
38         invd
39         /* set cache properties */
40         movl    $CPU_RCONF_DEFAULT, %ecx
41         rdmsr
42         movl    $0x010010000, %eax              /*1MB system memory in write back 1|00100|00 */
43         wrmsr
44
45         /* in LX DCDIS is set after POR which disables the cache..., clear this bit */
46         movl    CPU_DM_CONFIG0,%ecx
47         rdmsr
48         andl    $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax  /* TODO: make consistent with i$ init,  either whole reg = 0,  or just this bit... */
49         wrmsr
50
51         /* get cache timing params from BIOS config data locations and apply */
52         /* fix delay controls for DM and IM arrays */
53         /* fix delay controls for DM and IM arrays */
54         movl    $CPU_BC_MSS_ARRAY_CTL0, %ecx
55         xorl    %edx, %edx
56         movl    $0x2814D352, %eax
57         wrmsr
58
59         movl    $CPU_BC_MSS_ARRAY_CTL1, %ecx
60         xorl    %edx, %edx
61         movl    $0x1068334D, %eax
62         wrmsr
63
64         movl    $CPU_BC_MSS_ARRAY_CTL2, %ecx
65         movl    $0x00000106, %edx
66         movl    $0x83104104, %eax
67         wrmsr
68
69         movl    $GLCP_FIFOCTL, %ecx
70         rdmsr
71         movl    $0x00000005, %edx
72         wrmsr
73
74         /* Enable setting */
75         movl    $CPU_BC_MSS_ARRAY_CTL_ENA, %ecx
76         xorl    %edx, %edx
77         movl    $0x01, %eax
78         wrmsr
79
80         /* Get cleaned up. */
81         xorl    %edi, %edi
82         xorl    %esi, %esi
83         xorl    %ebp, %ebp
84
85         /* DCache Ways0 through Ways7 will be tagged for LX_STACK_BASE + CONFIG_DCACHE_RAM_SIZE for holding stack */
86         /* remember,  there is NO stack yet... */
87
88         /* Tell cache we want to fill WAY 0 starting at the top */
89         xorl    %edx, %edx
90         xorl    %eax, %eax
91         movl    $CPU_DC_INDEX, %ecx
92         wrmsr
93
94         /* startaddress for tag of Way0: ebp will hold the incrementing address. dont destroy! */
95         movl    $LX_STACK_BASE, %ebp    /* init to start address */
96         orl             $1, %ebp                                /* set valid bit and tag for this Way (B[31:12] : Cache tag value for line/way curr. selected by CPU_DC_INDEX */
97
98         /* start tag Ways 0 with 128 lines with 32bytes each: edi will hold the line counter. dont destroy! */
99         movl    $LX_NUM_CACHELINES, %edi
100 DCacheSetupFillWay:
101
102         /* fill with dummy data: zero it so we can tell it from PCI memory space (returns FFs). */
103         /* We will now store a line (32 bytes = 4 x 8bytes = 4 quadWords) */
104         movw    $0x04, %si
105         xorl    %edx, %edx
106         xorl    %eax, %eax
107         movl    $CPU_DC_DATA, %ecx
108 DCacheSetup_quadWordLoop:
109         wrmsr
110         decw    %si
111         jnz     DCacheSetup_quadWordLoop
112
113         /* Set the tag for this line,  need to do this for every new cache line to validate it! */
114         /* accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX increment and thus cont. in the next cache line... */
115         xorl    %edx, %edx
116         movl    %ebp, %eax
117         movl    $CPU_DC_TAG, %ecx
118         wrmsr
119
120         /* switch to next line */
121         /* lines are in Bits10:4 */
122         /* when index is crossing 0x7F -> 0x80  writing a RSVD bit as 0x80 is not a valid CL anymore! */
123         movl    $CPU_DC_INDEX, %ecx
124         rdmsr
125         addl    $0x010, %eax /* TODO: prob. would be more elegant to calc. this from counter var edi... */
126         wrmsr
127
128         decl    %edi
129         jnz     DCacheSetupFillWay
130
131         /* 1 Way has been filled,  forward start address for next Way,  terminate if we have reached end of desired address range */
132         addl    $LX_CACHEWAY_SIZE, %ebp
133         cmpl    $LX_STACK_END, %ebp
134         jge     leave_DCacheSetup
135         movl    $LX_NUM_CACHELINES, %edi
136
137         /* switch to next way */
138         movl    $CPU_DC_INDEX, %ecx
139         rdmsr
140         addl    $0x01, %eax
141         andl    $0xFFFFF80F, %eax /* lets be sure: reset line index Bits10:4 */
142         wrmsr
143
144         jmp     DCacheSetupFillWay
145
146 leave_DCacheSetup:
147         xorl    %edi, %edi
148         xorl    %esi, %esi
149         xorl    %ebp, %ebp
150
151         /* Disable the cache,  but ... DO NOT INVALIDATE the tags. */
152         /* Memory reads and writes will all hit in the cache. */
153         /* Cache updates and memory write-backs will not occur ! */
154         movl    %cr0, %eax
155         orl             $(CR0_CD + CR0_NW), %eax        /* set the CD and NW bits */
156         movl    %eax, %cr0
157
158         /* Now point sp to the cached stack. */
159         /* The stack will be fully functional at this location. No system memory is required at all ! */
160         /* set up the stack pointer */
161         movl    $LX_STACK_END, %eax
162         movl    %eax, %esp
163
164         /* test the stack*/
165         movl    $0x0F0F05A5A, %edx
166         pushl   %edx
167         popl    %ecx
168         cmpl    %ecx, %edx
169         je      DCacheSetupGood
170         movb    $0xC5, %al
171         outb    %al, $0x80
172 DCacheSetupBad:
173         hlt             /* issues */
174         jmp DCacheSetupBad
175 DCacheSetupGood:
176
177         /* Go do early init and memory setup */
178         call    cache_as_ram_main
179 done_cache_as_ram_main:
180
181         /* If you wanted to maintain the stack in memory you would need to set the tags as dirty
182           so the wbinvd would push out the old stack contents to memory */
183         /* Clear the cache, the following code from crt0.S.lb will setup a new stack*/
184         wbinvd
185
186 /* the following code is from crt0.S.lb */
187 /* This takes the place of the post-CAR funtions that the K8 uses to setup the stack and copy LB low.*/
188
189 #ifndef CONSOLE_DEBUG_TX_STRING
190         /* uses:         esp, ebx, ax, dx */
191 # define __CRT_CONSOLE_TX_STRING(string) \
192         mov     string, %ebx    ; \
193         CALLSP(crt_console_tx_string)
194
195 # if defined(CONFIG_TTYS0_BASE) && (ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG)
196 #  define CONSOLE_DEBUG_TX_STRING(string)        __CRT_CONSOLE_TX_STRING(string)
197 # else
198 #  define CONSOLE_DEBUG_TX_STRING(string)
199 # endif
200 #endif
201
202         /* clear boot_complete flag */
203         xorl    %ebp, %ebp
204 __main:
205         CONSOLE_DEBUG_TX_STRING($str_copying_to_ram)
206
207         /*
208          *      Copy data into RAM and clear the BSS. Since these segments
209          *      isn\'t really that big we just copy/clear using bytes, not
210          *      double words.
211          */
212         intel_chip_post_macro(0x11)             /* post 11 */
213
214         cld                             /* clear direction flag */
215
216         /* copy coreboot from it's initial load location to
217          * the location it is compiled to run at.
218          * Normally this is copying from FLASH ROM to RAM.
219          */
220         movl    %ebp, %esi
221         /* FIXME: look for a proper place for the stack */
222         movl    $0x4000000, %esp
223         movl    %esp, %ebp
224         pushl   %esi
225 #if CONFIG_CBFS == 1
226         pushl $str_coreboot_ram_name
227         call cbfs_and_run_core
228 #else
229         movl    $_liseg, %esi
230         movl    $_iseg,  %edi
231         movl    $_eiseg, %ecx
232         subl    %edi, %ecx
233         pushl   %ecx
234         pushl   %edi
235         pushl   %esi
236         call copy_and_run_core
237 #endif
238
239 .Lhlt:
240         intel_chip_post_macro(0xee)     /* post fail ee */
241         hlt
242         jmp     .Lhlt
243
244 #ifdef __CRT_CONSOLE_TX_STRING
245         /* Uses esp, ebx, ax, dx  */
246 crt_console_tx_string:
247         mov     (%ebx), %al
248         inc     %ebx
249         cmp     $0, %al
250         jne     9f
251         RETSP
252 9:
253 /* Base Address */
254 #ifndef CONFIG_TTYS0_BASE
255 #define CONFIG_TTYS0_BASE       0x3f8
256 #endif
257 /* Data */
258 #define TTYS0_RBR (CONFIG_TTYS0_BASE+0x00)
259
260 /* Control */
261 #define TTYS0_TBR TTYS0_RBR
262 #define TTYS0_IER (CONFIG_TTYS0_BASE+0x01)
263 #define TTYS0_IIR (CONFIG_TTYS0_BASE+0x02)
264 #define TTYS0_FCR TTYS0_IIR
265 #define TTYS0_LCR (CONFIG_TTYS0_BASE+0x03)
266 #define TTYS0_MCR (CONFIG_TTYS0_BASE+0x04)
267 #define TTYS0_DLL TTYS0_RBR
268 #define TTYS0_DLM TTYS0_IER
269
270 /* Status */
271 #define TTYS0_LSR (CONFIG_TTYS0_BASE+0x05)
272 #define TTYS0_MSR (CONFIG_TTYS0_BASE+0x06)
273 #define TTYS0_SCR (CONFIG_TTYS0_BASE+0x07)
274
275         mov     %al, %ah
276 10:     mov     $TTYS0_LSR, %dx
277         inb     %dx, %al
278         test    $0x20, %al
279         je      10b
280         mov     $TTYS0_TBR, %dx
281         mov     %ah, %al
282         outb    %al, %dx
283
284         jmp crt_console_tx_string
285 #endif /* __CRT_CONSOLE_TX_STRING */
286
287 #if defined(CONSOLE_DEBUG_TX_STRING) && (ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG)
288 .section ".rom.data"
289 #if CONFIG_COMPRESS
290 str_copying_to_ram:  .string "Uncompressing coreboot to ram.\r\n"
291 #else
292 str_copying_to_ram:  .string "Copying coreboot to ram.\r\n"
293 #endif
294 str_pre_main:        .string "Jumping to coreboot.\r\n"
295 .previous
296
297 #endif /* ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG */
298 #if CONFIG_CBFS == 1
299 # if CONFIG_USE_FALLBACK_IMAGE == 1
300 str_coreboot_ram_name:  .string "fallback/coreboot_ram"
301 # else
302 str_coreboot_ram_name:  .string "normal/coreboot_ram"
303 # endif
304 #endif