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