16aefc0961155859b2ab2dacac027a639ef99f9d
[coreboot.git] / src / mainboard / pcengines / alix1c / cache_as_ram_auto.c
1 /*
2  * This file is part of the LinuxBIOS 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 ASSEMBLY 1
21
22 #include <stdint.h>
23 #include <device/pci_def.h>
24 #include <arch/io.h>
25 #include <device/pnp_def.h>
26 #include <arch/romcc_io.h>
27 #include <arch/hlt.h>
28 #include "pc80/serial.c"
29 #include "arch/i386/lib/console.c"
30 #include "ram/ramtest.c"
31 #include "cpu/x86/bist.h"
32 #include "cpu/x86/msr.h"
33 #include <cpu/amd/lxdef.h>
34 #include <cpu/amd/geode_post_code.h>
35 #include "southbridge/amd/cs5536/cs5536.h"
36
37 #define POST_CODE(x) outb(x, 0x80)
38 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
39
40 #include "southbridge/amd/cs5536/cs5536_early_smbus.c"
41 #include "southbridge/amd/cs5536/cs5536_early_setup.c"
42 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
43
44 static inline int spd_read_byte(unsigned device, unsigned address)
45 {
46                 return smbus_read_byte(device, address);
47 }
48
49 #define ManualConf 0            /* Do automatic strapped PLL config */
50 #define PLLMSRhi 0x00001490 /* manual settings for the PLL */
51 #define PLLMSRlo 0x02000030
52 #define DIMM0 0xA0
53 #define DIMM1 0xA2
54 #include "northbridge/amd/lx/raminit.h"
55 #include "northbridge/amd/lx/pll_reset.c"
56 #include "northbridge/amd/lx/raminit.c"
57 #include "sdram/generic_sdram.c"
58 #include "cpu/amd/model_lx/cpureginit.c"
59 #include "cpu/amd/model_lx/syspreinit.c"
60
61 static void msr_init(void)
62 {
63         msr_t msr;
64         /* Setup access to the MC for under 1MB. Note MC not setup yet. */
65         msr.hi = 0x24fffc02;
66         msr.lo =  0x10010000;
67         wrmsr(CPU_RCONF_DEFAULT, msr);
68
69         msr.hi = 0x20000000;
70         msr.lo = 0xfff00;
71         wrmsr(MSR_GLIU0 + 0x20, msr);
72
73         msr.hi = 0x20000000;
74         msr.lo =  0xfff00;
75         wrmsr(MSR_GLIU1 + 0x20, msr);
76
77 }
78
79 static void mb_gpio_init(void)
80 {
81         /* Early mainboard specific GPIO setup */
82 }
83
84 void cache_as_ram_main(void)
85 {
86         extern void RestartCAR();
87         POST_CODE(0x01);
88
89         static const struct mem_controller memctrl [] = {
90                 {.channel0 = {(0xa<<3)|0, (0xa<<3)|1}}
91         };
92
93         SystemPreInit();
94         msr_init();
95
96         cs5536_early_setup();
97
98         /* NOTE: must do this AFTER the early_setup!
99          * it is counting on some early MSR setup
100          * for cs5536
101          */
102         cs5536_disable_internal_uart();
103         w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE);
104         mb_gpio_init();
105         uart_init();
106         console_init();
107
108         pll_reset(ManualConf);
109
110         cpuRegInit();
111
112         sdram_initialize(1, memctrl);
113
114         /* Check memory */
115         ram_check(0x00000000, 640 * 1024);
116
117         /* Switch from Cache as RAM to real RAM */
118         /* There are two ways we could think about this.
119          1. If we are using the auto.inc ROMCC way, the stack is going to be re-setup in the code following this code.
120                 Just wbinvd the stack to clear the cache tags. We don't care where the stack used to be.
121          2. This file is built as a normal .c -> .o and linked in etc. The stack might be used to return etc.
122                 That means we care about what is in the stack. If we are smart we set the CAR stack to the same location
123                 as the rest of LinuxBIOS. If that is the case we can just do a wbinvd. The stack will be written into real
124                 RAM that is now setup and we continue like nothing happened. If the stack is located somewhere other than
125                 where LB would like it, you need to write some code to do a copy from cache to RAM
126
127          We use method 1 on Norwich and on this board too. 
128         */
129         POST_CODE(0x02);
130         print_err("POST 02\n");
131         __asm__("wbinvd\n");
132         print_err("Past wbinvd\n");
133         /* we are finding the return does not work on this board. Explicitly call the label that is 
134          * after the call to us. This is gross, but sometimes at this level it is the only way out
135          */
136         done_cache_as_ram_main();
137 }