Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 1 | /* |
Stefan Reinauer | 6220b63 | 2008-01-27 18:54:57 +0000 | [diff] [blame] | 2 | * This file is part of the coreboot project. |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 3 | * |
| 4 | * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com> |
| 5 | * Copyright (C) 2005 Eswar Nallusamy, LANL |
| 6 | * Copyright (C) 2005 Tyan |
| 7 | * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan) |
| 8 | * Copyright (C) 2007 coresystems GmbH |
| 9 | * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH) |
| 10 | * Copyright (C) 2007 Advanced Micro Devices, Inc. |
| 11 | * |
| 12 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of the GNU General Public License as published by |
| 14 | * the Free Software Foundation; version 2 of the License. |
| 15 | * |
| 16 | * This program is distributed in the hope that it will be useful, |
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | * GNU General Public License for more details. |
| 20 | * |
| 21 | * You should have received a copy of the GNU General Public License |
| 22 | * along with this program; if not, write to the Free Software |
| 23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 24 | */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 25 | |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 26 | /* Init code - Switch CPU to protected mode and enable Cache-as-Ram (CAR). */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 27 | |
Ronald G. Minnich | 24d5ad5 | 2008-08-04 00:39:28 +0000 | [diff] [blame] | 28 | #include <macros.h> |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 29 | #include <amd_geodelx.h> |
| 30 | |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 31 | |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 32 | /* When we come here we are in protected mode. We expand the stack |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 33 | * and copy the data segment from ROM to the memory. |
| 34 | * |
| 35 | * After that, we call the chipset bootstrap routine that |
| 36 | * does what is left of the chipset initialization. |
| 37 | * |
Carl-Daniel Hailfinger | ef06e83 | 2008-10-07 21:59:21 +0000 | [diff] [blame] | 38 | * NOTE: Aligned to 4 so that we are sure that the prefetch |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 39 | * cache will be reloaded. |
| 40 | */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 41 | |
| 42 | .align 4 |
| 43 | .globl protected_stage0 |
| 44 | protected_stage0: |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 45 | /* This code was used by v2. TODO. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 46 | lgdt %cs:gdtptr |
| 47 | ljmp $ROM_CODE_SEG, $__protected_stage0 |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 48 | |
| 49 | .globl __protected_stage0 |
| 50 | __protected_stage0: |
Carl-Daniel Hailfinger | 7b5c164 | 2008-10-06 23:26:29 +0000 | [diff] [blame] | 51 | /* Save the BIST result. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 52 | movl %eax, %ebp |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 53 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 54 | port80_post(0x01) |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 55 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 56 | movw $ROM_DATA_SEG, %ax |
| 57 | movw %ax, %ds |
| 58 | movw %ax, %es |
| 59 | movw %ax, %ss |
| 60 | movw %ax, %fs |
| 61 | movw %ax, %gs |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 62 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 63 | /* Restore the BIST value to %eax. */ |
| 64 | movl %ebp, %eax |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 65 | |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 66 | .align 4 |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 67 | /* Here begins CAR support. */ |
Stefan Reinauer | 6220b63 | 2008-01-27 18:54:57 +0000 | [diff] [blame] | 68 | /* This particular code is straight from coreboot v2. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 69 | |
| 70 | /* DCacheSetup: Setup data cache for use as RAM for a stack. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 71 | DCacheSetup: |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 72 | invd |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 73 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 74 | /* Set cache properties. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 75 | movl $CPU_RCONF_DEFAULT, %ecx |
| 76 | rdmsr |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 77 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 78 | /* 1MB system memory in write back 1|00100|00. */ |
| 79 | movl $0x010010000, %eax |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 80 | wrmsr |
| 81 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 82 | /* In LX DCDIS is set after POR which disables the cache..., clear |
| 83 | * this bit. |
| 84 | */ |
Marc Jones | 064cd70 | 2007-07-19 15:15:57 +0000 | [diff] [blame] | 85 | movl $CPU_DM_CONFIG0,%ecx |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 86 | rdmsr |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 87 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 88 | /* TODO: Make consistent with i$ init, either whole reg = 0, or just |
| 89 | * this bit... |
| 90 | */ |
| 91 | andl $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 92 | wrmsr |
| 93 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 94 | /* Get cache timing params from BIOS config data locations and apply. */ |
| 95 | /* Fix delay controls for DM and IM arrays. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 96 | movl $CPU_BC_MSS_ARRAY_CTL0, %ecx |
| 97 | xorl %edx, %edx |
| 98 | movl $0x2814D352, %eax |
| 99 | wrmsr |
| 100 | |
| 101 | movl $CPU_BC_MSS_ARRAY_CTL1, %ecx |
| 102 | xorl %edx, %edx |
| 103 | movl $0x1068334D, %eax |
| 104 | wrmsr |
| 105 | |
| 106 | movl $CPU_BC_MSS_ARRAY_CTL2, %ecx |
| 107 | movl $0x00000106, %edx |
| 108 | movl $0x83104104, %eax |
| 109 | wrmsr |
| 110 | |
| 111 | movl $GLCP_FIFOCTL, %ecx |
| 112 | rdmsr |
| 113 | movl $0x00000005, %edx |
| 114 | wrmsr |
| 115 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 116 | /* Enable setting. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 117 | movl $CPU_BC_MSS_ARRAY_CTL_ENA, %ecx |
| 118 | xorl %edx, %edx |
| 119 | movl $0x01, %eax |
| 120 | wrmsr |
| 121 | |
| 122 | /* Get cleaned up. */ |
| 123 | xorl %edi, %edi |
| 124 | xorl %esi, %esi |
| 125 | xorl %ebp, %ebp |
| 126 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 127 | /* DCache Ways0 through Ways7 will be tagged for |
| 128 | * LX_STACK_BASE + DCACHE_RAM_SIZE for holding stack. |
| 129 | */ |
| 130 | /* Remember, there is NO stack yet... */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 131 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 132 | /* Tell cache we want to fill Way 0 starting at the top. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 133 | xorl %edx, %edx |
| 134 | xorl %eax, %eax |
| 135 | movl $CPU_DC_INDEX, %ecx |
| 136 | wrmsr |
| 137 | |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 138 | /* Start address for tag of Way0: ebp will hold the incrementing |
| 139 | * address. Don't destroy! |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 140 | */ |
| 141 | movl $LX_STACK_BASE, %ebp /* Init to start address. */ |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 142 | |
| 143 | /* Set valid bit and tag for this Way (B[31:12]: Cache tag value for |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 144 | * line/way curr. selected by CPU_DC_INDEX. |
| 145 | */ |
| 146 | orl $1, %ebp |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 147 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 148 | /* Start tag Ways 0 with 128 lines with 32 bytes each: edi will hold |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 149 | * the line counter. Don't destroy! |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 150 | */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 151 | movl $LX_NUM_CACHELINES, %edi |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 152 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 153 | DCacheSetupFillWay: |
| 154 | /* Fill with dummy data: zero it so we can tell it from PCI memory |
| 155 | * space (returns FFs). |
| 156 | */ |
| 157 | /* We will now store a line (32 bytes = 4 x 8 bytes = 4 quad-words). */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 158 | movw $0x04, %si |
| 159 | xorl %edx, %edx |
| 160 | xorl %eax, %eax |
| 161 | movl $CPU_DC_DATA, %ecx |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 162 | |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 163 | DCacheSetup_quadWordLoop: |
| 164 | wrmsr |
| 165 | decw %si |
| 166 | jnz DCacheSetup_quadWordLoop |
| 167 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 168 | /* Set the tag for this line, need to do this for every new cache |
| 169 | * line to validate it! |
| 170 | */ |
| 171 | /* Accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX |
| 172 | * increment and thus continue in the next cache line... |
| 173 | */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 174 | xorl %edx, %edx |
| 175 | movl %ebp, %eax |
| 176 | movl $CPU_DC_TAG, %ecx |
| 177 | wrmsr |
| 178 | |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 179 | /* Switch to next line. Lines are in bits 10:4. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 180 | /* When index is crossing 0x7F -> 0x80 writing a RSVD bit as 0x80 is |
| 181 | * not a valid CL anymore! |
| 182 | */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 183 | movl $CPU_DC_INDEX, %ecx |
| 184 | rdmsr |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 185 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 186 | /* TODO: Probably would be more elegant to calculate this from |
| 187 | * counter var edi... |
| 188 | */ |
| 189 | addl $0x010, %eax |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 190 | wrmsr |
| 191 | |
| 192 | decl %edi |
| 193 | jnz DCacheSetupFillWay |
| 194 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 195 | /* 1 Way has been filled, forward start address for next Way, |
| 196 | * terminate if we have reached end of desired address range. |
| 197 | */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 198 | addl $LX_CACHEWAY_SIZE, %ebp |
| 199 | cmpl $LX_STACK_END, %ebp |
| 200 | jge leave_DCacheSetup |
| 201 | movl $LX_NUM_CACHELINES, %edi |
| 202 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 203 | /* Switch to next way. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 204 | movl $CPU_DC_INDEX, %ecx |
| 205 | rdmsr |
| 206 | addl $0x01, %eax |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 207 | |
| 208 | /* Let's be sure: reset line index bits 10:4. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 209 | andl $0xFFFFF80F, %eax |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 210 | wrmsr |
| 211 | |
| 212 | jmp DCacheSetupFillWay |
| 213 | |
| 214 | leave_DCacheSetup: |
| 215 | xorl %edi, %edi |
| 216 | xorl %esi, %esi |
| 217 | xorl %ebp, %ebp |
| 218 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 219 | /* Disable the cache, but... DO NOT INVALIDATE the tags. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 220 | /* Memory reads and writes will all hit in the cache. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 221 | /* Cache updates and memory write-backs will not occur! */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 222 | movl %cr0, %eax |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 223 | orl $(CR0_CD + CR0_NW), %eax /* Set the CD and NW bits. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 224 | movl %eax, %cr0 |
| 225 | |
| 226 | /* Now point sp to the cached stack. */ |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 227 | /* The stack will be fully functional at this location. No system |
| 228 | * memory is required at all! |
| 229 | */ |
| 230 | /* Set up the stack pointer. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 231 | movl $LX_STACK_END, %eax |
| 232 | movl %eax, %esp |
| 233 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 234 | /* Test the stack. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 235 | movl $0x0F0F05A5A, %edx |
| 236 | pushl %edx |
| 237 | popl %ecx |
| 238 | cmpl %ecx, %edx |
| 239 | je DCacheSetupGood |
| 240 | movb $0xC5, %al |
| 241 | outb %al, $0x80 |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 242 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 243 | DCacheSetupBad: |
| 244 | hlt /* Issues */ |
| 245 | jmp DCacheSetupBad |
| 246 | |
| 247 | DCacheSetupGood: |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 248 | /* At this point, CAR should be working. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 249 | movl $(LX_STACK_END), %eax |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 250 | movl %eax, %esp |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 251 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 252 | /* Load a different set of data segments. */ |
| 253 | movw $CACHE_RAM_DATA_SEG, %ax |
| 254 | movw %ax, %ds |
| 255 | movw %ax, %es |
| 256 | movw %ax, %ss |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 257 | |
| 258 | lout: |
Carl-Daniel Hailfinger | 1b5c399 | 2008-08-18 16:54:12 +0000 | [diff] [blame] | 259 | /* Store zero for the pointer to the global variables. */ |
| 260 | movl $0, %eax |
| 261 | pushl %eax |
| 262 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 263 | /* Restore the BIST result. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 264 | movl %ebp, %eax |
Uwe Hermann | 203bffe | 2007-07-07 21:18:47 +0000 | [diff] [blame] | 265 | |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 266 | /* We need to set ebp? No need. */ |
Stefan Reinauer | 5dfd441 | 2007-05-19 08:44:14 +0000 | [diff] [blame] | 267 | movl %esp, %ebp |
Carl-Daniel Hailfinger | 96fcf12 | 2008-10-07 23:53:02 +0000 | [diff] [blame] | 268 | |
Marc Jones | f287276 | 2009-02-10 22:41:35 +0000 | [diff] [blame] | 269 | /* Third parameter: cpu #: 0 == BSP all other are APs. |
| 270 | * Always 0 for Geode. |
| 271 | */ |
| 272 | pushl $0 |
Carl-Daniel Hailfinger | 96fcf12 | 2008-10-07 23:53:02 +0000 | [diff] [blame] | 273 | /* Second parameter: init_detected */ |
| 274 | /* Store zero for the unused init_detected parameter. */ |
| 275 | pushl $0 |
| 276 | /* First parameter: bist */ |
| 277 | pushl %eax |
Carl-Daniel Hailfinger | 33de3b2 | 2008-10-16 03:00:28 +0000 | [diff] [blame] | 278 | call stage1_phase1 |
Uwe Hermann | bd53a46 | 2007-05-19 21:31:23 +0000 | [diff] [blame] | 279 | /* We will not go back. */ |
| 280 | |
Carl-Daniel Hailfinger | 73d4383 | 2008-10-08 16:07:29 +0000 | [diff] [blame] | 281 | #include "../stage0_common.S" |