printk_foo -> printk(BIOS_FOO, ...)
[coreboot.git] / src / northbridge / via / vx800 / examples / romstage.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2009 One Laptop per Child, Association, 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 as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
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 ASSEMBLY 1
22 #define __PRE_RAM__
23 #define RAMINIT_SYSINFO 1
24 #define CACHE_AS_RAM_ADDRESS_DEBUG 0
25
26 #include <stdint.h>
27 #include <device/pci_def.h>
28 #include <device/pci_ids.h>
29 #include <arch/io.h>
30 #include <device/pnp_def.h>
31 #include <arch/romcc_io.h>
32 #include <arch/hlt.h>
33 #include "pc80/serial.c"
34 #include "arch/i386/lib/console.c"
35 #include "lib/ramtest.c"
36 #include "northbridge/via/vx800/vx800.h"
37 #include "cpu/x86/mtrr/earlymtrr.c"
38 #include "cpu/x86/bist.h"
39 #include "pc80/udelay_io.c"
40 #include "lib/delay.c"
41 #if CONFIG_USE_INIT == 0
42 #include "lib/memcpy.c"
43 #endif
44 #include "cpu/x86/lapic/boot_cpu.c"
45
46 #include "driving_clk_phase_data.c"
47
48 #include "northbridge/via/vx800/raminit.h"
49 #include "northbridge/via/vx800/raminit.c"
50 #include "cpu/x86/car/copy_and_run.c"
51
52 int acpi_is_wakeup_early_via_vx800(void)
53 {
54         device_t dev;
55         u16 tmp, result;
56
57         print_debug("In acpi_is_wakeup_early_via_vx800\r\n");
58         /* Power management controller */
59         dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
60                                        PCI_DEVICE_ID_VIA_VX855_LPC), 0);
61
62         if (dev == PCI_DEV_INVALID)
63                 die("Power management controller not found\r\n");
64
65         /* Set ACPI base address to I/O VX800_ACPI_IO_BASE. */
66         pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 0x1);
67
68         /* Enable ACPI accessm RTC signal gated with PSON. */
69         pci_write_config8(dev, 0x81, 0x84);
70
71         tmp = inw(VX800_ACPI_IO_BASE + 0x04);
72         result = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0;
73         print_debug("         boot_mode=");
74         print_debug_hex16(result);
75         print_debug("\r\n");
76         return result;
77 }
78
79 static inline int spd_read_byte(unsigned device, unsigned address)
80 {
81         return smbus_read_byte(device, address);
82 }
83
84
85 static void enable_mainboard_devices(void)
86 {
87         device_t dev;
88         uint16_t values;
89
90         print_debug("In enable_mainboard_devices \r\n");
91
92         /*
93            Enable P2P Bridge Header for External PCI BUS.
94          */
95         dev = pci_locate_device(PCI_ID(0x1106, 0xa353), 0);
96         pci_write_config8(dev, 0x4f, 0x41);
97 }
98
99 static void enable_shadow_ram(void)
100 {
101         uint8_t shadowreg;
102         pci_write_config8(PCI_DEV(0, 0, 3), 0x80, 0xff);
103         /* 0xf0000-0xfffff - ACPI tables */
104         shadowreg = pci_read_config8(PCI_DEV(0, 0, 3), 0x83);
105         shadowreg |= 0x30;
106         pci_write_config8(PCI_DEV(0, 0, 3), 0x83, shadowreg);
107         /* 0xe0000-0xeffff - elfload? */
108
109         pci_write_config8(PCI_DEV(0, 0, 3), 0x82, 0xff);
110
111 }
112
113
114 /*
115 this table contains the value needed to be set before begin to init dram.
116 Note: REV_Bx should be cared when porting a new board!!!!! */
117 static const struct VIA_PCI_REG_INIT_TABLE mNbStage1InitTbl[] = {
118         //VT3409 no pcie
119         0x00, 0xFF, NB_APIC_REG(0x61), 0xFF, 0x0E,      // Set Exxxxxxx as pcie mmio config range
120         0x00, 0xFF, NB_APIC_REG(0x60), 0xF4, 0x0B,      // Support extended cfg address of pcie
121         //0x00, 0xFF, NB_APIC_REG(0x42), 0xF9, 0x02, // APIC Interrupt((BT_INTR)) Control
122         // Set ROMSIP value by software
123
124         /*0x00, 0xFF, NB_HOST_REG(0x70), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pullup Driving = 3
125            0x00, 0xFF, NB_HOST_REG(0x71), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pulldown Driving = 3
126            0x00, 0xFF, NB_HOST_REG(0x72), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pullup Driving = 3
127            0x00, 0xFF, NB_HOST_REG(0x73), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pulldown Driving = 3
128            0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0x21, // Memory I/F timing ctrl
129            0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0xE1, // Memory I/F timing ctrl
130            0x00, 0xFF, NB_HOST_REG(0x75), 0xFF, 0x18, // AGTL+ I/O Circuit
131            0x00, 0xFF, NB_HOST_REG(0x76), 0xFB, 0x0C, // AGTL+ Compensation Status
132            0x00, 0xFF, NB_HOST_REG(0x78), 0xFF, 0x33, // 2X AGTL+ Auto Compensation Offset
133            0x00, 0xFF, NB_HOST_REG(0x79), 0xFF, 0x33, // 4X AGTL+ Auto Compensation Offset
134            0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x72, // AGTL Compensation Status
135            0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x77, // AGTL Compensation Status
136            0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x44, // Input Host Address / Host Strobe Delay Control for HA Group
137            0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x22, // Input Host Address / Host Strobe Delay Control for HA Group
138            0x00, 0xFF, NB_HOST_REG(0x7C), 0xFF, 0x00, // Output Delay Control of PAD for HA Group
139            0x00, 0xFF, NB_HOST_REG(0x7D), 0xFF, 0xAA, // Host Address / Address Clock Output Delay Control (Only for P4 Bus)
140            0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
141            0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
142            0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
143            0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
144            0x00, 0xFF, NB_HOST_REG(0x80), 0x3F, 0x44, // Host Data Receiving Strobe Delay Ctrl 1
145            0x00, 0xFF, NB_HOST_REG(0x81), 0xFF, 0x44, // Host Data Receiving Strobe Delay Ctrl 2
146            0x00, 0xFF, NB_HOST_REG(0x82), 0xFF, 0x00, // Output Delay of PAD for HDSTB
147            0x00, 0xFF, NB_HOST_REG(0x83), 0xFF, 0x00, // Output Delay of PAD for HD
148            0x00, 0xFF, NB_HOST_REG(0x84), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 0)
149            0x00, 0xFF, NB_HOST_REG(0x85), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 1)
150            0x00, 0xFF, NB_HOST_REG(0x86), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 2)
151            0x00, 0xFF, NB_HOST_REG(0x87), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 3) */
152
153
154         // CPU Host Bus Control
155         0x00, 0xFF, NB_HOST_REG(0x50), 0x1F, 0x08,      // Request phase ctrl: Dynamic Defer Snoop Stall Count = 8
156         //0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7F, // CPU I/F Ctrl-1: Disable Fast DRDY and RAW
157         0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7C,      // CPU I/F Ctrl-1: Disable Fast DRDY and RAW
158         0x00, 0xFF, NB_HOST_REG(0x52), 0xCB, 0xCB,      // CPU I/F Ctrl-2: Enable all for performance
159         //0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x88, // Arbitration: Host/Master Occupancy timer = 8*4 HCLK
160         0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x44,      // Arbitration: Host/Master Occupancy timer = 4*4 HCLK
161         0x00, 0xFF, NB_HOST_REG(0x54), 0x1E, 0x1C,      // Misc Ctrl: Enable 8QW burst Mem Access
162         //0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x06, // Miscellaneous Control 2
163         0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x04,      // Miscellaneous Control 2
164         0x00, 0xFF, NB_HOST_REG(0x56), 0xF7, 0x63,      // Write Policy 1
165         //0x00, 0xFF, NB_HOST_REG(0x59), 0x3D, 0x01, // CPU Miscellaneous Control 1, enable Lowest-Priority IPL
166         //0x00, 0xFF, NB_HOST_REG(0x5c), 0xFF, 0x00, // CPU Miscellaneous Control 2
167         0x00, 0xFF, NB_HOST_REG(0x5D), 0xFF, 0xA2,      // Write Policy
168         0x00, 0xFF, NB_HOST_REG(0x5E), 0xFF, 0x88,      // Bandwidth Timer
169         0x00, 0xFF, NB_HOST_REG(0x5F), 0x46, 0x46,      // CPU Misc Ctrl
170         // 0x00, 0xFF, NB_HOST_REG(0x90), 0xFF, 0x0B, // CPU Miscellaneous Control 3
171         //0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0B, // CPU Miscellaneous Control 2
172         0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0A,      // CPU Miscellaneous Control 2
173         0x00, 0xFF, NB_HOST_REG(0x98), 0xC1, 0x41,      // CPU Miscellaneous Control 3
174         0x00, 0xFF, NB_HOST_REG(0x99), 0x0E, 0x06,      // CPU Miscellaneous Control 4
175
176
177         // Set APIC and SMRAM
178         0x00, 0xFF, NB_HOST_REG(0x97), 0xFF, 0x00,      // APIC Related Control
179         0x00, 0xFF, NB_DRAMC_REG(0x86), 0xD6, 0x29,     // SMM and APIC Decoding: enable APIC, MSI and SMRAM A-Seg
180         0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // End of the table
181 };
182
183 #define USE_VCP     1           //0 means use DVP
184 #define USE_COM1    1
185 #define USE_COM2    0
186
187 #define gCom1Base   0x3f8
188 #define gCom2Base   0x2f8
189 void EmbedComInit()
190 {
191         u8 ByteVal;
192         u16 ComBase;
193
194         //enable NB multiple function control
195         ByteVal = pci_read_config8(PCI_DEV(0, 0, 0), 0x4f);
196         ByteVal = ByteVal | 0x01;
197         pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, ByteVal);
198
199         //VGA Enable
200         ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA1);
201         ByteVal = ByteVal | 0x80;
202         pci_write_config8(PCI_DEV(0, 0, 3), 0xA1, ByteVal);
203
204         ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA7);
205         ByteVal = ByteVal | 0x08;
206         pci_write_config8(PCI_DEV(0, 0, 3), 0xA7, ByteVal);
207
208         //Enable p2p  IO/mem
209         ByteVal = pci_read_config8(PCI_DEV(0, 1, 0), 0x4);
210         ByteVal = ByteVal | 0x07;
211         pci_write_config8(PCI_DEV(0, 1, 0), 0x4, ByteVal);
212
213         //Turn on Graphic chip IO port port access
214         ByteVal = inb(0x3C3);
215         ByteVal = ByteVal | 0x01;
216         outb(ByteVal, 0x3C3);
217
218         //Turn off Graphic chip Register protection
219         outb(0x10, 0x3C4);
220         ByteVal = inb(0x3C5);
221         ByteVal = ByteVal | 0x01;
222         outb(ByteVal, 0x3C5);
223
224         //south module pad share enable 0x3C5.78[7]
225         outb(0x78, 0x3C4);
226         ByteVal = inb(0x3C5);
227         ByteVal = ByteVal | 0x80;
228         outb(ByteVal, 0x3C5);
229
230         //enable  UART Function multiplex with DVP or VCP pad D17F0Rx46[7,6]
231         ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0x46);
232         //multiplex with VCP
233         if (USE_VCP == 1)
234                 ByteVal = (ByteVal & 0x3F) | 0x40;
235         //multiplex with DVP
236         else
237                 ByteVal = (ByteVal & 0x3F) | 0xC0;
238         pci_write_config8(PCI_DEV(0, 17, 0), 0x46, ByteVal);
239
240
241
242         //enable embeded com1 and com2 D17F0RxB0[5,4]
243         ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xB0);
244         ByteVal = ByteVal & 0xcf;
245         //multiplex with VCP
246         if (USE_COM1 == 1)
247                 ByteVal = ByteVal | 0x10;
248         if (USE_COM2 == 1)
249                 ByteVal = ByteVal | 0x20;
250         pci_write_config8(PCI_DEV(0, 17, 0), 0xB0, ByteVal);
251
252         if (USE_COM1 == 1)
253                 ComBase = gCom1Base;
254         else
255                 ComBase = gCom2Base;
256
257 //noharddrive
258
259         //set embeded com1 IO base = 0x3E8
260         //D17F0RB4
261         //ByteVal = 0xFD;
262         if (USE_COM1 == 1) {
263                 ByteVal = (u8) ((gCom1Base >> 3) | 0x80);
264                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB4, ByteVal);
265                 ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2);
266                 ByteVal = (ByteVal & 0xf0) | 0x04;
267                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal);
268         }
269         //set embeded com2 IO base = 0x2E8
270         //D17F0RB5
271         //ByteVal = 0xDD;
272         if (USE_COM2 == 1) {
273                 ByteVal = (u8) ((gCom2Base >> 3) | 0x80);
274                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB5, ByteVal);
275                 ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2);
276                 ByteVal = (ByteVal & 0x0f) | 0x30;
277                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal);
278         }
279         //no port 80 biger then 0x10
280
281         //disable interrupt
282         ByteVal = inb(ComBase + 3);
283         outb(ByteVal & 0x7F, ComBase + 3);
284         outb(0x00, ComBase + 1);
285
286         //set baudrate
287         ByteVal = inb(ComBase + 3);
288         outb(ByteVal | 0x80, ComBase + 3);
289         outb(0x01, ComBase);
290         outb(0x00, ComBase + 1);
291
292         //set  frame  fromat
293         ByteVal = inb(ComBase + 3);
294         outb(ByteVal & 0x3F, ComBase + 3);
295         outb(0x03, ComBase + 3);
296         outb(0x00, ComBase + 2);
297         outb(0x00, ComBase + 4);
298
299         //SOutput("Embeded com output\n");
300         //while(1);
301 }
302
303 /* cache_as_ram.inc jump to here
304 */
305 void amd64_main(unsigned long bist)
306 {
307         unsigned cpu_reset = 0;
308         u16 boot_mode;
309         u8 rambits;
310
311         //device_t dev;
312         /* Enable multifunction for northbridge. */
313         pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, 0x01);
314         EmbedComInit();
315         //enable_vx800_serial();
316         //uart_init();
317
318
319 /*      1.    D15F0
320
321 a)      RxBAh = 71h
322
323 b)      RxBBh = 05h
324
325 c)      RxBEh = 71h
326
327 d)      RxBFh = 05h
328
329 2.    D17F0
330
331 a)      RxA0h = 06h
332
333 b)      RxA1h = 11h
334
335 c)      RxA2h = 27h
336
337 d)      RxA3h = 32h
338
339 e)      Rx79h = 40h
340
341 f)      Rx72h = 27h
342
343 g)      Rx73h = 32h
344 */
345
346         u8 Data8;
347
348         pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBA,
349                            PCI_DEVICE_ID_VIA_VX855_IDE);
350         pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBE,
351                            PCI_DEVICE_ID_VIA_VX855_IDE);
352         pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA0, PCI_VENDOR_ID_VIA);
353         pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA2,
354                            PCI_DEVICE_ID_VIA_VX855_LPC);
355         Data8 = pci_read_config8(PCI_DEV(0, 0x11, 0), 0x79);
356         Data8 &= ~0x40;
357         Data8 |= 0x40;
358         pci_write_config8(PCI_DEV(0, 0x11, 0), 0x79, Data8);
359         pci_write_config16(PCI_DEV(0, 0x11, 0), 0x72,
360                            PCI_DEVICE_ID_VIA_VX855_LPC);
361
362         console_init();         //there are to function defination of console_init(), while the src/archi386/lib is the right one
363
364         /* decide if this is a s3 wakeup or a normal boot */
365         boot_mode = acpi_is_wakeup_early_via_vx800();
366         /*add this, to transfer "cpu restart" to "cold boot"
367            When this boot is not a S3 resume, and PCI registers had been written, 
368            then this must be a cpu restart(result of os reboot cmd). so we need a real "cold boot". */
369         if ((boot_mode != 3)
370             && (pci_read_config8(PCI_DEV(0, 0, 3), 0x80) != 0)) {
371                 outb(6, 0xcf9);
372         }
373
374         /*x86 cold boot I/O cmd */
375         enable_smbus();
376         //smbus_fixup(&ctrl);// this fix does help vx800!, but vx855 no need this 
377
378         if (bist == 0) {
379                 // CAR need mtrr untill mem is ok, so i disable this early_mtrr_init();
380                 //print_debug("doing early_mtrr\r\n");
381                 //early_mtrr_init();
382         }
383
384         /* Halt if there was a built-in self test failure. */
385         report_bist_failure(bist);
386
387         print_debug("Enabling mainboard devices\r\n");
388         enable_mainboard_devices();
389
390         u8 Data;
391         device_t device;
392         /* Get NB Chip revision from D0F4RxF6, revision will be used in via_pci_inittable */
393         device = PCI_DEV(0, 0, 4);
394         Data = pci_read_config8(device, 0xf6);
395         print_debug("NB chip revision =");
396         print_debug_hex8(Data);
397         print_debug("\r\n");
398         /* make NB ready before draminit */
399         via_pci_inittable(Data, mNbStage1InitTbl);
400
401         /*add this.
402            When resume from s3, draminit is skiped, so need to recovery any PCI register related to draminit.
403            and d0f3 didnt lost its Power during whole s3 time, so any register not belongs to d0f3 need to be recoveried . */
404 #if 1
405         if (boot_mode == 3) {
406                 u8 i;
407                 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
408                 DRAM_SYS_ATTR DramAttr;
409
410                 print_debug("This is a S3 wakeup\r\n");
411
412                 memset(&DramAttr, 0, sizeof(DRAM_SYS_ATTR));
413                 /*Step1 DRAM Detection; DDR1 or DDR2; Get SPD Data; Rank Presence;64 or 128bit; Unbuffered or registered; 1T or 2T */
414                 DRAMDetect(&DramAttr);
415
416                 /*begin to get ram size, 43,42 41 40 contains the end address of last rank in ddr2-slot */
417                 device = PCI_DEV(0, 0, 3);
418                 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
419                         rambits = pci_read_config8(device, ramregs[i]);
420                         if (rambits != 0)
421                                 break;
422                 }
423
424                 DRAMDRDYSetting(&DramAttr);
425
426                 Data = 0x80;    // this value is same with dev_init.c
427                 pci_write_config8(PCI_DEV(0, 0, 4), 0xa3, Data);
428                 pci_write_config8(PCI_DEV(0, 17, 7), 0x60, rambits << 2);
429                 Data = pci_read_config8(MEMCTRL, 0x88);
430                 pci_write_config8(PCI_DEV(0, 17, 7), 0xE5, Data);
431
432                 DRAMRegFinalValue(&DramAttr);   // I just copy this function from draminit to here!
433                 SetUMARam();    // I just copy this function from draminit to here!
434                 print_debug("Resume from S3, RAM init was ignored\r\n");
435         } else {
436                 ddr2_ram_setup();
437                 ram_check(0, 640 * 1024);
438         }
439 #endif
440         //ddr2_ram_setup();
441         /*this line is the same with cx700 port . */
442         enable_shadow_ram();
443
444         /*
445            For coreboot most time of S3 resume is the same as normal boot, so some memory area under 1M become dirty,
446            so before this happen, I need to backup the content of mem to top-mem. 
447            I will reserve the 1M top-men in LBIO table in coreboot_table.c and recovery the content of 1M-mem in wakeup.c
448          */
449 #if PAYLOAD_IS_SEABIOS==1       //
450         if (boot_mode == 3) {
451                 /*   some idea of Libo.Feng at amd.com in  http://www.coreboot.org/pipermail/coreboot/2008-December/043111.html
452                    I want move the 1M data, I have to set some MTRRs myself. */
453                 /* seting mtrr before back memoy save s3 resume time about 0.14 seconds */
454                 /*because CAR stack use cache, and here to use cache , must be careful, 
455                    1 during these mtrr code, must no function call, (after this mtrr, I think it should be ok to use function)
456                    2 before stack switch, no use variable that have value set before this
457                    3 due to 2, take care of "cpu_reset", I directlly set it to ZERO.
458                  */
459                 u32 memtop = *(u32 *) WAKE_MEM_INFO;
460                 u32 memtop1 = *(u32 *) WAKE_MEM_INFO - 0x100000;
461                 u32 memtop2 = *(u32 *) WAKE_MEM_INFO - 0x200000;
462                 u32 memtop3 =
463                     *(u32 *) WAKE_MEM_INFO - 64 * 1024 - 0x100000;
464                 u32 memtop4 =
465                     *(u32 *) WAKE_MEM_INFO - 64 * 1024 - 0x100000 +
466                     0xe0000;
467                 /*      __asm__ volatile (              
468                    "movl    $0x204, %%ecx\n\t"
469                    "xorl    %%edx, %%edx\n\t"
470                    "movl     %0,%%eax\n\t"
471                    "orl     $(0 | 6), %%eax\n\t"
472                    "wrmsr\n\t"
473
474                    "movl    $0x205, %%ecx\n\t"
475                    "xorl    %%edx, %%edx\n\t"
476                    "movl   $0x100000,%%eax\n\t"
477                    "decl                %%eax\n\t"
478                    "notl                %%eax\n\t"
479                    "orl    $(0 | 0x800), %%eax\n\t"
480                    "wrmsr\n\t"
481                    ::"g"(memtop2)
482                    );
483                    __asm__ volatile (           
484                    "movl    $0x206, %%ecx\n\t"
485                    "xorl    %%edx, %%edx\n\t"
486                    "movl     %0,%%eax\n\t"
487                    "orl     $(0 | 6), %%eax\n\t"
488                    "wrmsr\n\t"
489
490                    "movl    $0x207, %%ecx\n\t"
491                    "xorl    %%edx, %%edx\n\t"
492                    "movl   $0x100000,%%eax\n\t"
493                    "decl                %%eax\n\t"
494                    "notl                %%eax\n\t"
495                    "orl    $(0 | 0x800), %%eax\n\t"
496                    "wrmsr\n\t"
497                    ::"g"(memtop1)
498                    );
499                    __asm__ volatile (       
500                    "movl    $0x208, %ecx\n\t"
501                    "xorl    %edx, %edx\n\t"
502                    "movl    $0,%eax\n\t"
503                    "orl     $(0 | 6), %eax\n\t"
504                    "wrmsr\n\t"
505
506                    "movl    $0x209, %ecx\n\t"
507                    "xorl    %edx, %edx\n\t"
508                    "movl     $0x100000,%eax\n\t"
509                    "decl                %eax\n\t"
510                    "notl                %eax\n\t"
511                    "orl     $(0 | 0x800), %eax\n\t"
512                    "wrmsr\n\t"
513                    );
514                  */
515                 // WAKE_MEM_INFO is  inited in get_set_top_available_mem in tables.c
516                 // these two memcpy not not be enabled if set the MTRR around this two lines.
517                 /*__asm__ volatile (            
518                                 "movl    $0, %%esi\n\t"
519         "movl    %0, %%edi\n\t"
520         "movl    $0xa0000, %%ecx\n\t"
521         "shrl    $2, %%ecx\n\t"
522         "rep movsd\n\t"    
523         ::"g"(memtop3)        
524         );
525         __asm__ volatile (              
526                                 "movl    $0xe0000, %%esi\n\t"
527         "movl    %0, %%edi\n\t"
528         "movl    $0x20000, %%ecx\n\t"
529         "shrl    $2, %%ecx\n\t"
530         "rep movsd\n\t"    
531         ::"g"(memtop4)        
532         );*/
533                 print_debug("copy memory to high memory to protect s3 wakeup vector code \r\n");        //this can have function call, because no variable used before this
534                 memcpy((unsigned char *) ((*(u32 *) WAKE_MEM_INFO) -
535                                           64 * 1024 - 0x100000),
536                        (unsigned char *) 0, 0xa0000);
537                 memcpy((unsigned char *) ((*(u32 *) WAKE_MEM_INFO) -
538                                           64 * 1024 - 0x100000 + 0xe0000),
539                        (unsigned char *) 0xe0000, 0x20000);
540
541                 /* restore the MTRR previously modified. */
542 /*              __asm__ volatile (      
543         "wbinvd\n\t"                            
544         "xorl    %edx, %edx\n\t"
545         "xorl    %eax, %eax\n\t"
546         "movl    $0x204, %ecx\n\t"
547         "wrmsr\n\t"
548                                 "movl    $0x205, %ecx\n\t"                                      
549         "wrmsr\n\t"        
550                                 "movl    $0x206, %ecx\n\t"
551         "wrmsr\n\t"
552                                 "movl    $0x207, %ecx\n\t"                     
553         "wrmsr\n\t"        
554                                 "movl    $0x208, %ecx\n\t"                     
555         "wrmsr\n\t"        
556                                 "movl    $0x209, %ecx\n\t"                     
557         "wrmsr\n\t"        
558                 );*/
559         }
560 #endif
561 /*
562 the following code is  copied from src/mainboard/tyan/s2735/romstage.c
563 Only the code around CLEAR_FIRST_1M_RAM is changed.
564 I remove all the code around CLEAR_FIRST_1M_RAM and #include "cpu/x86/car/cache_as_ram_post.c"
565 the CLEAR_FIRST_1M_RAM seems to make cpu/x86/car/cache_as_ram_post.c stop at somewhere, 
566 and cpu/x86/car/cache_as_ram_post.c  do not cache my $CONFIG_XIP_ROM_BASE+SIZE area.
567
568 So, I use: #include "cpu/via/car/cache_as_ram_post.c". my via-version post.c have some diff with x86-version
569 */
570 #if 1
571         {
572                 /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
573                 unsigned v_esp;
574                 __asm__ volatile ("movl   %%esp, %0\n\t":"=a" (v_esp)
575                     );
576 #if CONFIG_USE_INIT
577                 printk(BIOS_DEBUG, "v_esp=%08x\r\n", v_esp);
578 #else
579                 print_debug("v_esp=");
580                 print_debug_hex32(v_esp);
581                 print_debug("\r\n");
582 #endif
583         }
584
585 #endif
586 #if 1
587
588       cpu_reset_x:
589 // it seems that cpu_reset is not used before this, so I just reset it, (this is because the s3 resume, setting in mtrr and copy data may destroy 
590 //stack
591         cpu_reset = 0;
592 #if CONFIG_USE_INIT
593         printk(BIOS_DEBUG, "cpu_reset = %08x\r\n", cpu_reset);
594 #else
595         print_debug("cpu_reset = ");
596         print_debug_hex32(cpu_reset);
597         print_debug("\r\n");
598 #endif
599
600         if (cpu_reset == 0) {
601                 print_debug("Clearing initial memory region: ");
602         }
603         print_debug("No cache as ram now - ");
604
605         /* store cpu_reset to ebx */
606         __asm__ volatile ("movl %0, %%ebx\n\t"::"a" (cpu_reset)
607             );
608
609
610 /* cancel these lines, CLEAR_FIRST_1M_RAM cause the cpu/x86/car/cache_as_ram_post.c stop at somewhere
611
612         if(cpu_reset==0) {
613 #define CLEAR_FIRST_1M_RAM 1
614 #include "cpu/via/car/cache_as_ram_post.c"      
615         }
616         else {
617 #undef CLEAR_FIRST_1M_RAM 
618 #include "cpu/via/car/cache_as_ram_post.c"
619         }
620 */
621 #include "cpu/via/car/cache_as_ram_post.c"
622 //#include "cpu/x86/car/cache_as_ram_post.c"    
623         __asm__ volatile (
624                                  /* set new esp *//* before CONFIG_RAMBASE */
625                                  "subl   %0, %%ebp\n\t"
626                                  "subl   %0, %%esp\n\t"::
627                                  "a" ((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE) -
628                                       CONFIG_RAMBASE)
629             );
630
631         {
632                 unsigned new_cpu_reset;
633
634                 /* get back cpu_reset from ebx */
635                 __asm__ volatile ("movl %%ebx, %0\n\t":"=a" (new_cpu_reset)
636                     );
637
638                 /* We can not go back any more, we lost old stack data in cache as ram */
639                 if (new_cpu_reset == 0) {
640                         print_debug("Use Ram as Stack now - done\r\n");
641                 } else {
642                         print_debug("Use Ram as Stack now - \r\n");
643                 }
644 #if CONFIG_USE_INIT
645                 printk(BIOS_DEBUG, "new_cpu_reset = %08x\r\n", new_cpu_reset);
646 #else
647                 print_debug("new_cpu_reset = ");
648                 print_debug_hex32(new_cpu_reset);
649                 print_debug("\r\n");
650 #endif
651                 /*copy and execute coreboot_ram */
652                 copy_and_run(new_cpu_reset);
653                 /* We will not return */
654         }
655 #endif
656
657
658         print_debug("should not be here -\r\n");
659
660 }