blob: 0ed4ffdf853fdc881d0086dadd7f43edb18b319a [file] [log] [blame]
Marc Jones8ae8c882007-12-19 01:32:08 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones8ae8c882007-12-19 01:32:08 +00003 *
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 as published by
8 * the Free Software Foundation; version 2 of the License.
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.
Marc Jones8ae8c882007-12-19 01:32:08 +000014 */
15
16#include <stdint.h>
17#include <cpu/x86/lapic.h>
Stefan Reinauerbe7f7982009-03-13 15:42:27 +000018#include "amdfam10.h"
Marc Jones8ae8c882007-12-19 01:32:08 +000019
20#define NODE_ID 0x60
21#define HT_INIT_CONTROL 0x6c
22#define HTIC_ColdR_Detect (1<<4)
23#define HTIC_BIOSR_Detect (1<<5)
24#define HTIC_INIT_Detect (1<<6)
25
26/* mmconf is not ready */
27/* io_ext is not ready */
Stefan Reinauer6f57b512010-07-08 16:41:05 +000028u32 cpu_init_detected(u8 nodeid)
Marc Jones8ae8c882007-12-19 01:32:08 +000029{
30 u32 htic;
Edward O'Callaghan3ec9c952014-10-26 10:36:02 +110031 pci_devfn_t dev;
Marc Jones8ae8c882007-12-19 01:32:08 +000032
33 dev = NODE_PCI(nodeid, 0);
34 htic = pci_io_read_config32(dev, HT_INIT_CONTROL);
35
36 return !!(htic & HTIC_INIT_Detect);
37}
38
Stefan Reinauer6f57b512010-07-08 16:41:05 +000039u32 bios_reset_detected(void)
Marc Jones8ae8c882007-12-19 01:32:08 +000040{
41 u32 htic;
Stefan Reinauer08670622009-06-30 15:17:49 +000042 htic = pci_io_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0), HT_INIT_CONTROL);
Marc Jones8ae8c882007-12-19 01:32:08 +000043
44 return (htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect);
45}
46
Stefan Reinauer6f57b512010-07-08 16:41:05 +000047u32 cold_reset_detected(void)
Marc Jones8ae8c882007-12-19 01:32:08 +000048{
49 u32 htic;
Stefan Reinauer08670622009-06-30 15:17:49 +000050 htic = pci_io_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0), HT_INIT_CONTROL);
Marc Jones8ae8c882007-12-19 01:32:08 +000051
52 return !(htic & HTIC_ColdR_Detect);
53}
54
Stefan Reinauer6f57b512010-07-08 16:41:05 +000055u32 other_reset_detected(void) // other warm reset not started by BIOS
Marc Jones8ae8c882007-12-19 01:32:08 +000056{
57 u32 htic;
Stefan Reinauer08670622009-06-30 15:17:49 +000058 htic = pci_io_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0), HT_INIT_CONTROL);
Marc Jones8ae8c882007-12-19 01:32:08 +000059
60 return (htic & HTIC_ColdR_Detect) && (htic & HTIC_BIOSR_Detect);
61}
62
63static void distinguish_cpu_resets(u8 nodeid)
64{
65 u32 htic;
Edward O'Callaghan3ec9c952014-10-26 10:36:02 +110066 pci_devfn_t device;
Marc Jones8ae8c882007-12-19 01:32:08 +000067 device = NODE_PCI(nodeid, 0);
68 htic = pci_io_read_config32(device, HT_INIT_CONTROL);
69 htic |= HTIC_ColdR_Detect | HTIC_BIOSR_Detect | HTIC_INIT_Detect;
70 pci_io_write_config32(device, HT_INIT_CONTROL, htic);
71}
72
73static u32 warm_reset_detect(u8 nodeid)
74{
75 u32 htic;
Edward O'Callaghan3ec9c952014-10-26 10:36:02 +110076 pci_devfn_t device;
Marc Jones8ae8c882007-12-19 01:32:08 +000077 device = NODE_PCI(nodeid, 0);
78 htic = pci_io_read_config32(device, HT_INIT_CONTROL);
79 return (htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect);
80}
81
Vladimir Serbinenkobf8722a2014-11-09 13:17:39 +010082void set_bios_reset(void);
83void set_bios_reset(void)
Marc Jones8ae8c882007-12-19 01:32:08 +000084{
85
86 u32 nodes;
87 u32 htic;
Edward O'Callaghan3ec9c952014-10-26 10:36:02 +110088 pci_devfn_t dev;
Marc Jones8ae8c882007-12-19 01:32:08 +000089 int i;
90
Stefan Reinauer08670622009-06-30 15:17:49 +000091 nodes = ((pci_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0), 0x60) >> 4) & 7) + 1;
Marc Jones8ae8c882007-12-19 01:32:08 +000092
93 for(i = 0; i < nodes; i++) {
94 dev = NODE_PCI(i,0);
95 htic = pci_read_config32(dev, HT_INIT_CONTROL);
96 htic &= ~HTIC_BIOSR_Detect;
97 pci_write_config32(dev, HT_INIT_CONTROL, htic);
98 }
99}
100
101
102/* Look up a which bus a given node/link combination is on.
103 * return 0 when we can't find the answer.
104 */
105static u8 node_link_to_bus(u8 node, u8 link) // node are 6 bit, and link three bit
106{
107 u32 reg;
108 u32 val;
109
110 // put node and link in correct bit
111 val = ((node & 0x0f)<<4) | ((node & 0x30)<< (12-4)) | ((link & 0x07)<<8) ;
112
113 for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
114 u32 config_map;
Stefan Reinauer08670622009-06-30 15:17:49 +0000115 config_map = pci_io_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 1), reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000116 if ((config_map & 3) != 3) {
117 continue;
118 }
119 if ((config_map & (((63 & 0x0f)<<4) | ((63 & 0x30)<< (12-4)) | ((7 & 0x07)<<8) )
120 ) == val )
121 {
122 return (config_map >> 16) & 0xff;
123 }
124 }
125
Marc Jones8ae8c882007-12-19 01:32:08 +0000126 return 0;
127}
128
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000129u32 get_sblk(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000130{
131 u32 reg;
Stefan Reinauer08670622009-06-30 15:17:49 +0000132 /* read PCI_DEV(CONFIG_CBB,CONFIG_CDB,0) 0x64 bit [8:9] to find out SbLink m */
133 reg = pci_io_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0), 0x64);
Marc Jones8ae8c882007-12-19 01:32:08 +0000134 return ((reg>>8) & 3) ;
135}
136
137
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000138u8 get_sbbusn(u8 sblk)
Marc Jones8ae8c882007-12-19 01:32:08 +0000139{
140 return node_link_to_bus(0, sblk);
141}