blob: 0c6faf76c36c64b809f14c9b3d6b76d2d0b5cbc3 [file] [log] [blame]
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +00001#define ASSEMBLY 1
Myles Watson1d6d45e2009-11-06 17:02:51 +00002#define __PRE_RAM__
Myles Watson18d7c2e2009-10-27 14:05:21 +00003
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +00004#include <stdint.h>
5#include <device/pci_def.h>
6#include <arch/io.h>
7#include <device/pnp_def.h>
8#include <arch/romcc_io.h>
9#include <cpu/x86/lapic.h>
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +000010#include <stdlib.h>
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +000011#include "option_table.h"
12#include "pc80/mc146818rtc_early.c"
13#include "pc80/serial.c"
14#include "arch/i386/lib/console.c"
Stefan Reinauerc13093b2009-09-23 18:51:03 +000015#include "lib/ramtest.c"
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +000016
17#include <cpu/amd/model_fxx_rev.h>
18#include "northbridge/amd/amdk8/incoherent_ht.c"
19#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
20#include "northbridge/amd/amdk8/raminit.h"
21#include "cpu/amd/model_fxx/apic_timer.c"
22#include "lib/delay.c"
23
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +000024#include "cpu/x86/lapic/boot_cpu.c"
25#include "northbridge/amd/amdk8/reset_test.c"
26#include "northbridge/amd/amdk8/debug.c"
27#include "superio/nsc/pc87360/pc87360_early_serial.c"
28
29#include "cpu/amd/mtrr/amd_earlymtrr.c"
30#include "cpu/x86/bist.h"
31
32#include "northbridge/amd/amdk8/setup_resource_map.c"
33
34#define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
35
36#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
37
38/*
39 * GPIO28 of 8111 will control H0_MEMRESET_L
40 * GPIO29 of 8111 will control H1_MEMRESET_L
41 */
42static void memreset_setup(void)
43{
44 if (is_cpu_pre_c0()) {
45 /* Set the memreset low */
46 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
47 /* Ensure the BIOS has control of the memory lines */
48 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
49 }
50 else {
51 /* Ensure the CPU has controll of the memory lines */
52 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 29);
53 }
54}
55
56static void memreset(int controllers, const struct mem_controller *ctrl)
57{
58 if (is_cpu_pre_c0()) {
59 udelay(800);
60 /* Set memreset_high */
61 outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
62 udelay(90);
63 }
64}
65
66static inline void activate_spd_rom(const struct mem_controller *ctrl)
67{
68 /* nothing to do */
69}
70
71static inline int spd_read_byte(unsigned device, unsigned address)
72{
73 return smbus_read_byte(device, address);
74}
75
76#define QRANK_DIMM_SUPPORT 1
77
78#include "northbridge/amd/amdk8/raminit.c"
79#include "northbridge/amd/amdk8/resourcemap.c"
80#include "northbridge/amd/amdk8/coherent_ht.c"
Stefan Reinauerc13093b2009-09-23 18:51:03 +000081#include "lib/generic_sdram.c"
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +000082
83#if CONFIG_LOGICAL_CPUS==1
84#define SET_NB_CFG_54 1
85#endif
86#include "cpu/amd/dualcore/dualcore.c"
87
88#define FIRST_CPU 1
89#define SECOND_CPU 1
90#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
91
92#include "cpu/amd/car/copy_and_run.c"
93
94#include "cpu/amd/car/post_cache_as_ram.c"
95
96#include "cpu/amd/model_fxx/init_cpus.c"
97
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +000098#include "southbridge/amd/amd8111/amd8111_enable_rom.c"
99#include "northbridge/amd/amdk8/early_ht.c"
100
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000101void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
102{
Myles Watson18d7c2e2009-10-27 14:05:21 +0000103 static const uint16_t spd_addr [] = {
104 (0xa<<3)|0, (0xa<<3)|2, 0, 0,
105 (0xa<<3)|1, (0xa<<3)|3, 0, 0,
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000106#if CONFIG_MAX_PHYSICAL_CPUS > 1
Myles Watson18d7c2e2009-10-27 14:05:21 +0000107 (0xa<<3)|4, (0xa<<3)|6, 0, 0,
108 (0xa<<3)|5, (0xa<<3)|7, 0, 0,
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000109#endif
110 };
111
Myles Watson18d7c2e2009-10-27 14:05:21 +0000112 int needs_reset;
113 unsigned bsp_apicid = 0;
114 struct mem_controller ctrl[8];
115 unsigned nodes;
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000116
Patrick Georgi2bd91002010-03-18 16:46:50 +0000117 if (!cpu_init_detectedx && boot_cpu()) {
Patrick Georgi776b85b2010-03-18 16:18:58 +0000118 /* Nothing special needs to be done to find bus 0 */
119 /* Allow the HT devices to be found */
120
121 enumerate_ht_chain();
122
123 amd8111_enable_rom();
124 }
125
Myles Watson18d7c2e2009-10-27 14:05:21 +0000126 if (bist == 0) {
127 bsp_apicid = init_cpus(cpu_init_detectedx);
128 }
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000129
Stefan Reinauer08670622009-06-30 15:17:49 +0000130 pc87360_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
Myles Watson18d7c2e2009-10-27 14:05:21 +0000131 uart_init();
132 console_init();
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000133
134 /* Halt if there was a built in self test failure */
135 report_bist_failure(bist);
136
Myles Watson18d7c2e2009-10-27 14:05:21 +0000137 setup_default_resource_map();
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000138
139 needs_reset = setup_coherent_ht_domain();
Myles Watson18d7c2e2009-10-27 14:05:21 +0000140
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000141#if CONFIG_LOGICAL_CPUS==1
Myles Watson18d7c2e2009-10-27 14:05:21 +0000142 // It is said that we should start core1 after all core0 launched
143 start_other_cores();
144 wait_all_other_cores_started(bsp_apicid);
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000145#endif
Myles Watson18d7c2e2009-10-27 14:05:21 +0000146 /* This is needed to be able to call udelay(). It could be moved to
147 * memreset_setup, since udelay is called in memreset. */
148 init_timer();
149
150 // automatically set that for you, but you might meet tight space
151 needs_reset |= ht_setup_chains_x();
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000152
153 if (needs_reset) {
Myles Watson18d7c2e2009-10-27 14:05:21 +0000154 print_info("ht reset -\r\n");
155 soft_reset();
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000156 }
157
Myles Watson18d7c2e2009-10-27 14:05:21 +0000158 allow_all_aps_stop(bsp_apicid);
159
160 nodes = get_nodes();
161
162 fill_mem_ctrl(nodes, ctrl, spd_addr);
163
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000164 enable_smbus();
165
166 memreset_setup();
Myles Watson18d7c2e2009-10-27 14:05:21 +0000167
168 sdram_initialize(nodes, ctrl);
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000169
170 post_cache_as_ram();
Stefan Reinauerbc3f2f02007-11-02 11:06:40 +0000171}