a1d775d6d660b1ed90edc260078c047d075dc863
[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 #include <cpu/x86/post_code.h>
30 /***************************************************************************
31 /**
32 /**     DCacheSetup
33 /**
34 /**     Setup data cache for  use as RAM for a stack.
35 /**
36 /***************************************************************************/
37 DCacheSetup:
38         /* Save the BIST result */
39         movl    %eax, %ebx
40
41         invd
42         /* set cache properties */
43         movl    $CPU_RCONF_DEFAULT, %ecx
44         rdmsr
45         movl    $0x010010000, %eax              /*1MB system memory in write back 1|00100|00 */
46         wrmsr
47
48         /* in LX DCDIS is set after POR which disables the cache..., clear this bit */
49         movl    CPU_DM_CONFIG0,%ecx
50         rdmsr
51         andl    $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax  /* TODO: make consistent with i$ init,  either whole reg = 0,  or just this bit... */
52         wrmsr
53
54         /* get cache timing params from BIOS config data locations and apply */
55         /* fix delay controls for DM and IM arrays */
56         /* fix delay controls for DM and IM arrays */
57         movl    $CPU_BC_MSS_ARRAY_CTL0, %ecx
58         xorl    %edx, %edx
59         movl    $0x2814D352, %eax
60         wrmsr
61
62         movl    $CPU_BC_MSS_ARRAY_CTL1, %ecx
63         xorl    %edx, %edx
64         movl    $0x1068334D, %eax
65         wrmsr
66
67         movl    $CPU_BC_MSS_ARRAY_CTL2, %ecx
68         movl    $0x00000106, %edx
69         movl    $0x83104104, %eax
70         wrmsr
71
72         movl    $GLCP_FIFOCTL, %ecx
73         rdmsr
74         movl    $0x00000005, %edx
75         wrmsr
76
77         /* Enable setting */
78         movl    $CPU_BC_MSS_ARRAY_CTL_ENA, %ecx
79         xorl    %edx, %edx
80         movl    $0x01, %eax
81         wrmsr
82
83         /* Get cleaned up. */
84         xorl    %edi, %edi
85         xorl    %esi, %esi
86         xorl    %ebp, %ebp
87
88         /* DCache Ways0 through Ways7 will be tagged for LX_STACK_BASE + CONFIG_DCACHE_RAM_SIZE for holding stack */
89         /* remember,  there is NO stack yet... */
90
91         /* Tell cache we want to fill WAY 0 starting at the top */
92         xorl    %edx, %edx
93         xorl    %eax, %eax
94         movl    $CPU_DC_INDEX, %ecx
95         wrmsr
96
97         /* startaddress for tag of Way0: ebp will hold the incrementing address. dont destroy! */
98         movl    $LX_STACK_BASE, %ebp    /* init to start address */
99         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 */
100
101         /* start tag Ways 0 with 128 lines with 32bytes each: edi will hold the line counter. dont destroy! */
102         movl    $LX_NUM_CACHELINES, %edi
103 DCacheSetupFillWay:
104
105         /* fill with dummy data: zero it so we can tell it from PCI memory space (returns FFs). */
106         /* We will now store a line (32 bytes = 4 x 8bytes = 4 quadWords) */
107         movw    $0x04, %si
108         xorl    %edx, %edx
109         xorl    %eax, %eax
110         movl    $CPU_DC_DATA, %ecx
111 DCacheSetup_quadWordLoop:
112         wrmsr
113         decw    %si
114         jnz     DCacheSetup_quadWordLoop
115
116         /* Set the tag for this line,  need to do this for every new cache line to validate it! */
117         /* accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX increment and thus cont. in the next cache line... */
118         xorl    %edx, %edx
119         movl    %ebp, %eax
120         movl    $CPU_DC_TAG, %ecx
121         wrmsr
122
123         /* switch to next line */
124         /* lines are in Bits10:4 */
125         /* when index is crossing 0x7F -> 0x80  writing a RSVD bit as 0x80 is not a valid CL anymore! */
126         movl    $CPU_DC_INDEX, %ecx
127         rdmsr
128         addl    $0x010, %eax /* TODO: prob. would be more elegant to calc. this from counter var edi... */
129         wrmsr
130
131         decl    %edi
132         jnz     DCacheSetupFillWay
133
134         /* 1 Way has been filled,  forward start address for next Way,  terminate if we have reached end of desired address range */
135         addl    $LX_CACHEWAY_SIZE, %ebp
136         cmpl    $LX_STACK_END, %ebp
137         jge     leave_DCacheSetup
138         movl    $LX_NUM_CACHELINES, %edi
139
140         /* switch to next way */
141         movl    $CPU_DC_INDEX, %ecx
142         rdmsr
143         addl    $0x01, %eax
144         andl    $0xFFFFF80F, %eax /* lets be sure: reset line index Bits10:4 */
145         wrmsr
146
147         jmp     DCacheSetupFillWay
148
149 leave_DCacheSetup:
150         xorl    %edi, %edi
151         xorl    %esi, %esi
152         xorl    %ebp, %ebp
153
154         /* Disable the cache,  but ... DO NOT INVALIDATE the tags. */
155         /* Memory reads and writes will all hit in the cache. */
156         /* Cache updates and memory write-backs will not occur ! */
157         movl    %cr0, %eax
158         orl             $(CR0_CD + CR0_NW), %eax        /* set the CD and NW bits */
159         movl    %eax, %cr0
160
161         /* Now point sp to the cached stack. */
162         /* The stack will be fully functional at this location. No system memory is required at all ! */
163         /* set up the stack pointer */
164         movl    $LX_STACK_END, %eax
165         movl    %eax, %esp
166
167         /* test the stack*/
168         movl    $0x0F0F05A5A, %edx
169         pushl   %edx
170         popl    %ecx
171         cmpl    %ecx, %edx
172         je      DCacheSetupGood
173
174         post_code(0xc5)
175 DCacheSetupBad:
176         hlt             /* issues */
177         jmp DCacheSetupBad
178 DCacheSetupGood:
179         /* Go do early init and memory setup */
180
181         /* Restore the BIST result */
182         movl    %ebx, %eax
183         movl    %esp, %ebp
184         pushl   %eax
185
186         post_code(0x23)
187
188         /* Call romstage.c main function */
189         call    main
190 done_cache_as_ram_main:
191
192         /* We now run over the stack-in-cache, copying it back to itself to invalidate the cache */
193
194         push   %edi
195         mov    $(CONFIG_DCACHE_RAM_SIZE/4),%ecx
196         push   %esi
197         mov    $(CONFIG_DCACHE_RAM_BASE),%edi
198         mov    %edi,%esi
199         cld
200         rep movsl %ds:(%esi),%es:(%edi)
201         pop    %esi
202         pop    %edi
203
204         /* Clear the cache out to ram */
205         wbinvd
206         /* re-enable the cache */
207         movl    %cr0, %eax
208         xorl             $(CR0_CD + CR0_NW), %eax        /* clear  the CD and NW bits */
209         movl    %eax, %cr0
210
211         /* clear boot_complete flag */
212         xorl    %ebp, %ebp
213 __main:
214         post_code(POST_PREPARE_RAMSTAGE)
215
216         /* TODO For suspend/resume the cache will have to live between
217          * CONFIG_RAMBASE and CONFIG_RAMTOP
218          */
219
220         cld                             /* clear direction flag */
221
222         /* copy coreboot from it's initial load location to
223          * the location it is compiled to run at.
224          * Normally this is copying from FLASH ROM to RAM.
225          */
226         movl    %ebp, %esi
227         pushl   %esi
228         call copy_and_run
229
230 .Lhlt:
231         post_code(POST_DEAD_CODE)
232         hlt
233         jmp     .Lhlt
234