libpayload: code cosmetics
[coreboot.git] / src / cpu / amd / model_gx2 / cache_as_ram.inc
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007 Advanced Micro Devices, Inc.
5  * Copyright (C) 2010 Nils Jacobs
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #define GX2_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 */
22 #define GX2_STACK_END           GX2_STACK_BASE+(CONFIG_DCACHE_RAM_SIZE-1)
23
24 #define GX2_NUM_CACHELINES      0x080   /* there are 128lines per way */
25 #define GX2_CACHELINE_SIZE      0x020   /* there are 32bytes per line */
26 #define GX2_CACHEWAY_SIZE       (GX2_NUM_CACHELINES * GX2_CACHELINE_SIZE)
27 #define CR0_CD                          0x40000000      /* bit 30 = Cache Disable */
28 #define CR0_NW                          0x20000000      /* bit 29 = Not Write Through */
29 #include <cpu/amd/gx2def.h>
30 #include <cpu/x86/post_code.h>
31 /***************************************************************************
32 /**
33 /**     DCacheSetup
34 /**
35 /**     Setup data cache for  use as RAM for a stack.
36 /**
37 /**     Max. size data cache =0x4000 (16KB)
38 /**
39 /***************************************************************************/
40 DCacheSetup:
41         /* Save the BIST result */
42         movl    %eax, %ebx
43
44         invd
45         /* set cache properties */
46         movl    $CPU_RCONF_DEFAULT, %ecx
47         rdmsr
48         movl    $0x010010000, %eax              /*1MB system memory in write back 1|00100|00 */
49         wrmsr
50
51         /* in GX2 DCDIS is set after POR which disables the cache..., clear this bit */
52         movl    $CPU_DM_CONFIG0, %ecx
53         rdmsr
54         andl    $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax  /* TODO: make consistent with i$ init,  either whole reg = 0,  or just this bit... */
55         wrmsr
56
57         /* Get cleaned up. */
58         xorl    %edi, %edi
59         xorl    %esi, %esi
60         xorl    %ebp, %ebp
61
62         /* DCache Ways0 through Ways3 will be tagged for GX2_STACK_BASE + CONFIG_DCACHE_RAM_SIZE for holding stack */
63         /* remember,  there is NO stack yet... */
64
65         /* Tell cache we want to fill WAY 0 starting at the top */
66         xorl    %edx, %edx
67         xorl    %eax, %eax
68         movl    $CPU_DC_INDEX, %ecx
69         wrmsr
70
71         /* startaddress for tag of Way0: ebp will hold the incrementing address. dont destroy! */
72         movl    $GX2_STACK_BASE, %ebp   /* init to start address */
73         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 */
74
75         /* start tag Ways 0 with 128 lines with 32bytes each: edi will hold the line counter. dont destroy! */
76         movl    $GX2_NUM_CACHELINES, %edi
77 DCacheSetupFillWay:
78
79         /* fill with dummy data: zero it so we can tell it from PCI memory space (returns FFs). */
80         /* We will now store a line (32 bytes = 4 x 8bytes = 4 quadWords) */
81         movw    $0x04, %si
82         xorl    %edx, %edx
83         xorl    %eax, %eax
84         movl    $CPU_DC_DATA, %ecx
85 DCacheSetup_quadWordLoop:
86         wrmsr
87         decw    %si
88         jnz     DCacheSetup_quadWordLoop
89
90         /* Set the tag for this line,need to do this for every new cache line to validate it! */
91         /* accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX increment and thus cont. in the next cache line... */
92         xorl    %edx, %edx
93         movl    %ebp, %eax
94         movl    $CPU_DC_TAG, %ecx
95         wrmsr
96
97         /* switch to next line */
98         /* lines are in Bits8:2 */
99         /* when index is crossing 0x7F -> 0x80  writing a RSVD bit as 0x80 is not a valid CL anymore! */
100         movl    $CPU_DC_INDEX, %ecx
101         rdmsr
102         addl    $0x04, %eax /* inc DC_LINE. TODO: prob. would be more elegant to calc. this from counter var edi... */
103         wrmsr
104
105         decl    %edi
106         jnz     DCacheSetupFillWay
107
108         /* 1 Way has been filled,  forward start address for next Way,  terminate if we have reached end of desired address range */
109         addl    $GX2_CACHEWAY_SIZE, %ebp
110         cmpl    $GX2_STACK_END, %ebp
111         jge     leave_DCacheSetup
112         movl    $GX2_NUM_CACHELINES, %edi
113
114         /* switch to next way */
115         movl    $CPU_DC_INDEX, %ecx
116         rdmsr
117         addl    $0x01, %eax
118         andl    $0xFFFFFE03, %eax /* lets be sure: reset line index Bits8:2 */
119         wrmsr
120
121         jmp     DCacheSetupFillWay
122
123 leave_DCacheSetup:
124         xorl    %edi, %edi
125         xorl    %esi, %esi
126         xorl    %ebp, %ebp
127
128         /* Disable the cache,  but ... DO NOT INVALIDATE the tags. */
129         /* Memory reads and writes will all hit in the cache. */
130         /* Cache updates and memory write-backs will not occur ! */
131         movl    %cr0, %eax
132         orl             $(CR0_CD + CR0_NW), %eax        /* set the CD and NW bits */
133         movl    %eax, %cr0
134
135         /* Now point sp to the cached stack. */
136         /* The stack will be fully functional at this location. No system memory is required at all ! */
137         /* set up the stack pointer */
138         movl    $GX2_STACK_END, %eax
139         movl    %eax, %esp
140
141         /* test the stack*/
142         movl    $0x0F0F05A5A, %edx
143         pushl   %edx
144         popl    %ecx
145         cmpl    %ecx, %edx
146         je      DCacheSetupGood
147
148         post_code(0xc5)
149 DCacheSetupBad:
150         hlt             /* issues */
151         jmp DCacheSetupBad
152 DCacheSetupGood:
153         /* Go do early init and memory setup */
154
155         /* Restore the BIST result */
156         movl    %ebx, %eax
157         movl    %esp, %ebp
158         pushl   %eax
159
160         post_code(0x23)
161
162         /* Call romstage.c main function */
163         call    main
164 done_cache_as_ram_main:
165
166         /* We now run over the stack-in-cache, copying it back to itself to invalidate the cache */
167
168         push   %edi
169         mov    $(CONFIG_DCACHE_RAM_SIZE/4),%ecx
170         push   %esi
171         mov    $(CONFIG_DCACHE_RAM_BASE),%edi
172         mov    %edi,%esi
173         cld
174         rep movsl %ds:(%esi),%es:(%edi)
175         pop    %esi
176         pop    %edi
177
178         /* Clear the cache out to ram */
179         wbinvd
180         /* re-enable the cache */
181         movl    %cr0, %eax
182         xorl             $(CR0_CD + CR0_NW), %eax        /* clear  the CD and NW bits */
183         movl    %eax, %cr0
184
185         /* clear boot_complete flag */
186         xorl    %ebp, %ebp
187 __main:
188         post_code(POST_PREPARE_RAMSTAGE)
189
190         /* TODO For suspend/resume the cache will have to live between
191          * CONFIG_RAMBASE and CONFIG_RAMTOP
192          */
193
194         cld                             /* clear direction flag */
195
196         /* copy coreboot from it's initial load location to
197          * the location it is compiled to run at.
198          * Normally this is copying from FLASH ROM to RAM.
199          */
200         movl    %ebp, %esi
201         pushl   %esi
202         call copy_and_run
203
204 .Lhlt:
205         post_code(POST_DEAD_CODE)
206         hlt
207         jmp     .Lhlt
208