Chapter 3: cleared
This commit is contained in:
parent
cfd5194fbc
commit
0df1574eee
|
@ -457,7 +457,7 @@ note = "[Online; accessed 8-May-2024]"
|
|||
author = {Intel Corporation},
|
||||
title = {Intel Converged Security and Management Engine (CSME) Security White Paper},
|
||||
year = {2020},
|
||||
url = {https://www.intel.com/content/dam/www/public/us/en/security-advisory/documents/intel-csme-security-white-paper.pdf}
|
||||
url = {https://software.intel.com/content/dam/www/public/us/en/security-advisory/documents/intel-csme-security-white-paper.pdf}
|
||||
}
|
||||
|
||||
@article{heasman2007,
|
||||
|
@ -973,4 +973,140 @@ note = "[Online; accessed 17-August-2024]"
|
|||
year = 2024,
|
||||
url = {https://doc.coreboot.org/memory-map.html},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
}
|
||||
|
||||
@article{medeiros2017,
|
||||
author = {Ivison Medeiros and
|
||||
Jonathan de Oliveira Dutra and
|
||||
Anderson Faustino da Silva and
|
||||
Rafael Silva Bigonha and
|
||||
Nicolas Anquetil and
|
||||
St{\'{e}}phane Ducasse},
|
||||
title = {Towards a dynamic data distribution management framework based on Apache Spark},
|
||||
journal = {Journal of the Brazilian Computer Society},
|
||||
volume = {23},
|
||||
number = {1},
|
||||
pages = {1--15},
|
||||
year = {2017},
|
||||
url = {https://journal-bcs.springeropen.com/articles/10.1186/s13173-017-0066-7},
|
||||
doi = {10.1186/s13173-017-0066-7},
|
||||
}
|
||||
|
||||
@inproceedings{markuze2021,
|
||||
author = {Alex Markuze and
|
||||
Shay Vargaftik and
|
||||
Gil Kupfer and
|
||||
Boris Pismenny and
|
||||
Nadav Amit and
|
||||
Adam Morrison and
|
||||
Dan Tsafrir},
|
||||
title = {Understanding DMA Attacks in the Presence of an IOMMU},
|
||||
booktitle = {Proceedings of the Sixteenth European Conference on Computer Systems (EuroSys '21)},
|
||||
year = {2021},
|
||||
url = {https://research.vmware.com/publications/understanding-dma-attacks-in-the-presence-of-an-iommu},
|
||||
publisher = {ACM},
|
||||
}
|
||||
|
||||
@manual{tianocore_payload,
|
||||
title = {TianoCore as a Coreboot Payload},
|
||||
author = {{TianoCore Project}},
|
||||
year = 2024,
|
||||
url = {https://doc.coreboot.org/payloads/tianocore.html},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{osdev_gop,
|
||||
title = {Graphics Output Protocol (GOP)},
|
||||
author = {{OSDev Wiki}},
|
||||
year = 2024,
|
||||
url = {https://wiki.osdev.org/GOP},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{proprivacy_intel_me,
|
||||
title = {Intel Management Engine: The obscure chip that does a lot for your computer},
|
||||
author = {Paul Bischoff},
|
||||
year = 2020,
|
||||
url = {https://proprivacy.com/privacy-news/intel-management-engine},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{netgarage_intel_me,
|
||||
title = {Intel Management Engine},
|
||||
author = {io.netgarage},
|
||||
year = 2024,
|
||||
url = {https://io.netgarage.org/me/},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{kernel_mei_hdcp,
|
||||
title = {High-bandwidth Digital Content Protection (HDCP)},
|
||||
author = {Linux Kernel Organization},
|
||||
year = 2020,
|
||||
url = {https://www.kernel.org/doc/html//v5.8/driver-api/mei/hdcp.html},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{heise_amt_attack,
|
||||
title = {Intel-Fernwartung AMT bei Angriffen auf PCs genutzt},
|
||||
author = {Stefan Krempl},
|
||||
year = 2017,
|
||||
url = {https://www.heise.de/news/Intel-Fernwartung-AMT-bei-Angriffen-auf-PCs-genutzt-3739441.html},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{blackhat_me_hack,
|
||||
title = {How to Hack a Turned-Off Computer, or Running Unsigned Code in Intel Management Engine},
|
||||
author = {Mark Ermolov and Maxim Goryachy},
|
||||
year = 2017,
|
||||
url = {https://www.blackhat.com/eu-17/briefings/schedule/#how-to-hack-a-turned-off-computer-or-running-unsigned-code-in-intel-management-engine-8668},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{eff_intel_me,
|
||||
title = {Intel’s Management Engine is a Security Hazard, and Users Need a Way to Disable It},
|
||||
author = {Danny O’Brien},
|
||||
year = 2017,
|
||||
url = {https://www.eff.org/deeplinks/2017/05/intels-management-engine-security-hazard-and-users-need-way-disable-it},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{boingboing_intel_me,
|
||||
title = {Intel x86 processors ship with a secret backdoor},
|
||||
author = {Cory Doctorow},
|
||||
year = 2016,
|
||||
url = {https://boingboing.net/2016/06/15/intel-x86-processors-ship-with.html},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{phoronix_hdcp_2_2_i915,
|
||||
title = {HDCP 2.2 Coming To The Intel i915 Linux DRM Driver},
|
||||
author = {Michael Larabel},
|
||||
year = 2018,
|
||||
url = {https://www.phoronix.com/news/HDCP-2.2-For-i915-DRM},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{phoronix_hdcp_2_2_driver,
|
||||
title = {HDCP 2.2 Support Being Worked On For Intel Linux Graphics Driver},
|
||||
author = {Michael Larabel},
|
||||
year = 2017,
|
||||
url = {https://www.phoronix.com/news/HDCP-2.2-Intel-Linux-Driver},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@online{fsf_intel_me,
|
||||
title = {The Management Engine: An Attack on Computer Users' Freedom},
|
||||
author = {{Free Software Foundation}},
|
||||
year = 2016,
|
||||
url = {https://www.fsf.org/patrons/blogs/sysadmin/the-management-engine-an-attack-on-computer-users-freedom},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
||||
@manual{uefi_what_is_uefi,
|
||||
title = {What is UEFI?},
|
||||
author = {{UEFI Forum}},
|
||||
year = 2023,
|
||||
url = {https://uefi.org/sites/default/files/resources/What%20is%20UEFI-Aug31-2023-Final.pdf},
|
||||
note = {Accessed: 2024-08-17}
|
||||
}
|
||||
|
|
|
@ -427,6 +427,35 @@
|
|||
\range{pages}{9}
|
||||
\keyw{Hardware ; Microprogramming}
|
||||
\endentry
|
||||
\entry{proprivacy_intel_me}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=8f544ee2d07626a301eb14f2d8af6b0b}{%
|
||||
family={Bischoff},
|
||||
familyi={B\bibinitperiod},
|
||||
given={Paul},
|
||||
giveni={P\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{8f544ee2d07626a301eb14f2d8af6b0b}
|
||||
\strng{fullhash}{8f544ee2d07626a301eb14f2d8af6b0b}
|
||||
\strng{bibnamehash}{8f544ee2d07626a301eb14f2d8af6b0b}
|
||||
\strng{authorbibnamehash}{8f544ee2d07626a301eb14f2d8af6b0b}
|
||||
\strng{authornamehash}{8f544ee2d07626a301eb14f2d8af6b0b}
|
||||
\strng{authorfullhash}{8f544ee2d07626a301eb14f2d8af6b0b}
|
||||
\field{sortinit}{B}
|
||||
\field{sortinithash}{d7095fff47cda75ca2589920aae98399}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Intel Management Engine: The obscure chip that does a lot for your computer}
|
||||
\field{year}{2020}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://proprivacy.com/privacy-news/intel-management-engine
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://proprivacy.com/privacy-news/intel-management-engine
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{brown2003linuxbios}{inproceedings}{}
|
||||
\true{moreauthor}
|
||||
\true{morelabelname}
|
||||
|
@ -604,7 +633,6 @@
|
|||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Coreboot Memory Management and Payload Allocation}
|
||||
\field{year}{2024}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://doc.coreboot.org/memory-map.html
|
||||
\endverb
|
||||
|
@ -666,10 +694,10 @@
|
|||
\field{type}{techreport}
|
||||
\field{year}{2020}
|
||||
\verb{urlraw}
|
||||
\verb https://www.intel.com/content/dam/www/public/us/en/security-advisory/documents/intel-csme-security-white-paper.pdf
|
||||
\verb https://software.intel.com/content/dam/www/public/us/en/security-advisory/documents/intel-csme-security-white-paper.pdf
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.intel.com/content/dam/www/public/us/en/security-advisory/documents/intel-csme-security-white-paper.pdf
|
||||
\verb https://software.intel.com/content/dam/www/public/us/en/security-advisory/documents/intel-csme-security-white-paper.pdf
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{intel_smm}{report}{}
|
||||
|
@ -748,6 +776,35 @@
|
|||
\field{title}{UEFI Firmware}
|
||||
\field{year}{2019}
|
||||
\endentry
|
||||
\entry{boingboing_intel_me}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=f07392ff66b0c83a1520683a348eabe1}{%
|
||||
family={Doctorow},
|
||||
familyi={D\bibinitperiod},
|
||||
given={Cory},
|
||||
giveni={C\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{f07392ff66b0c83a1520683a348eabe1}
|
||||
\strng{fullhash}{f07392ff66b0c83a1520683a348eabe1}
|
||||
\strng{bibnamehash}{f07392ff66b0c83a1520683a348eabe1}
|
||||
\strng{authorbibnamehash}{f07392ff66b0c83a1520683a348eabe1}
|
||||
\strng{authornamehash}{f07392ff66b0c83a1520683a348eabe1}
|
||||
\strng{authorfullhash}{f07392ff66b0c83a1520683a348eabe1}
|
||||
\field{sortinit}{D}
|
||||
\field{sortinithash}{6f385f66841fb5e82009dc833c761848}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Intel x86 processors ship with a secret backdoor}
|
||||
\field{year}{2016}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://boingboing.net/2016/06/15/intel-x86-processors-ship-with.html
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://boingboing.net/2016/06/15/intel-x86-processors-ship-with.html
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{ast2050_memory}{article}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=d6cfb2b8c4b3f9440ec4642438129367}{%
|
||||
|
@ -987,6 +1044,7 @@
|
|||
\strng{authorbibnamehash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{authornamehash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{authorfullhash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\field{extraname}{1}
|
||||
\field{sortinit}{F}
|
||||
\field{sortinithash}{2638baaa20439f1b5a8f80c6c08a13b4}
|
||||
\field{labelnamesource}{author}
|
||||
|
@ -1001,6 +1059,34 @@
|
|||
\verb https://ryf.fsf.org/products/VikingsD16
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{fsf_intel_me}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=cb96118d65be9f05ad10bd5cfdaf0f6d}{%
|
||||
family={{Free Software Foundation}},
|
||||
familyi={F\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{fullhash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{bibnamehash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{authorbibnamehash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{authornamehash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\strng{authorfullhash}{cb96118d65be9f05ad10bd5cfdaf0f6d}
|
||||
\field{extraname}{2}
|
||||
\field{sortinit}{F}
|
||||
\field{sortinithash}{2638baaa20439f1b5a8f80c6c08a13b4}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{The Management Engine: An Attack on Computer Users' Freedom}
|
||||
\field{year}{2016}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://www.fsf.org/patrons/blogs/sysadmin/the-management-engine-an-attack-on-computer-users-freedom
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.fsf.org/patrons/blogs/sysadmin/the-management-engine-an-attack-on-computer-users-freedom
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{freiberger2000fire}{book}{}
|
||||
\name{author}{2}{}{%
|
||||
{{hash=d3ab7b5c9a381bafc1c1c3eb700a3667}{%
|
||||
|
@ -1274,6 +1360,33 @@
|
|||
\field{title}{Intel Management Engine (Intel ME)}
|
||||
\true{nocite}
|
||||
\endentry
|
||||
\entry{netgarage_intel_me}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=64eb2dd5b853ed2e3e6ede4df0c13b5a}{%
|
||||
family={io.netgarage},
|
||||
familyi={i\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{64eb2dd5b853ed2e3e6ede4df0c13b5a}
|
||||
\strng{fullhash}{64eb2dd5b853ed2e3e6ede4df0c13b5a}
|
||||
\strng{bibnamehash}{64eb2dd5b853ed2e3e6ede4df0c13b5a}
|
||||
\strng{authorbibnamehash}{64eb2dd5b853ed2e3e6ede4df0c13b5a}
|
||||
\strng{authornamehash}{64eb2dd5b853ed2e3e6ede4df0c13b5a}
|
||||
\strng{authorfullhash}{64eb2dd5b853ed2e3e6ede4df0c13b5a}
|
||||
\field{sortinit}{i}
|
||||
\field{sortinithash}{8d291c51ee89b6cd86bf5379f0b151d8}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Intel Management Engine}
|
||||
\field{year}{2024}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://io.netgarage.org/me/
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://io.netgarage.org/me/
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{openbmc_customization}{article}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=5a25bc91f524ca6dfc2ecf9f4a13903c}{%
|
||||
|
@ -1408,6 +1521,35 @@
|
|||
\field{title}{Beyond BIOS: Developing with the Unified Extensible Firmware Interface}
|
||||
\field{year}{2017}
|
||||
\endentry
|
||||
\entry{heise_amt_attack}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=b7a2e18f77259e34d5b676fd04412bb3}{%
|
||||
family={Krempl},
|
||||
familyi={K\bibinitperiod},
|
||||
given={Stefan},
|
||||
giveni={S\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{b7a2e18f77259e34d5b676fd04412bb3}
|
||||
\strng{fullhash}{b7a2e18f77259e34d5b676fd04412bb3}
|
||||
\strng{bibnamehash}{b7a2e18f77259e34d5b676fd04412bb3}
|
||||
\strng{authorbibnamehash}{b7a2e18f77259e34d5b676fd04412bb3}
|
||||
\strng{authornamehash}{b7a2e18f77259e34d5b676fd04412bb3}
|
||||
\strng{authorfullhash}{b7a2e18f77259e34d5b676fd04412bb3}
|
||||
\field{sortinit}{K}
|
||||
\field{sortinithash}{c02bf6bff1c488450c352b40f5d853ab}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Intel-Fernwartung AMT bei Angriffen auf PCs genutzt}
|
||||
\field{year}{2017}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://www.heise.de/news/Intel-Fernwartung-AMT-bei-Angriffen-auf-PCs-genutzt-3739441.html
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.heise.de/news/Intel-Fernwartung-AMT-bei-Angriffen-auf-PCs-genutzt-3739441.html
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{numa}{article}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=419af6f87214eb9f2bfa2a03a877cb04}{%
|
||||
|
@ -1436,6 +1578,66 @@
|
|||
\verb 10.1145/2508834.2513149
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{phoronix_hdcp_2_2_i915}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=b51b9464b5589cf5380e3b897d0a43b6}{%
|
||||
family={Larabel},
|
||||
familyi={L\bibinitperiod},
|
||||
given={Michael},
|
||||
giveni={M\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{fullhash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{bibnamehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{authorbibnamehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{authornamehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{authorfullhash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\field{extraname}{1}
|
||||
\field{sortinit}{L}
|
||||
\field{sortinithash}{7c47d417cecb1f4bd38d1825c427a61a}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{HDCP 2.2 Coming To The Intel i915 Linux DRM Driver}
|
||||
\field{year}{2018}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://www.phoronix.com/news/HDCP-2.2-For-i915-DRM
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.phoronix.com/news/HDCP-2.2-For-i915-DRM
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{phoronix_hdcp_2_2_driver}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=b51b9464b5589cf5380e3b897d0a43b6}{%
|
||||
family={Larabel},
|
||||
familyi={L\bibinitperiod},
|
||||
given={Michael},
|
||||
giveni={M\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{fullhash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{bibnamehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{authorbibnamehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{authornamehash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\strng{authorfullhash}{b51b9464b5589cf5380e3b897d0a43b6}
|
||||
\field{extraname}{2}
|
||||
\field{sortinit}{L}
|
||||
\field{sortinithash}{7c47d417cecb1f4bd38d1825c427a61a}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{HDCP 2.2 Support Being Worked On For Intel Linux Graphics Driver}
|
||||
\field{year}{2017}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://www.phoronix.com/news/HDCP-2.2-Intel-Linux-Driver
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.phoronix.com/news/HDCP-2.2-Intel-Linux-Driver
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{cyber_smm_hack}{report}{}
|
||||
\name{author}{4}{}{%
|
||||
{{hash=e0fdb42b953ef541418307b69787da0c}{%
|
||||
|
@ -1645,6 +1847,131 @@
|
|||
\verb https://www.gnu.org/software/gnuboot/web/status.html
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{markuze2021}{inproceedings}{}
|
||||
\name{author}{7}{}{%
|
||||
{{hash=bddf7b21e1c8949d4103f016bbdbf08f}{%
|
||||
family={Markuze},
|
||||
familyi={M\bibinitperiod},
|
||||
given={Alex},
|
||||
giveni={A\bibinitperiod}}}%
|
||||
{{hash=4d511e0a6f00c8ad5dab79333097c89a}{%
|
||||
family={Vargaftik},
|
||||
familyi={V\bibinitperiod},
|
||||
given={Shay},
|
||||
giveni={S\bibinitperiod}}}%
|
||||
{{hash=566b0f1f830072ac0d45f6ef80b04254}{%
|
||||
family={Kupfer},
|
||||
familyi={K\bibinitperiod},
|
||||
given={Gil},
|
||||
giveni={G\bibinitperiod}}}%
|
||||
{{hash=a287912a74a981d9138e6ab9f22c55c5}{%
|
||||
family={Pismenny},
|
||||
familyi={P\bibinitperiod},
|
||||
given={Boris},
|
||||
giveni={B\bibinitperiod}}}%
|
||||
{{hash=b37f5c4b4ff4d2c5c57d026a8a01e86a}{%
|
||||
family={Amit},
|
||||
familyi={A\bibinitperiod},
|
||||
given={Nadav},
|
||||
giveni={N\bibinitperiod}}}%
|
||||
{{hash=3959b4901b01ec379cdb6e26d406f37d}{%
|
||||
family={Morrison},
|
||||
familyi={M\bibinitperiod},
|
||||
given={Adam},
|
||||
giveni={A\bibinitperiod}}}%
|
||||
{{hash=d4e54c84413641d186ef3461d7e0d1f7}{%
|
||||
family={Tsafrir},
|
||||
familyi={T\bibinitperiod},
|
||||
given={Dan},
|
||||
giveni={D\bibinitperiod}}}%
|
||||
}
|
||||
\list{publisher}{1}{%
|
||||
{ACM}%
|
||||
}
|
||||
\strng{namehash}{7df12f9031d9ee32c2b44bcc39f18d9d}
|
||||
\strng{fullhash}{ec0a172ad1c93eebd683b01a914d1db6}
|
||||
\strng{bibnamehash}{7df12f9031d9ee32c2b44bcc39f18d9d}
|
||||
\strng{authorbibnamehash}{7df12f9031d9ee32c2b44bcc39f18d9d}
|
||||
\strng{authornamehash}{7df12f9031d9ee32c2b44bcc39f18d9d}
|
||||
\strng{authorfullhash}{ec0a172ad1c93eebd683b01a914d1db6}
|
||||
\field{sortinit}{M}
|
||||
\field{sortinithash}{4625c616857f13d17ce56f7d4f97d451}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{booktitle}{Proceedings of the Sixteenth European Conference on Computer Systems (EuroSys '21)}
|
||||
\field{title}{Understanding DMA Attacks in the Presence of an IOMMU}
|
||||
\field{year}{2021}
|
||||
\verb{urlraw}
|
||||
\verb https://research.vmware.com/publications/understanding-dma-attacks-in-the-presence-of-an-iommu
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://research.vmware.com/publications/understanding-dma-attacks-in-the-presence-of-an-iommu
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{medeiros2017}{article}{}
|
||||
\name{author}{6}{}{%
|
||||
{{hash=cd5b56523e512e29ac9cad15b1818b81}{%
|
||||
family={Medeiros},
|
||||
familyi={M\bibinitperiod},
|
||||
given={Ivison},
|
||||
giveni={I\bibinitperiod}}}%
|
||||
{{hash=81aac05bbc300ff1dbbe6a7ddbe4f9f9}{%
|
||||
family={Oliveira\bibnamedelima Dutra},
|
||||
familyi={O\bibinitperiod\bibinitdelim D\bibinitperiod},
|
||||
given={Jonathan},
|
||||
giveni={J\bibinitperiod},
|
||||
prefix={de},
|
||||
prefixi={d\bibinitperiod}}}%
|
||||
{{hash=2413e19308f20bc8fa40f233758c88c0}{%
|
||||
family={Silva},
|
||||
familyi={S\bibinitperiod},
|
||||
given={Anderson\bibnamedelima Faustino},
|
||||
giveni={A\bibinitperiod\bibinitdelim F\bibinitperiod},
|
||||
prefix={da},
|
||||
prefixi={d\bibinitperiod}}}%
|
||||
{{hash=5f41c346d6f1b5bae7683d20592f3fc9}{%
|
||||
family={Bigonha},
|
||||
familyi={B\bibinitperiod},
|
||||
given={Rafael\bibnamedelima Silva},
|
||||
giveni={R\bibinitperiod\bibinitdelim S\bibinitperiod}}}%
|
||||
{{hash=df7428155f9dd9261cff7e2e0db2fb72}{%
|
||||
family={Anquetil},
|
||||
familyi={A\bibinitperiod},
|
||||
given={Nicolas},
|
||||
giveni={N\bibinitperiod}}}%
|
||||
{{hash=75e1e4e2c87fe37bb8edbe9563815011}{%
|
||||
family={Ducasse},
|
||||
familyi={D\bibinitperiod},
|
||||
given={Stéphane},
|
||||
giveni={S\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{7fc239c45cb70d84978e99f949cde22a}
|
||||
\strng{fullhash}{9df4f50abd9fd1266efe374274366054}
|
||||
\strng{bibnamehash}{7fc239c45cb70d84978e99f949cde22a}
|
||||
\strng{authorbibnamehash}{7fc239c45cb70d84978e99f949cde22a}
|
||||
\strng{authornamehash}{7fc239c45cb70d84978e99f949cde22a}
|
||||
\strng{authorfullhash}{9df4f50abd9fd1266efe374274366054}
|
||||
\field{sortinit}{M}
|
||||
\field{sortinithash}{4625c616857f13d17ce56f7d4f97d451}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{journaltitle}{Journal of the Brazilian Computer Society}
|
||||
\field{number}{1}
|
||||
\field{title}{Towards a dynamic data distribution management framework based on Apache Spark}
|
||||
\field{volume}{23}
|
||||
\field{year}{2017}
|
||||
\field{pages}{1\bibrangedash 15}
|
||||
\range{pages}{15}
|
||||
\verb{doi}
|
||||
\verb 10.1186/s13173-017-0066-7
|
||||
\endverb
|
||||
\verb{urlraw}
|
||||
\verb https://journal-bcs.springeropen.com/articles/10.1186/s13173-017-0066-7
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://journal-bcs.springeropen.com/articles/10.1186/s13173-017-0066-7
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{coreboot_challenges}{article}{}
|
||||
\name{author}{2}{}{%
|
||||
{{hash=af33676c3a4888dfa26a657f486708df}{%
|
||||
|
@ -1790,6 +2117,35 @@
|
|||
\verb https://www.nuvoton.com/
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{eff_intel_me}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=4ffff1c6c9a41ed000b5647ade54accb}{%
|
||||
family={O’Brien},
|
||||
familyi={O\bibinitperiod},
|
||||
given={Danny},
|
||||
giveni={D\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{4ffff1c6c9a41ed000b5647ade54accb}
|
||||
\strng{fullhash}{4ffff1c6c9a41ed000b5647ade54accb}
|
||||
\strng{bibnamehash}{4ffff1c6c9a41ed000b5647ade54accb}
|
||||
\strng{authorbibnamehash}{4ffff1c6c9a41ed000b5647ade54accb}
|
||||
\strng{authornamehash}{4ffff1c6c9a41ed000b5647ade54accb}
|
||||
\strng{authorfullhash}{4ffff1c6c9a41ed000b5647ade54accb}
|
||||
\field{sortinit}{O}
|
||||
\field{sortinithash}{2cd7140a07aea5341f9e2771efe90aae}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Intel’s Management Engine is a Security Hazard, and Users Need a Way to Disable It}
|
||||
\field{year}{2017}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://www.eff.org/deeplinks/2017/05/intels-management-engine-security-hazard-and-users-need-way-disable-it
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.eff.org/deeplinks/2017/05/intels-management-engine-security-hazard-and-users-need-way-disable-it
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{AlexanderOgolyuk2017UBaI}{article}{}
|
||||
\name{author}{3}{}{%
|
||||
{{hash=e471e22ecc8ac7b4a9a0aeef1178d250}{%
|
||||
|
@ -1834,6 +2190,62 @@
|
|||
\field{pages}{657\bibrangedash 662}
|
||||
\range{pages}{6}
|
||||
\endentry
|
||||
\entry{kernel_mei_hdcp}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=7801bf0ed827facf06b73af7e7edb095}{%
|
||||
family={Organization},
|
||||
familyi={O\bibinitperiod},
|
||||
given={Linux\bibnamedelima Kernel},
|
||||
giveni={L\bibinitperiod\bibinitdelim K\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{7801bf0ed827facf06b73af7e7edb095}
|
||||
\strng{fullhash}{7801bf0ed827facf06b73af7e7edb095}
|
||||
\strng{bibnamehash}{7801bf0ed827facf06b73af7e7edb095}
|
||||
\strng{authorbibnamehash}{7801bf0ed827facf06b73af7e7edb095}
|
||||
\strng{authornamehash}{7801bf0ed827facf06b73af7e7edb095}
|
||||
\strng{authorfullhash}{7801bf0ed827facf06b73af7e7edb095}
|
||||
\field{sortinit}{O}
|
||||
\field{sortinithash}{2cd7140a07aea5341f9e2771efe90aae}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{High-bandwidth Digital Content Protection (HDCP)}
|
||||
\field{year}{2020}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://www.kernel.org/doc/html//v5.8/driver-api/mei/hdcp.html
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://www.kernel.org/doc/html//v5.8/driver-api/mei/hdcp.html
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{osdev_gop}{online}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=2bd2931fac872535642e43e290f7d25b}{%
|
||||
family={{OSDev Wiki}},
|
||||
familyi={O\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{2bd2931fac872535642e43e290f7d25b}
|
||||
\strng{fullhash}{2bd2931fac872535642e43e290f7d25b}
|
||||
\strng{bibnamehash}{2bd2931fac872535642e43e290f7d25b}
|
||||
\strng{authorbibnamehash}{2bd2931fac872535642e43e290f7d25b}
|
||||
\strng{authornamehash}{2bd2931fac872535642e43e290f7d25b}
|
||||
\strng{authorfullhash}{2bd2931fac872535642e43e290f7d25b}
|
||||
\field{sortinit}{O}
|
||||
\field{sortinithash}{2cd7140a07aea5341f9e2771efe90aae}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{Graphics Output Protocol (GOP)}
|
||||
\field{year}{2024}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://wiki.osdev.org/GOP
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://wiki.osdev.org/GOP
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{pearson2014}{inproceedings}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=0cb7f02abd4eddb75a923fdbd4722b97}{%
|
||||
|
@ -2406,6 +2818,60 @@
|
|||
\verb https://www.aspeedtech.com/products.php?fPath=20&rId=29
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{tianocore_payload}{manual}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=632f06b41d4b1b901fc37d1cf32e810f}{%
|
||||
family={{TianoCore Project}},
|
||||
familyi={T\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{632f06b41d4b1b901fc37d1cf32e810f}
|
||||
\strng{fullhash}{632f06b41d4b1b901fc37d1cf32e810f}
|
||||
\strng{bibnamehash}{632f06b41d4b1b901fc37d1cf32e810f}
|
||||
\strng{authorbibnamehash}{632f06b41d4b1b901fc37d1cf32e810f}
|
||||
\strng{authornamehash}{632f06b41d4b1b901fc37d1cf32e810f}
|
||||
\strng{authorfullhash}{632f06b41d4b1b901fc37d1cf32e810f}
|
||||
\field{sortinit}{T}
|
||||
\field{sortinithash}{9af77f0292593c26bde9a56e688eaee9}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{TianoCore as a Coreboot Payload}
|
||||
\field{year}{2024}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://doc.coreboot.org/payloads/tianocore.html
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://doc.coreboot.org/payloads/tianocore.html
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{uefi_what_is_uefi}{manual}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=018a60b8cb2aa8763314c4672515eee5}{%
|
||||
family={{UEFI Forum}},
|
||||
familyi={U\bibinitperiod}}}%
|
||||
}
|
||||
\strng{namehash}{018a60b8cb2aa8763314c4672515eee5}
|
||||
\strng{fullhash}{018a60b8cb2aa8763314c4672515eee5}
|
||||
\strng{bibnamehash}{018a60b8cb2aa8763314c4672515eee5}
|
||||
\strng{authorbibnamehash}{018a60b8cb2aa8763314c4672515eee5}
|
||||
\strng{authornamehash}{018a60b8cb2aa8763314c4672515eee5}
|
||||
\strng{authorfullhash}{018a60b8cb2aa8763314c4672515eee5}
|
||||
\field{sortinit}{U}
|
||||
\field{sortinithash}{6901a00e45705986ee5e7ca9fd39adca}
|
||||
\field{labelnamesource}{author}
|
||||
\field{labeltitlesource}{title}
|
||||
\field{note}{Accessed: 2024-08-17}
|
||||
\field{title}{What is UEFI?}
|
||||
\field{year}{2023}
|
||||
\true{nocite}
|
||||
\verb{urlraw}
|
||||
\verb https://uefi.org/sites/default/files/resources/What%20is%20UEFI-Aug31-2023-Final.pdf
|
||||
\endverb
|
||||
\verb{url}
|
||||
\verb https://uefi.org/sites/default/files/resources/What%20is%20UEFI-Aug31-2023-Final.pdf
|
||||
\endverb
|
||||
\endentry
|
||||
\entry{lip6_annuaire}{misc}{}
|
||||
\name{author}{1}{}{%
|
||||
{{hash=a220fc1da6562fa2e1e0bc05c201b485}{%
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -13,28 +13,32 @@
|
|||
\contentsline {section}{\numberline {2.2}Chipset}{13}{section.2.2}%
|
||||
\contentsline {section}{\numberline {2.3}Processors}{15}{section.2.3}%
|
||||
\contentsline {section}{\numberline {2.4}Baseboard Management Controller}{16}{section.2.4}%
|
||||
\contentsline {chapter}{\numberline {3}Key components in modern firmware [WIP]}{18}{chapter.3}%
|
||||
\contentsline {chapter}{\numberline {3}Key components in modern firmware}{18}{chapter.3}%
|
||||
\contentsline {section}{\numberline {3.1}General structure of coreboot}{18}{section.3.1}%
|
||||
\contentsline {subsection}{\numberline {3.1.1}Bootblock stage}{19}{subsection.3.1.1}%
|
||||
\contentsline {subsection}{\numberline {3.1.2}Romstage}{20}{subsection.3.1.2}%
|
||||
\contentsline {subsection}{\numberline {3.1.3}Ramstage}{20}{subsection.3.1.3}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.3.1}Advanced Configuration and Power Interface}{20}{subsubsection.3.1.3.1}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.3.2}System Management Mode}{21}{subsubsection.3.1.3.2}%
|
||||
\contentsline {subsection}{\numberline {3.1.4}Payload}{22}{subsection.3.1.4}%
|
||||
\contentsline {section}{\numberline {3.2}AMD Platform Security Processor and Intel Management Engine}{22}{section.3.2}%
|
||||
\contentsline {chapter}{\numberline {4}Memory initialization and training algorithms [WIP]}{23}{chapter.4}%
|
||||
\contentsline {section}{\numberline {4.1}Importance of memory initialization}{23}{section.4.1}%
|
||||
\contentsline {section}{\numberline {4.2}Memory training algorithms}{23}{section.4.2}%
|
||||
\contentsline {section}{\numberline {4.3}Practical examples}{24}{section.4.3}%
|
||||
\contentsline {chapter}{\numberline {5}Firmware and hardware virtualization [WIP]}{25}{chapter.5}%
|
||||
\contentsline {section}{\numberline {5.1}Introduction to hardware virtualization}{25}{section.5.1}%
|
||||
\contentsline {section}{\numberline {5.2}Role of BIOS/UEFI in virtualization}{25}{section.5.2}%
|
||||
\contentsline {section}{\numberline {5.3}Security and freedom considerations}{25}{section.5.3}%
|
||||
\contentsline {section}{\numberline {5.4}Future trends in firmware and virtualization}{25}{section.5.4}%
|
||||
\contentsline {chapter}{Conclusion}{26}{chapter*.2}%
|
||||
\contentsline {section}{\numberline {5.5}Summary of key points}{26}{section.5.5}%
|
||||
\contentsline {section}{\numberline {5.6}Call for action}{26}{section.5.6}%
|
||||
\contentsline {chapter}{Bibliography}{27}{section.5.6}%
|
||||
\contentsline {chapter}{List of Figures}{32}{chapter*.3}%
|
||||
\contentsline {chapter}{List of Listings}{33}{chapter*.3}%
|
||||
\contentsline {chapter}{GNU Free Documentation License}{34}{chapter*.5}%
|
||||
\contentsline {subsection}{\numberline {3.1.2}Romstage}{21}{subsection.3.1.2}%
|
||||
\contentsline {subsection}{\numberline {3.1.3}Ramstage}{22}{subsection.3.1.3}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.3.1}Advanced Configuration and Power Interface}{22}{subsubsection.3.1.3.1}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.3.2}System Management Mode}{23}{subsubsection.3.1.3.2}%
|
||||
\contentsline {subsection}{\numberline {3.1.4}Payload}{23}{subsection.3.1.4}%
|
||||
\contentsline {section}{\numberline {3.2}AMD Platform Security Processor and Intel Management Engine}{24}{section.3.2}%
|
||||
\contentsline {chapter}{\numberline {4}Memory initialization and training algorithms [WIP]}{26}{chapter.4}%
|
||||
\contentsline {section}{\numberline {4.1}Importance of memory initialization}{26}{section.4.1}%
|
||||
\contentsline {section}{\numberline {4.2}Memory training algorithms}{26}{section.4.2}%
|
||||
\contentsline {section}{\numberline {4.3}Practical examples}{27}{section.4.3}%
|
||||
\contentsline {subsection}{\numberline {4.3.1}RAM Initialization Preparation}{27}{subsection.4.3.1}%
|
||||
\contentsline {subsection}{\numberline {4.3.2}RAM Initialization}{27}{subsection.4.3.2}%
|
||||
\contentsline {subsubsection}{\numberline {4.3.2.1}Memory Controller Initialization}{27}{subsubsection.4.3.2.1}%
|
||||
\contentsline {subsubsection}{\numberline {4.3.2.2}Memory Module Training}{28}{subsubsection.4.3.2.2}%
|
||||
\contentsline {chapter}{\numberline {5}Firmware and hardware virtualization [WIP]}{29}{chapter.5}%
|
||||
\contentsline {section}{\numberline {5.1}Introduction to hardware virtualization}{29}{section.5.1}%
|
||||
\contentsline {section}{\numberline {5.2}Role of BIOS/UEFI in virtualization}{29}{section.5.2}%
|
||||
\contentsline {section}{\numberline {5.3}Security and freedom considerations}{29}{section.5.3}%
|
||||
\contentsline {section}{\numberline {5.4}Future trends in firmware and virtualization}{29}{section.5.4}%
|
||||
\contentsline {chapter}{Conclusion}{30}{chapter*.2}%
|
||||
\contentsline {section}{\numberline {5.5}Summary of key points}{30}{section.5.5}%
|
||||
\contentsline {section}{\numberline {5.6}Call for action}{30}{section.5.6}%
|
||||
\contentsline {chapter}{Bibliography}{31}{section.5.6}%
|
||||
\contentsline {chapter}{List of Figures}{37}{chapter*.3}%
|
||||
\contentsline {chapter}{List of Listings}{38}{chapter*.3}%
|
||||
\contentsline {chapter}{GNU Free Documentation License}{39}{chapter*.5}%
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* This file assembles the start of the romstage program by the order of the
|
||||
* includes. Thus, it's extremely important that one pays very careful
|
||||
* attention to the order of the includes. */
|
||||
|
||||
#include <arch/x86/prologue.inc>
|
||||
#include <cpu/x86/32bit/entry32.inc>
|
||||
#include <cpu/x86/fpu_enable.inc>
|
||||
#if CONFIG(SSE)
|
||||
#include <cpu/x86/sse_enable.inc>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The assembly.inc is generated based on the requirements of the mainboard.
|
||||
* For example, for ROMCC boards the MAINBOARDDIR/romstage.c would be
|
||||
* processed by ROMCC and added. In non-ROMCC boards the chipsets'
|
||||
* cache-as-ram setup files would be here.
|
||||
*/
|
||||
#include <generated/assembly.inc>
|
|
@ -0,0 +1,50 @@
|
|||
#include <cpu/x86/cr.h>
|
||||
|
||||
/*
|
||||
* Include the old code for reset vector and protected mode entry. That code has
|
||||
* withstood the test of time.
|
||||
*/
|
||||
#include <arch/x86/prologue.inc>
|
||||
#include <cpu/x86/16bit/entry16.inc>
|
||||
#include <cpu/x86/16bit/reset16.inc>
|
||||
#include <cpu/x86/32bit/entry32.inc>
|
||||
|
||||
/* BIST result in eax */
|
||||
mov %eax, %ebx
|
||||
/* entry64.inc preserves ebx. */
|
||||
#include <cpu/x86/64bit/entry64.inc>
|
||||
mov %ebx, %eax
|
||||
|
||||
#if CONFIG(BOOTBLOCK_DEBUG_SPINLOOP)
|
||||
|
||||
/* Wait for a JTAG debugger to break in and set EBX non-zero */
|
||||
xor %ebx, %ebx
|
||||
|
||||
debug_spinloop:
|
||||
cmp $0, %ebx
|
||||
jz debug_spinloop
|
||||
#endif
|
||||
|
||||
bootblock_protected_mode_entry:
|
||||
|
||||
#if !CONFIG(USE_MARCH_586)
|
||||
/* MMX registers required here */
|
||||
|
||||
/* BIST result in eax */
|
||||
movd %eax, %mm0
|
||||
|
||||
/* Get an early timestamp */
|
||||
rdtsc
|
||||
movd %eax, %mm1
|
||||
movd %edx, %mm2
|
||||
#endif
|
||||
|
||||
#if CONFIG(SSE)
|
||||
enable_sse:
|
||||
mov %cr4, %eax
|
||||
or $CR4_OSFXSR, %ax
|
||||
mov %eax, %cr4
|
||||
#endif /* CONFIG(SSE) */
|
||||
|
||||
/* We're done. Now it's up to platform-specific code */
|
||||
jmp bootblock_pre_c_entry
|
|
@ -0,0 +1,637 @@
|
|||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/amd/msr.h>
|
||||
#include <cpu/amd/mtrr.h>
|
||||
|
||||
#define CacheSize CONFIG_DCACHE_RAM_SIZE
|
||||
#define CacheBase CONFIG_DCACHE_RAM_BASE
|
||||
#define CacheSizeBSPStack CONFIG_DCACHE_BSP_TOP_STACK_SIZE
|
||||
#define CacheSizeBSPSlush CONFIG_DCACHE_BSP_TOP_STACK_SLUSH
|
||||
|
||||
/* For CAR with Fam10h. */
|
||||
#define CacheSizeAPStack CONFIG_DCACHE_AP_STACK_SIZE
|
||||
|
||||
#define jmp_if_not_k8(x) comisd %xmm2, %xmm1; jae x
|
||||
#define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x
|
||||
#define jmp_if_not_fam15h(x) comisd %xmm3, %xmm1; jb x
|
||||
#define jmp_if_fam15h(x) comisd %xmm3, %xmm1; jae x
|
||||
|
||||
#define CPUID_MASK 0x0ff00f00
|
||||
#define CPUID_VAL_FAM10_ROTATED 0x0f000010
|
||||
#define CPUID_VAL_FAM15_ROTATED 0x0f000060
|
||||
|
||||
/*
|
||||
* XMM map:
|
||||
* xmm1: CPU family
|
||||
* xmm2: Fam10h comparison value
|
||||
* xmm3: Fam15h comparison value
|
||||
* xmm4: Backup EBX
|
||||
* xmm5: coreboot init detect
|
||||
*/
|
||||
|
||||
/* Save the BIST result. */
|
||||
movl %eax, %ebp
|
||||
|
||||
/*
|
||||
* For normal part %ebx already contain cpu_init_detected
|
||||
* from fallback call.
|
||||
*/
|
||||
|
||||
cache_as_ram_setup:
|
||||
post_code(0xa0)
|
||||
|
||||
/* Enable SSE. */
|
||||
movl %cr4, %eax
|
||||
orl $(3 << 9), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Figure out the CPU family. */
|
||||
cvtsi2sd %ebx, %xmm4
|
||||
movl $0x01, %eax
|
||||
cpuid
|
||||
/* Base family is bits 8..11, extended family is bits 20..27. */
|
||||
andl $CPUID_MASK, %eax
|
||||
/* Reorder bits for easier comparison by value. */
|
||||
roll $0x10, %eax
|
||||
cvtsi2sd %eax, %xmm1
|
||||
movl $CPUID_VAL_FAM10_ROTATED, %eax
|
||||
cvtsi2sd %eax, %xmm2
|
||||
movl $CPUID_VAL_FAM15_ROTATED, %eax
|
||||
cvtsi2sd %eax, %xmm3
|
||||
cvtsd2si %xmm4, %ebx
|
||||
|
||||
/* Check if cpu_init_detected. */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
andl $MTRR_DEF_TYPE_EN, %eax
|
||||
movl %eax, %ebx /* We store the status. */
|
||||
cvtsi2sd %ebx, %xmm5
|
||||
|
||||
jmp_if_k8(CAR_FAM10_out_post_errata)
|
||||
|
||||
/*
|
||||
* For GH, CAR need to set DRAM Base/Limit registers to direct that
|
||||
* to node0.
|
||||
* Only BSP needed, for other nodes set during HT/memory init.
|
||||
* So we need to check if it is BSP.
|
||||
*/
|
||||
movl $0x1b, %ecx
|
||||
rdmsr
|
||||
bt $8, %eax /* BSP */
|
||||
jnc CAR_FAM10_out
|
||||
|
||||
/* Enable RT tables on BSP. */
|
||||
movl $0x8000c06c, %eax
|
||||
movw $0xcf8, %dx
|
||||
outl %eax, %dx
|
||||
addw $4, %dx
|
||||
inl %dx, %eax
|
||||
btr $0, %eax
|
||||
outl %eax, %dx
|
||||
|
||||
/* Setup temporary DRAM map: [0,16M) bit 0-23. */
|
||||
movl $0x8000c144, %eax
|
||||
movw $0xcf8, %dx
|
||||
outl %eax, %dx
|
||||
addw $4, %dx
|
||||
movl $0, %eax
|
||||
outl %eax, %dx
|
||||
|
||||
movl $0x8000c140, %eax
|
||||
movw $0xcf8, %dx
|
||||
outl %eax, %dx
|
||||
addw $4, %dx
|
||||
movl $3, %eax
|
||||
outl %eax, %dx
|
||||
|
||||
CAR_FAM10_out:
|
||||
|
||||
jmp_if_fam15h(CAR_FAM10_errata_applied)
|
||||
/*
|
||||
* Errata 193: Disable clean copybacks to L3 cache to allow cached ROM.
|
||||
* Re-enable it in after RAM is initialized and before CAR is disabled.
|
||||
*/
|
||||
movl $BU_CFG2_MSR, %ecx
|
||||
rdmsr
|
||||
bts $15, %eax /* Set bit 15 in EDX:EAX (bit 15 in EAX). */
|
||||
wrmsr
|
||||
|
||||
/* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */
|
||||
movl $BU_CFG2_MSR, %ecx
|
||||
rdmsr
|
||||
bts $35-32, %edx /* Set bit 35 in EDX:EAX (bit 3 in EDX). */
|
||||
wrmsr
|
||||
|
||||
CAR_FAM10_errata_applied:
|
||||
|
||||
#if CONFIG(MMCONF_SUPPORT)
|
||||
#if (CONFIG_MMCONF_BASE_ADDRESS > 0xFFFFFFFF)
|
||||
#error "MMCONF_BASE_ADDRESS too big"
|
||||
#elif (CONFIG_MMCONF_BASE_ADDRESS & 0xFFFFF)
|
||||
#error "MMCONF_BASE_ADDRESS not 1MB aligned"
|
||||
#endif
|
||||
movl $0, %edx
|
||||
movl $((CONFIG_MMCONF_BASE_ADDRESS) | (1 << 0)), %eax
|
||||
#if (CONFIG_MMCONF_BUS_NUMBER == 1)
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 2)
|
||||
orl $(1 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 4)
|
||||
orl $(2 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 8)
|
||||
orl $(3 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 16)
|
||||
orl $(4 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 32)
|
||||
orl $(5 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 64)
|
||||
orl $(6 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 128)
|
||||
orl $(7 << 2), %eax
|
||||
#elif (CONFIG_MMCONF_BUS_NUMBER == 256)
|
||||
orl $(8 << 2), %eax
|
||||
#else
|
||||
#error "bad MMCONF_BUS_NUMBER value"
|
||||
#endif
|
||||
movl $MMIO_CONF_BASE, %ecx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
CAR_FAM10_out_post_errata:
|
||||
|
||||
/* Fam15h APIC IDs do not depend on NB config bit 54 */
|
||||
jmp_if_not_fam15h(skip_nb54_set)
|
||||
movl $NB_CFG_MSR, %ecx
|
||||
rdmsr
|
||||
bts $(54 - 32), %edx /* Set NB config bit 54 */
|
||||
wrmsr
|
||||
|
||||
skip_nb54_set:
|
||||
/* On Fam15h CPUs each compute unit's MTRRs are shared between two cores */
|
||||
jmp_if_not_fam15h(skip_cu_check)
|
||||
|
||||
/* Get the initial APIC ID. */
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
movl %ebx, %eax
|
||||
|
||||
/* Restore init detect */
|
||||
cvtsd2si %xmm5, %ebx
|
||||
|
||||
/* Determine if this is the second core to start in a compute unit; if so, wait for first core start, clear init detect and skip MTRR init */
|
||||
bt $24, %eax
|
||||
jnc skip_cu_check /* First core in the compute unit jumps to skip_cu_check */
|
||||
|
||||
/* Determine if this is the second core to start in a compute unit; if so, clear init detect and skip MTRR init */
|
||||
/* Busywait until the first core sets up the MTRRs */
|
||||
check_init_detect_1:
|
||||
/* Check if cpu_init_detected. */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
andl $MTRR_DEF_TYPE_EN, %eax
|
||||
cmp $0x00000000, %eax
|
||||
je check_init_detect_1 /* First core has not yet started */
|
||||
|
||||
check_init_detect_2:
|
||||
movl $SYSCFG_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn), %eax
|
||||
cmp $0x00000000, %eax
|
||||
je check_init_detect_2 /* First core has not yet started */
|
||||
|
||||
/* First core has now started */
|
||||
movl $0x00000000, %ebx /* Clear init detect flag */
|
||||
cvtsi2sd %ebx, %xmm5
|
||||
jmp fam10_mtrr_setup_complete
|
||||
|
||||
skip_cu_check:
|
||||
|
||||
jmp_if_not_fam15h(CAR_FAM15_errata_applied)
|
||||
|
||||
/* Erratum 714, RevGuide for Fam15h, Pub#48063 Rev. 3.24 */
|
||||
movl $BU_CFG2_MSR, %ecx
|
||||
rdmsr
|
||||
bts $8, %eax /* Set bit 8 in EDX:EAX (bit 8 in EAX). */
|
||||
wrmsr
|
||||
|
||||
CAR_FAM15_errata_applied:
|
||||
|
||||
/* Set MtrrFixDramModEn for clear fixed MTRR. */
|
||||
enable_fixed_mtrr_dram_modify:
|
||||
movl $SYSCFG_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax
|
||||
orl $SYSCFG_MSR_MtrrFixDramModEn, %eax
|
||||
wrmsr
|
||||
|
||||
/* Clear all MTRRs. */
|
||||
xorl %edx, %edx
|
||||
movl $all_mtrr_msrs, %esi
|
||||
|
||||
clear_fixed_var_mtrr:
|
||||
lodsl (%esi), %eax
|
||||
testl %eax, %eax
|
||||
jz clear_fixed_var_mtrr_out
|
||||
|
||||
movl %eax, %ecx
|
||||
xorl %eax, %eax
|
||||
wrmsr
|
||||
|
||||
jmp clear_fixed_var_mtrr
|
||||
clear_fixed_var_mtrr_out:
|
||||
|
||||
/*
|
||||
* 0x06 is the WB IO type for a given 4k segment.
|
||||
* 0x1e is the MEM IO type for a given 4k segment (K10 and above).
|
||||
* segs is the number of 4k segments in the area of the particular
|
||||
* register we want to use for CAR.
|
||||
* reg is the register where the IO type should be stored.
|
||||
*/
|
||||
.macro extractmask segs, reg
|
||||
.if \segs <= 0
|
||||
/*
|
||||
* The xorl here is superfluous because at the point of first execution
|
||||
* of this macro, %eax and %edx are cleared. Later invocations of this
|
||||
* macro will have a monotonically increasing segs parameter.
|
||||
*/
|
||||
xorl \reg, \reg
|
||||
.else
|
||||
jmp_if_k8(1f)
|
||||
|
||||
.if \segs == 1
|
||||
movl $0x1e000000, \reg /* WB MEM type */
|
||||
.elseif \segs == 2
|
||||
movl $0x1e1e0000, \reg /* WB MEM type */
|
||||
.elseif \segs == 3
|
||||
movl $0x1e1e1e00, \reg /* WB MEM type */
|
||||
.elseif \segs >= 4
|
||||
movl $0x1e1e1e1e, \reg /* WB MEM type */
|
||||
.endif
|
||||
jmp 2f
|
||||
1:
|
||||
.if \segs == 1
|
||||
movl $0x06000000, \reg /* WB IO type */
|
||||
.elseif \segs == 2
|
||||
movl $0x06060000, \reg /* WB IO type */
|
||||
.elseif \segs == 3
|
||||
movl $0x06060600, \reg /* WB IO type */
|
||||
.elseif \segs >= 4
|
||||
movl $0x06060606, \reg /* WB IO type */
|
||||
.endif
|
||||
2:
|
||||
.endif /* if \segs <= 0 */
|
||||
.endm
|
||||
|
||||
/*
|
||||
* carsize is the cache size in bytes we want to use for CAR.
|
||||
* windowoffset is the 32k-aligned window into CAR size.
|
||||
*/
|
||||
.macro simplemask carsize, windowoffset
|
||||
.set gas_bug_workaround,(((\carsize - \windowoffset) >> 12) - 4)
|
||||
extractmask gas_bug_workaround, %eax
|
||||
.set gas_bug_workaround,(((\carsize - \windowoffset) >> 12))
|
||||
extractmask gas_bug_workaround, %edx
|
||||
/*
|
||||
* Without the gas bug workaround, the entire macro would consist
|
||||
* only of the two lines below:
|
||||
* extractmask (((\carsize - \windowoffset) >> 12) - 4), %eax
|
||||
* extractmask (((\carsize - \windowoffset) >> 12)), %edx
|
||||
*/
|
||||
.endm
|
||||
|
||||
#if CONFIG(CPU_AMD_MODEL_10XXX)
|
||||
#if CacheSize > 0x80000
|
||||
#error Invalid CAR size, must be at most 128k (processor limit is 512k).
|
||||
#endif
|
||||
#else
|
||||
#if CacheSize > 0x10000
|
||||
#error Invalid CAR size, must be at most 64k.
|
||||
#endif
|
||||
#endif
|
||||
#if CacheSize < 0x1000
|
||||
#error Invalid CAR size, must be at least 4k. This is a processor limitation.
|
||||
#endif
|
||||
#if (CacheSize & (0x1000 - 1))
|
||||
#error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
|
||||
#endif
|
||||
|
||||
#if CacheSize > 0x8000
|
||||
/* Enable caching for 32K-64K using fixed MTRR. */
|
||||
movl $MTRR_FIX_4K_C0000, %ecx
|
||||
simplemask CacheSize, 0x8000
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
#if CacheSize > 0x10000
|
||||
/* Enable caching for 64K-96K using fixed MTRR. */
|
||||
movl $MTRR_FIX_4K_D0000, %ecx
|
||||
simplemask CacheSize, 0x10000
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
#if CacheSize > 0x18000
|
||||
/* Enable caching for 96K-128K using fixed MTRR. */
|
||||
movl $MTRR_FIX_4K_D8000, %ecx
|
||||
simplemask CacheSize, 0x18000
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
/* Enable caching for 0-32K using fixed MTRR. */
|
||||
movl $MTRR_FIX_4K_C8000, %ecx
|
||||
simplemask CacheSize, 0
|
||||
wrmsr
|
||||
|
||||
jmp_if_fam15h(fam15_skip_dram_mtrr_setup)
|
||||
|
||||
/* Enable memory access for first MBs using top_mem. */
|
||||
movl $TOP_MEM, %ecx
|
||||
xorl %edx, %edx
|
||||
movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
|
||||
wrmsr
|
||||
|
||||
fam15_skip_dram_mtrr_setup:
|
||||
|
||||
#if CONFIG_XIP_ROM_SIZE
|
||||
|
||||
/* Enable write base caching so we can do execute in place (XIP)
|
||||
* on the flash ROM.
|
||||
*/
|
||||
movl $MTRR_PHYS_BASE(1), %ecx
|
||||
xorl %edx, %edx
|
||||
/*
|
||||
* IMPORTANT: The following calculation _must_ be done at runtime. See
|
||||
* https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
|
||||
*/
|
||||
movl $_program, %eax
|
||||
andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
|
||||
orl $MTRR_TYPE_WRBACK, %eax
|
||||
wrmsr
|
||||
|
||||
movl $MTRR_PHYS_MASK(1), %ecx
|
||||
movl $0xff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for K8 (CONFIG_CPU_ADDR_BITS = 40) */
|
||||
jmp_if_k8(wbcache_post_fam10_setup)
|
||||
movl $0xffff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for FAM10 (CONFIG_CPU_ADDR_BITS = 48) */
|
||||
wbcache_post_fam10_setup:
|
||||
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
|
||||
wrmsr
|
||||
#endif /* CONFIG_XIP_ROM_SIZE */
|
||||
|
||||
/* Set the default memory type and enable fixed and variable MTRRs. */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
xorl %edx, %edx
|
||||
movl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
|
||||
wrmsr
|
||||
|
||||
/* Enable the MTRRs and IORRs in SYSCFG. */
|
||||
movl $SYSCFG_MSR, %ecx
|
||||
rdmsr
|
||||
orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
|
||||
wrmsr
|
||||
|
||||
fam10_mtrr_setup_complete:
|
||||
post_code(0xa1)
|
||||
|
||||
/* Disable conversion of INVD to WBINVD (INVDWBINVD = 0) */
|
||||
mov $HWCR_MSR, %ecx
|
||||
rdmsr
|
||||
btr $4, %eax
|
||||
wrmsr
|
||||
|
||||
jmp_if_not_fam15h(fam15_car_msr_setup_complete)
|
||||
/* Disable streaming store (DisSS = 1) */
|
||||
mov $LS_CFG_MSR, %ecx
|
||||
rdmsr
|
||||
bts $28, %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable speculative ITLB reloads (DisSpecTlbRld = 1) */
|
||||
mov $IC_CFG_MSR, %ecx
|
||||
rdmsr
|
||||
bts $9, %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable speculative DTLB reloads (DisSpecTlbRld = 1) and set DisHwPf = 1 */
|
||||
mov $DC_CFG_MSR, %ecx
|
||||
rdmsr
|
||||
bts $4, %eax
|
||||
bts $13, %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable CR0 combining (CombineCr0Cd = 0) */
|
||||
mov $BU_CFG3_MSR, %ecx
|
||||
rdmsr
|
||||
btr $49-32, %edx
|
||||
wrmsr
|
||||
fam15_car_msr_setup_complete:
|
||||
|
||||
/* Enable cache. */
|
||||
movl %cr0, %eax
|
||||
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
jmp_if_not_k8(CAR_skip_k8_errata_part1)
|
||||
|
||||
/* Set DisFillP on BSP. */
|
||||
movl $0x8000c068, %eax
|
||||
movw $0xcf8, %dx
|
||||
outl %eax, %dx
|
||||
addw $4, %dx
|
||||
inl %dx, %eax
|
||||
bts $10, %eax
|
||||
outl %eax, %dx
|
||||
|
||||
CAR_skip_k8_errata_part1:
|
||||
|
||||
jmp_if_k8(fam10_end_part1)
|
||||
|
||||
/* So we need to check if it is BSP. */
|
||||
movl $0x1b, %ecx
|
||||
rdmsr
|
||||
bt $8, %eax /* BSP */
|
||||
jnc CAR_FAM10_ap
|
||||
fam10_end_part1:
|
||||
|
||||
post_code(0xa2)
|
||||
|
||||
/* Read the range with lodsl. */
|
||||
cld
|
||||
movl $CacheBase, %esi
|
||||
movl $(CacheSize >> 2), %ecx
|
||||
rep lodsl
|
||||
|
||||
/* Clear the range. */
|
||||
movl $CacheBase, %edi
|
||||
movl $(CacheSize >> 2), %ecx
|
||||
xorl %eax, %eax
|
||||
rep stosl
|
||||
|
||||
jmp_if_not_k8(CAR_skip_k8_errata_part2)
|
||||
|
||||
/* Clear DisFillP on BSP. */
|
||||
movl $0x8000c068, %eax
|
||||
movw $0xcf8, %dx
|
||||
outl %eax, %dx
|
||||
addw $4, %dx
|
||||
inl %dx, %eax
|
||||
btr $10, %eax
|
||||
outl %eax, %dx
|
||||
|
||||
CAR_skip_k8_errata_part2:
|
||||
|
||||
/* Set up the stack pointer. */
|
||||
movl $(CacheBase + CacheSize), %eax
|
||||
movl %eax, %esp
|
||||
|
||||
/* Poison the lower stack boundary */
|
||||
movl $((CacheBase + CacheSize) - CacheSizeBSPStack), %eax
|
||||
movl $0xdeadbeef, (%eax)
|
||||
|
||||
post_code(0xa3)
|
||||
|
||||
jmp CAR_FAM10_ap_out
|
||||
CAR_FAM10_ap:
|
||||
/*
|
||||
* Need to set stack pointer for AP.
|
||||
* It will be from:
|
||||
* CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))
|
||||
* - (NodeID << CoreIDbits + CoreID) * CacheSizeAPStack
|
||||
* The spacing between the BSP stack and the top of the AP
|
||||
* stacks is purposefully set larger (an extra CacheSizeBSPSlush
|
||||
* worth of unused space) than necessary to aid debugging when
|
||||
* additional stack variables are added by future developers.
|
||||
* The extra space will allow BSP overruns to be caught by
|
||||
* the warning logic and easily fixed instead of crashing the
|
||||
* system with no obvious clues of what went wrong.
|
||||
*
|
||||
* So, need to get the NodeID and CoreID at first.
|
||||
* If NB_CFG_MSR bit 54 is set just use initial APIC ID, otherwise need
|
||||
* to reverse it.
|
||||
*/
|
||||
|
||||
/* Get the coreid bits at first. */
|
||||
movl $0x80000008, %eax
|
||||
cpuid
|
||||
shrl $12, %ecx
|
||||
andl $0x0f, %ecx
|
||||
movl %ecx, %edi
|
||||
|
||||
/* Get the initial APIC ID. */
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
shrl $24, %ebx
|
||||
|
||||
/* Get the nb cfg bit 54. */
|
||||
movl $NB_CFG_MSR, %ecx
|
||||
rdmsr
|
||||
movl %edi, %ecx /* CoreID bits */
|
||||
bt $(54 - 32), %edx
|
||||
jc roll_cfg
|
||||
|
||||
/* Fam10h NB config bit 54 was not set */
|
||||
rolb %cl, %bl
|
||||
roll_cfg:
|
||||
jmp_if_not_fam15h(ap_apicid_ready)
|
||||
cmp $0x5, %ecx
|
||||
jne ap_apicid_ready
|
||||
|
||||
/* This is a multi-node CPU
|
||||
* Adjust the maximum APIC ID to a more reasonable value
|
||||
* given that no 32-core Family 15h processors exist
|
||||
*/
|
||||
movl %ebx, %ecx
|
||||
and $0x0f, %ecx /* Get lower 4 bits of CPU number */
|
||||
and $0x60, %ebx /* Get node ID */
|
||||
shrl $0x1, %ebx /* Shift node ID part of APIC ID down by 1 */
|
||||
or %ecx, %ebx /* Recombine node ID and CPU number */
|
||||
|
||||
ap_apicid_ready:
|
||||
|
||||
/* Calculate stack pointer using adjusted APIC ID stored in ebx */
|
||||
movl $CacheSizeAPStack, %eax
|
||||
mull %ebx
|
||||
movl $(CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))), %esp
|
||||
subl %eax, %esp
|
||||
|
||||
/* Restore init detect */
|
||||
cvtsd2si %xmm5, %ebx
|
||||
|
||||
post_code(0xa4)
|
||||
|
||||
CAR_FAM10_ap_out:
|
||||
|
||||
post_code(0xa5)
|
||||
|
||||
/* Disable SSE. */
|
||||
movl %cr4, %eax
|
||||
andl $~(3 << 9), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
post_code(0xa6)
|
||||
|
||||
/* Restore the BIST result. */
|
||||
movl %ebp, %eax
|
||||
|
||||
/* We need to set EBP? No need. */
|
||||
movl %esp, %ebp
|
||||
pushl %ebx /* Init detected. */
|
||||
pushl %eax /* BIST */
|
||||
|
||||
post_code(0xa7)
|
||||
|
||||
call cache_as_ram_main
|
||||
|
||||
call post_cache_as_ram
|
||||
movl %eax, %esp
|
||||
|
||||
call cache_as_ram_new_stack
|
||||
|
||||
/* We will not go back. */
|
||||
|
||||
post_code(0xaf) /* Should never see this POST code. */
|
||||
|
||||
all_mtrr_msrs:
|
||||
/* fixed MTRR MSRs */
|
||||
.long MTRR_FIX_64K_00000
|
||||
.long MTRR_FIX_16K_80000
|
||||
.long MTRR_FIX_16K_A0000
|
||||
.long MTRR_FIX_4K_C0000
|
||||
.long MTRR_FIX_4K_C8000
|
||||
.long MTRR_FIX_4K_D0000
|
||||
.long MTRR_FIX_4K_D8000
|
||||
.long MTRR_FIX_4K_E0000
|
||||
.long MTRR_FIX_4K_E8000
|
||||
.long MTRR_FIX_4K_F0000
|
||||
.long MTRR_FIX_4K_F8000
|
||||
|
||||
/* var MTRR MSRs */
|
||||
.long MTRR_PHYS_BASE(0)
|
||||
.long MTRR_PHYS_MASK(0)
|
||||
.long MTRR_PHYS_BASE(1)
|
||||
.long MTRR_PHYS_MASK(1)
|
||||
.long MTRR_PHYS_BASE(2)
|
||||
.long MTRR_PHYS_MASK(2)
|
||||
.long MTRR_PHYS_BASE(3)
|
||||
.long MTRR_PHYS_MASK(3)
|
||||
.long MTRR_PHYS_BASE(4)
|
||||
.long MTRR_PHYS_MASK(4)
|
||||
.long MTRR_PHYS_BASE(5)
|
||||
.long MTRR_PHYS_MASK(5)
|
||||
.long MTRR_PHYS_BASE(6)
|
||||
.long MTRR_PHYS_MASK(6)
|
||||
.long MTRR_PHYS_BASE(7)
|
||||
.long MTRR_PHYS_MASK(7)
|
||||
|
||||
/* Variable IORR MTRR MSRs */
|
||||
.long IORRBase_MSR(0)
|
||||
.long IORRMask_MSR(0)
|
||||
.long IORRBase_MSR(1)
|
||||
.long IORRMask_MSR(1)
|
||||
|
||||
/* Top of memory MTRR MSRs */
|
||||
.long TOP_MEM
|
||||
.long TOP_MEM2
|
||||
|
||||
.long 0x000 /* NULL, end of table */
|
||||
|
||||
cache_as_ram_setup_out:
|
||||
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
.align 4096
|
||||
#endif
|
||||
.code16
|
||||
.globl _start16bit
|
||||
.type _start16bit, @function
|
||||
|
||||
_start16bit:
|
||||
cli
|
||||
/* Save the BIST result */
|
||||
movl %eax, %ebp
|
||||
#if !CONFIG(NO_EARLY_BOOTBLOCK_POSTCODES)
|
||||
post_code(POST_RESET_VECTOR_CORRECT)
|
||||
#endif
|
||||
|
||||
/* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
|
||||
* executing any further code. Even though paging is disabled we
|
||||
* could still get false address translations due to the TLB if we
|
||||
* didn't invalidate it. Thanks to kmliu@sis.com.tw for this TLB fix.
|
||||
*/
|
||||
|
||||
xorl %eax, %eax
|
||||
movl %eax, %cr3 /* Invalidate TLB*/
|
||||
|
||||
/* Invalidating the cache here seems to be a bad idea on
|
||||
* modern processors. Don't.
|
||||
* If we are hyperthreaded or we have multiple cores it is bad,
|
||||
* for SMP startup. On Opterons it causes a 5 second delay.
|
||||
* Invalidating the cache was pure paranoia in any event.
|
||||
* If your CPU needs it you can write a CPU dependent version of
|
||||
* entry16.inc.
|
||||
*/
|
||||
|
||||
/* Note: gas handles memory addresses in 16 bit code very poorly.
|
||||
* In particular it doesn't appear to have a directive allowing you
|
||||
* associate a section or even an absolute offset with a segment register.
|
||||
*
|
||||
* This means that anything except cs:ip relative offsets are
|
||||
* a real pain in 16 bit mode. And explains why it is almost
|
||||
* impossible to get gas to do lgdt correctly.
|
||||
*
|
||||
* One way to work around this is to have the linker do the
|
||||
* math instead of the assembler. This solves the very
|
||||
* pratical problem of being able to write code that can
|
||||
* be relocated.
|
||||
*
|
||||
* An lgdt call before we have memory enabled cannot be
|
||||
* position independent, as we cannot execute a call
|
||||
* instruction to get our current instruction pointer.
|
||||
* So while this code is relocateable it isn't arbitrarily
|
||||
* relocatable.
|
||||
*
|
||||
* The criteria for relocation have been relaxed to their
|
||||
* utmost, so that we can use the same code for both
|
||||
* our initial entry point and startup of the second CPU.
|
||||
* The code assumes when executing at _start16bit that:
|
||||
* (((cs & 0xfff) == 0) and (ip == _start16bit & 0xffff))
|
||||
* or
|
||||
* ((cs == anything) and (ip == 0)).
|
||||
*
|
||||
* The restrictions in reset16.inc mean that _start16bit initially
|
||||
* must be loaded at or above 0xffff0000 or below 0x100000.
|
||||
*
|
||||
* The linker scripts computes gdtptr16_offset by simply returning
|
||||
* the low 16 bits. This means that the initial segment used
|
||||
* when start is called must be 64K aligned. This should not
|
||||
* restrict the address as the ip address can be anything.
|
||||
*
|
||||
* Also load an IDT with NULL limit to prevent the 16bit IDT being used
|
||||
* in protected mode before c_start.S sets up a 32bit IDT when entering
|
||||
* RAM stage. In practise: CPU will shutdown on any exception.
|
||||
* See IA32 manual Vol 3A 19.26 Interrupts.
|
||||
*/
|
||||
|
||||
movw %cs, %ax
|
||||
shlw $4, %ax
|
||||
movw $nullidt_offset, %bx
|
||||
subw %ax, %bx
|
||||
lidt %cs:(%bx)
|
||||
movw $gdtptr16_offset, %bx
|
||||
subw %ax, %bx
|
||||
lgdtl %cs:(%bx)
|
||||
|
||||
movl %cr0, %eax
|
||||
andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
|
||||
orl $0x60000001, %eax /* CD, NW, PE = 1 */
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Restore BIST to %eax */
|
||||
movl %ebp, %eax
|
||||
|
||||
/* Now that we are in protected mode jump to a 32 bit code segment. */
|
||||
ljmpl $ROM_CODE_SEG, $__protected_start
|
||||
|
||||
/**
|
||||
* The gdt is defined in entry32.inc, it has a 4 Gb code segment
|
||||
* at 0x08, and a 4 GB data segment at 0x10;
|
||||
*/
|
||||
.align 4
|
||||
.globl gdtptr16
|
||||
gdtptr16:
|
||||
.word gdt_end - gdt -1 /* compute the table limit */
|
||||
.long gdt /* we know the offset */
|
||||
|
||||
.align 4
|
||||
.globl nullidt
|
||||
nullidt:
|
||||
.word 0 /* limit */
|
||||
.long 0
|
||||
.word 0
|
||||
|
||||
.globl _estart16bit
|
||||
_estart16bit:
|
||||
.code32
|
|
@ -0,0 +1,14 @@
|
|||
.section ".reset", "ax", %progbits
|
||||
.code16
|
||||
.globl _start
|
||||
_start:
|
||||
.byte 0xe9
|
||||
.int _start16bit - ( . + 2 )
|
||||
/* Note: The above jump is hand coded to work around bugs in binutils.
|
||||
* 5 byte are used for a 3 byte instruction. This works because x86
|
||||
* is little endian and allows us to use supported 32bit relocations
|
||||
* instead of the weird 16 bit relocations that binutils does not
|
||||
* handle consistently between versions because they are used so rarely.
|
||||
*/
|
||||
.previous
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#include <arch/rom_segs.h>
|
||||
#include <cpu/x86/post_code.h>
|
||||
#include <arch/x86/gdt_init.S>
|
||||
|
||||
.code32
|
||||
/*
|
||||
* When we come here we are in protected mode. We expand
|
||||
* the stack and copies the data segment from ROM to the
|
||||
* memory.
|
||||
*
|
||||
* After that, we call the chipset bootstrap routine that
|
||||
* does what is left of the chipset initialization.
|
||||
*
|
||||
* NOTE aligned to 4 so that we are sure that the prefetch
|
||||
* cache will be reloaded.
|
||||
*
|
||||
* In the bootblock there is already a ljmp to __protected_start and
|
||||
* the reset vector jumps to symbol _start16bit in entry16.inc from
|
||||
* the reset vectors's symbol which is _start. Therefore, don't
|
||||
* expose the _start symbol for bootblock.
|
||||
*/
|
||||
.align 4
|
||||
#if !ENV_BOOTBLOCK
|
||||
.globl _start
|
||||
_start:
|
||||
#endif
|
||||
|
||||
lgdt %cs:gdtptr
|
||||
ljmp $ROM_CODE_SEG, $__protected_start
|
||||
|
||||
__protected_start:
|
||||
/* Save the BIST value */
|
||||
movl %eax, %ebp
|
||||
|
||||
#if !CONFIG(NO_EARLY_BOOTBLOCK_POSTCODES)
|
||||
post_code(POST_ENTER_PROTECTED_MODE)
|
||||
#endif
|
||||
|
||||
movw $ROM_DATA_SEG, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
/* Restore the BIST value to %eax */
|
||||
movl %ebp, %eax
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* For starting coreboot in long mode.
|
||||
*
|
||||
* For reference see "AMD64 ArchitectureProgrammer's Manual Volume 2",
|
||||
* Document 24593-Rev. 3.31-July 2019 Chapter 5.3
|
||||
*
|
||||
* Clobbers: eax, ecx, edx
|
||||
*/
|
||||
|
||||
#if defined(__x86_64__)
|
||||
.code32
|
||||
#if (CONFIG_ARCH_X86_64_PGTBL_LOC & 0xfff) > 0
|
||||
#error pagetables must be 4KiB aligned!
|
||||
#endif
|
||||
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <arch/rom_segs.h>
|
||||
|
||||
setup_longmode:
|
||||
/* Get page table address */
|
||||
movl $(CONFIG_ARCH_X86_64_PGTBL_LOC), %eax
|
||||
|
||||
/* load identity mapped page tables */
|
||||
movl %eax, %cr3
|
||||
|
||||
/* enable PAE */
|
||||
movl %cr4, %eax
|
||||
btsl $5, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* enable long mode */
|
||||
movl $(IA32_EFER), %ecx
|
||||
rdmsr
|
||||
btsl $8, %eax
|
||||
wrmsr
|
||||
|
||||
/* enable paging */
|
||||
movl %cr0, %eax
|
||||
btsl $31, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* use long jump to switch to 64-bit code segment */
|
||||
ljmp $ROM_CODE_SEG64, $__longmode_start
|
||||
.code64
|
||||
__longmode_start:
|
||||
|
||||
#endif
|
|
@ -0,0 +1,91 @@
|
|||
#include <arch/exception.h>
|
||||
#include <bootblock_common.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <program_loading.h>
|
||||
#include <symbols.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
DECLARE_OPTIONAL_REGION(timestamp);
|
||||
|
||||
__weak void bootblock_mainboard_early_init(void) { /* no-op */ }
|
||||
__weak void bootblock_soc_early_init(void) { /* do nothing */ }
|
||||
__weak void bootblock_soc_init(void) { /* do nothing */ }
|
||||
__weak void bootblock_mainboard_init(void) { /* do nothing */ }
|
||||
|
||||
/*
|
||||
* This is a the same as the bootblock main(), with the difference that it does
|
||||
* not collect a timestamp. Instead it accepts the initial timestamp and
|
||||
* possibly additional timestamp entries as arguments. This can be used in cases
|
||||
* where earlier stamps are available. Note that this function is designed to be
|
||||
* entered from C code. This function assumes that the timer has already been
|
||||
* initialized, so it does not call init_timer().
|
||||
*/
|
||||
static void bootblock_main_with_timestamp(uint64_t base_timestamp,
|
||||
struct timestamp_entry *timestamps, size_t num_timestamps)
|
||||
{
|
||||
/* Initialize timestamps if we have TIMESTAMP region in memlayout.ld. */
|
||||
if (CONFIG(COLLECT_TIMESTAMPS) &&
|
||||
REGION_SIZE(timestamp) > 0) {
|
||||
int i;
|
||||
timestamp_init(base_timestamp);
|
||||
for (i = 0; i < num_timestamps; i++)
|
||||
timestamp_add(timestamps[i].entry_id,
|
||||
timestamps[i].entry_stamp);
|
||||
}
|
||||
|
||||
timestamp_add_now(TS_START_BOOTBLOCK);
|
||||
|
||||
bootblock_soc_early_init();
|
||||
bootblock_mainboard_early_init(); // ./src/lib/bootblock.c:__weak void bootblock_mainboard_early_init(void) { /* no-op */ }
|
||||
|
||||
sanitize_cmos();
|
||||
cmos_post_init();
|
||||
|
||||
if (CONFIG(BOOTBLOCK_CONSOLE)) {
|
||||
console_init();
|
||||
exception_init();
|
||||
}
|
||||
|
||||
bootblock_soc_init(); // __weak void bootblock_soc_init(void) { /* do nothing */ }
|
||||
bootblock_mainboard_init();
|
||||
|
||||
timestamp_add_now(TS_END_BOOTBLOCK);
|
||||
|
||||
run_romstage();
|
||||
}
|
||||
|
||||
void bootblock_main_with_basetime(uint64_t base_timestamp)
|
||||
{
|
||||
bootblock_main_with_timestamp(base_timestamp, NULL, 0);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
uint64_t base_timestamp = 0;
|
||||
|
||||
init_timer();
|
||||
|
||||
if (CONFIG(COLLECT_TIMESTAMPS))
|
||||
base_timestamp = timestamp_get();
|
||||
|
||||
bootblock_main_with_timestamp(base_timestamp, NULL, 0);
|
||||
}
|
||||
|
||||
#if CONFIG(COMPRESS_BOOTBLOCK)
|
||||
/*
|
||||
* This is the bootblock entry point when it is run after a decompressor stage.
|
||||
* For non-decompressor builds, _start is generally defined in architecture-
|
||||
* specific assembly code. In decompressor builds that architecture
|
||||
* initialization code already ran in the decompressor, so the bootblock can
|
||||
* start straight into common code with a C environment.
|
||||
*/
|
||||
void _start(struct bootblock_arg *arg);
|
||||
void _start(struct bootblock_arg *arg)
|
||||
{
|
||||
bootblock_main_with_timestamp(arg->base_timestamp, arg->timestamps,
|
||||
arg->num_timestamps);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
void run_romstage(void)
|
||||
{
|
||||
struct prog romstage =
|
||||
PROG_INIT(PROG_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage");
|
||||
|
||||
vboot_run_logic();
|
||||
|
||||
if (prog_locate(&romstage))
|
||||
goto fail;
|
||||
|
||||
timestamp_add_now(TS_START_COPYROM);
|
||||
|
||||
if (cbfs_prog_stage_load(&romstage))
|
||||
goto fail;
|
||||
|
||||
timestamp_add_now(TS_END_COPYROM);
|
||||
|
||||
console_time_report();
|
||||
|
||||
prog_run(&romstage);
|
||||
|
||||
fail:
|
||||
if (CONFIG(BOOTBLOCK_CONSOLE))
|
||||
die_with_post_code(POST_INVALID_ROM,
|
||||
"Couldn't load romstage.\n");
|
||||
halt();
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#include <device/pci_ops.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
|
||||
void bootblock_mainboard_init(void)
|
||||
{
|
||||
uint8_t recovery_enabled;
|
||||
unsigned char addr;
|
||||
unsigned char byte;
|
||||
|
||||
bootblock_northbridge_init();
|
||||
bootblock_southbridge_init();
|
||||
|
||||
/* Recovery jumper is connected to SP5100 GPIO61, and clears the GPIO when placed in the Recovery position */
|
||||
byte = pci_io_read_config8(PCI_DEV(0, 0x14, 0), 0x56);
|
||||
byte |= 0x1 << 4; /* Set GPIO61 to input mode */
|
||||
pci_io_write_config8(PCI_DEV(0, 0x14, 0), 0x56, byte);
|
||||
recovery_enabled = (!(pci_io_read_config8(PCI_DEV(0, 0x14, 0), 0x57) & 0x1));
|
||||
if (recovery_enabled) {
|
||||
#if CONFIG(USE_OPTION_TABLE)
|
||||
/* Clear NVRAM checksum */
|
||||
for (addr = LB_CKS_RANGE_START; addr <= LB_CKS_RANGE_END; addr++) {
|
||||
cmos_write(0x0, addr);
|
||||
}
|
||||
|
||||
/* Set fallback boot */
|
||||
byte = cmos_read(RTC_BOOT_BYTE);
|
||||
byte &= 0xfc;
|
||||
cmos_write(byte, RTC_BOOT_BYTE);
|
||||
#else
|
||||
/* FIXME
|
||||
* Figure out how to recover if the option table is not available
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
|
||||
{
|
||||
uint32_t esp;
|
||||
__asm__ volatile (
|
||||
"movl %%esp, %0"
|
||||
: "=r" (esp)
|
||||
);
|
||||
|
||||
struct sys_info *sysinfo = get_sysinfo();
|
||||
|
||||
/* Limit the maximum HT speed to 2.6GHz to prevent lockups
|
||||
* due to HT CPU <--> CPU wiring not being validated to 3.2GHz
|
||||
*/
|
||||
sysinfo->ht_link_cfg.ht_speed_limit = 2600;
|
||||
|
||||
uint32_t bsp_apicid = 0, val;
|
||||
uint8_t byte;
|
||||
uint8_t power_on_reset = 0;
|
||||
msr_t msr;
|
||||
|
||||
int s3resume = acpi_is_wakeup_s3();
|
||||
|
||||
if (!cpu_init_detectedx && boot_cpu()) {
|
||||
/* Initial timestamp */
|
||||
timestamp_init(timestamp_get());
|
||||
timestamp_add_now(TS_START_ROMSTAGE);
|
||||
|
||||
/* Initialize the printk, nvram CBFS, and microcode CBFS spinlocks */
|
||||
initialize_romstage_console_lock();
|
||||
initialize_romstage_nvram_cbfs_lock();
|
||||
initialize_romstage_microcode_cbfs_lock();
|
||||
|
||||
/* Nothing special needs to be done to find bus 0 */
|
||||
/* Allow the HT devices to be found */
|
||||
set_bsp_node_CHtExtNodeCfgEn();
|
||||
enumerate_ht_chain();
|
||||
|
||||
/* SR56x0 pcie bridges block pci_locate_device() before pcie training.
|
||||
* disable all pcie bridges on SR56x0 to work around it
|
||||
*/
|
||||
sr5650_disable_pcie_bridge();
|
||||
|
||||
/* Initialize southbridge */
|
||||
sb7xx_51xx_pci_port80();
|
||||
|
||||
/* Configure secondary serial port pin mux */
|
||||
winbond_set_pinmux(SERIAL_1_DEV, 0x2a, W83667HG_SPI_PINMUX_GPIO4_SERIAL_B_MASK, W83667HG_SPI_PINMUX_SERIAL_B);
|
||||
|
||||
/* Initialize early serial */
|
||||
winbond_enable_serial(SERIAL_0_DEV, CONFIG_TTYS0_BASE);
|
||||
console_init();
|
||||
|
||||
/* Disable LPC legacy DMA support to prevent lockup */
|
||||
byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0x78);
|
||||
byte &= ~(1 << 0);
|
||||
pci_write_config8(PCI_DEV(0, 0x14, 3), 0x78, byte);
|
||||
}
|
||||
|
||||
printk(BIOS_SPEW, "Initial stack pointer: %08x\n", esp);
|
||||
|
||||
post_code(0x30);
|
||||
|
||||
if (bist == 0)
|
||||
bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
|
||||
|
||||
post_code(0x32);
|
||||
|
||||
enable_sr5650_dev8();
|
||||
sb7xx_51xx_lpc_init();
|
||||
|
||||
if (CONFIG_MAX_PHYSICAL_CPUS != 4)
|
||||
printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD G34 board!\n", CONFIG_MAX_PHYSICAL_CPUS);
|
||||
|
||||
/* Halt if there was a built in self test failure */
|
||||
report_bist_failure(bist);
|
||||
|
||||
val = cpuid_eax(1);
|
||||
printk(BIOS_DEBUG, "BSP Family_Model: %08x\n", val);
|
||||
printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
|
||||
printk(BIOS_DEBUG, "bsp_apicid = %02x\n", bsp_apicid);
|
||||
printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx\n", cpu_init_detectedx);
|
||||
|
||||
/* Setup sysinfo defaults */
|
||||
set_sysinfo_in_ram(0);
|
||||
|
||||
if (!sb7xx_51xx_decode_last_reset())
|
||||
power_on_reset = 1;
|
||||
|
||||
initialize_mca(1, power_on_reset);
|
||||
update_microcode(val);
|
||||
|
||||
post_code(0x33);
|
||||
|
||||
cpuSetAMDMSR(0);
|
||||
post_code(0x34);
|
||||
|
||||
amd_ht_init(sysinfo);
|
||||
amd_ht_fixup(sysinfo);
|
||||
post_code(0x35);
|
||||
|
||||
/* Setup nodes PCI space and start core 0 AP init. */
|
||||
finalize_node_setup(sysinfo);
|
||||
|
||||
/* Setup any mainboard PCI settings etc. */
|
||||
setup_mb_resource_map();
|
||||
initialize_mca(0, power_on_reset);
|
||||
post_code(0x36);
|
||||
|
||||
/* Wait for all the APs core0 started by finalize_node_setup. */
|
||||
wait_all_core0_started();
|
||||
|
||||
/* run _early_setup before soft-reset. */
|
||||
sr5650_early_setup();
|
||||
sb7xx_51xx_early_setup();
|
||||
|
||||
if (CONFIG(LOGICAL_CPUS)) {
|
||||
/* Core0 on each node is configured. Now setup any additional cores. */
|
||||
printk(BIOS_DEBUG, "start_other_cores()\n");
|
||||
start_other_cores(bsp_apicid);
|
||||
post_code(0x37);
|
||||
wait_all_other_cores_started(bsp_apicid);
|
||||
}
|
||||
|
||||
if (CONFIG(SET_FIDVID)) {
|
||||
msr = rdmsr(MSR_COFVID_STS);
|
||||
printk(BIOS_DEBUG, "\nBegin FIDVID MSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo);
|
||||
|
||||
/* FIXME: The sb fid change may survive the warm reset and only need to be done once */
|
||||
enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
|
||||
|
||||
post_code(0x39);
|
||||
|
||||
#if CONFIG(SET_FIDVID)
|
||||
if (!warm_reset_detect(0)) { // BSP is node 0
|
||||
init_fidvid_bsp(bsp_apicid, sysinfo->nodes);
|
||||
} else {
|
||||
init_fidvid_stage2(bsp_apicid, 0); // BSP is node 0
|
||||
}
|
||||
#endif
|
||||
|
||||
post_code(0x3A);
|
||||
|
||||
/* show final fid and vid */
|
||||
msr = rdmsr(MSR_COFVID_STS);
|
||||
printk(BIOS_DEBUG, "End FIDVIDMSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo);
|
||||
}
|
||||
|
||||
post_code(0x38);
|
||||
|
||||
init_timer(); // Need to use TMICT to synconize FID/VID
|
||||
|
||||
sr5650_htinit();
|
||||
|
||||
/* Reset for HT, FIDVID, PLL and errata changes to take effect. */
|
||||
if (!warm_reset_detect(0)) {
|
||||
printk(BIOS_INFO, "...WARM RESET...\n\n\n");
|
||||
soft_reset();
|
||||
die("After soft_reset - shouldn't see this message!!!\n");
|
||||
}
|
||||
|
||||
sr5650_htinit_dect_and_enable_isochronous_link();
|
||||
|
||||
/* Set default DDR memory voltage
|
||||
* This will be overridden later during RAM initialization
|
||||
*/
|
||||
set_lpc_sticky_ctl(1); /* Retain LPC/IMC GPIO configuration during S3 sleep */
|
||||
if (!s3resume) { /* Avoid supply voltage glitches while the DIMMs are retaining data */
|
||||
set_ddr3_voltage(0, 0); /* Node 0 */
|
||||
set_ddr3_voltage(1, 0); /* Node 1 */
|
||||
}
|
||||
|
||||
/* Set up peripheral control lines */
|
||||
set_peripheral_control_lines();
|
||||
|
||||
post_code(0x3B);
|
||||
|
||||
/* Wait for all APs to be stopped, otherwise RAM initialization may hang */
|
||||
if (CONFIG(LOGICAL_CPUS))
|
||||
wait_all_other_cores_stopped(bsp_apicid);
|
||||
|
||||
/* It's the time to set ctrl in sysinfo now; */
|
||||
printk(BIOS_DEBUG, "fill_mem_ctrl() detected %d nodes\n", sysinfo->nodes);
|
||||
if (is_fam15h())
|
||||
fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam15);
|
||||
else
|
||||
fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam10);
|
||||
post_code(0x3D);
|
||||
|
||||
#if 0
|
||||
/* FIXME
|
||||
* After the AMD K10 code has been converted to use
|
||||
* CONFIG(DEBUG_SMBUS) uncomment this block
|
||||
*/
|
||||
if (CONFIG(DEBUG_SMBUS)) {
|
||||
dump_spd_registers(&cpu[0]);
|
||||
dump_smbus_registers();
|
||||
}
|
||||
#endif
|
||||
|
||||
post_code(0x40);
|
||||
|
||||
raminit_amdmct(sysinfo);
|
||||
|
||||
#ifdef TEST_MEMORY
|
||||
execute_memory_test();
|
||||
#endif
|
||||
|
||||
if (s3resume)
|
||||
cbmem_initialize();
|
||||
else
|
||||
cbmem_initialize_empty();
|
||||
|
||||
romstage_handoff_init(s3resume);
|
||||
|
||||
post_code(0x41);
|
||||
|
||||
amdmct_cbmem_store_info(sysinfo);
|
||||
|
||||
printk(BIOS_DEBUG, "disable_spd()\n");
|
||||
switch_spd_mux(0x1);
|
||||
|
||||
sr5650_before_pci_init();
|
||||
sb7xx_51xx_before_pci_init();
|
||||
|
||||
/* Configure SP5100 GPIOs to match vendor settings */
|
||||
pci_write_config16(PCI_DEV(0, 0x14, 0), 0x50, 0x0170);
|
||||
pci_write_config16(PCI_DEV(0, 0x14, 0), 0x54, 0x0707);
|
||||
pci_write_config16(PCI_DEV(0, 0x14, 0), 0x56, 0x0bb0);
|
||||
pci_write_config16(PCI_DEV(0, 0x14, 0), 0x5a, 0x0ff0);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include "northbridge/amd/amdfam10/early_ht.c"
|
||||
|
||||
static void bootblock_northbridge_init(void) {
|
||||
/* Nothing special needs to be done to find bus 0 */
|
||||
/* Allow the HT devices to be found */
|
||||
/* mov bsp to bus 0xff when > 8 nodes */
|
||||
set_bsp_node_CHtExtNodeCfgEn();
|
||||
enumerate_ht_chain();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
void raminit_amdmct(struct sys_info *sysinfo)
|
||||
{
|
||||
struct MCTStatStruc *pMCTstat = &(sysinfo->MCTstat);
|
||||
struct DCTStatStruc *pDCTstatA = sysinfo->DCTstatA;
|
||||
|
||||
printk(BIOS_DEBUG, "raminit_amdmct begin:\n");
|
||||
timestamp_add_now(TS_BEFORE_INITRAM);
|
||||
|
||||
mctAutoInitMCT_D(pMCTstat, pDCTstatA);
|
||||
|
||||
timestamp_add_now(TS_AFTER_INITRAM);
|
||||
printk(BIOS_DEBUG, "raminit_amdmct end:\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#include <device/pci_ops.h>
|
||||
#include <northbridge/amd/amdfam10/raminit.h>
|
||||
#include <northbridge/amd/amdfam10/amdfam10.h>
|
||||
#include <delay.h>
|
||||
|
||||
static void set_htic_bit(u8 i, u32 val, u8 bit)
|
||||
{
|
||||
u32 dword;
|
||||
dword = pci_read_config32(NODE_PCI(i, 0), HT_INIT_CONTROL);
|
||||
dword &= ~(1<<bit);
|
||||
dword |= ((val & 1) <<bit);
|
||||
pci_write_config32(NODE_PCI(i, 0), HT_INIT_CONTROL, dword);
|
||||
}
|
||||
|
||||
#ifdef UNUSED_CODE
|
||||
static u32 get_htic_bit(u8 i, u8 bit)
|
||||
{
|
||||
u32 dword;
|
||||
dword = pci_read_config32(NODE_PCI(i, 0), HT_INIT_CONTROL);
|
||||
dword &= (1<<bit);
|
||||
return dword;
|
||||
}
|
||||
|
||||
static void wait_till_sysinfo_in_ram(void)
|
||||
{
|
||||
while (1) {
|
||||
/* give the NB a break, many CPUs spinning on one bit makes a
|
||||
* lot of traffic and time is not too important to APs.
|
||||
*/
|
||||
udelay(1000);
|
||||
if (get_htic_bit(0, 9)) return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void fill_mem_ctrl(u32 controllers, struct mem_controller *ctrl_a, const u8 *spd_addr)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int index = 0;
|
||||
struct mem_controller *ctrl;
|
||||
for (i = 0; i < controllers; i++) {
|
||||
ctrl = &ctrl_a[i];
|
||||
ctrl->node_id = i;
|
||||
ctrl->f0 = NODE_PCI(i, 0);
|
||||
ctrl->f1 = NODE_PCI(i, 1);
|
||||
ctrl->f2 = NODE_PCI(i, 2);
|
||||
ctrl->f3 = NODE_PCI(i, 3);
|
||||
ctrl->f4 = NODE_PCI(i, 4);
|
||||
ctrl->f5 = NODE_PCI(i, 5);
|
||||
|
||||
if (spd_addr == (void *)0) continue;
|
||||
|
||||
ctrl->spd_switch_addr = spd_addr[index++];
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
ctrl->spd_addr[j] = spd_addr[index++];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_sysinfo_in_ram(u32 val)
|
||||
{
|
||||
set_htic_bit(0, val, 9);
|
||||
}
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
|
||||
struct DCTStatStruc *pDCTstatA)
|
||||
{
|
||||
/*
|
||||
* Memory may be mapped contiguously all the way up to 4GB (depending on setup
|
||||
* options). It is the responsibility of PCI subsystem to create an uncacheable
|
||||
* IO region below 4GB and to adjust TOP_MEM downward prior to any IO mapping or
|
||||
* accesses. It is the same responsibility of the CPU sub-system prior to
|
||||
* accessing LAPIC.
|
||||
*
|
||||
* Slot Number is an external convention, and is determined by OEM with accompanying
|
||||
* silk screening. OEM may choose to use Slot number convention which is consistent
|
||||
* with DIMM number conventions. All AMD engineering platforms do.
|
||||
*
|
||||
* Build Requirements:
|
||||
* 1. MCT_SEG0_START and MCT_SEG0_END macros to begin and end the code segment,
|
||||
* defined in mcti.inc.
|
||||
*
|
||||
* Run-Time Requirements:
|
||||
* 1. Complete Hypertransport Bus Configuration
|
||||
* 2. SMBus Controller Initialized
|
||||
* 1. BSP in Big Real Mode
|
||||
* 2. Stack at SS:SP, located somewhere between A000:0000 and F000:FFFF
|
||||
* 3. Checksummed or Valid NVRAM bits
|
||||
* 4. MCG_CTL = -1, MC4_CTL_EN = 0 for all CPUs
|
||||
* 5. MCi_STS from shutdown/warm reset recorded (if desired) prior to entry
|
||||
* 6. All var MTRRs reset to zero
|
||||
* 7. State of NB_CFG.DisDatMsk set properly on all CPUs
|
||||
* 8. All CPUs at 2GHz Speed (unless DQS training is not installed).
|
||||
* 9. All cHT links at max Speed/Width (unless DQS training is not installed).
|
||||
*
|
||||
*
|
||||
* Global relationship between index values and item values:
|
||||
*
|
||||
* pDCTstat.CASL pDCTstat.Speed
|
||||
* j CL(j) k F(k)
|
||||
* --------------------------
|
||||
* 0 2.0 - -
|
||||
* 1 3.0 1 200 MHz
|
||||
* 2 4.0 2 266 MHz
|
||||
* 3 5.0 3 333 MHz
|
||||
* 4 6.0 4 400 MHz
|
||||
* 5 7.0 5 533 MHz
|
||||
* 6 8.0 6 667 MHz
|
||||
* 7 9.0 7 800 MHz
|
||||
*/
|
||||
u8 Node, NodesWmem;
|
||||
u32 node_sys_base;
|
||||
uint8_t dimm;
|
||||
uint8_t nvram;
|
||||
uint8_t enable_cc6;
|
||||
uint8_t ecc_enabled;
|
||||
uint8_t allow_config_restore;
|
||||
|
||||
uint8_t s3resume = acpi_is_wakeup_s3();
|
||||
|
||||
restartinit:
|
||||
|
||||
if (!mctGet_NVbits(NV_ECC_CAP) || !mctGet_NVbits(NV_ECC))
|
||||
pMCTstat->try_ecc = 0;
|
||||
else
|
||||
pMCTstat->try_ecc = 1;
|
||||
|
||||
mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/
|
||||
if (s3resume) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_En_Fam15\n");
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
mct_ForceNBPState0_En_Fam15(pMCTstat, pDCTstat);
|
||||
}
|
||||
|
||||
#if CONFIG(HAVE_ACPI_RESUME)
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: Restoring DCT configuration from NVRAM\n");
|
||||
if (restore_mct_information_from_nvram(0) != 0)
|
||||
printk(BIOS_CRIT, "%s: ERROR: Unable to restore DCT configuration from NVRAM\n", __func__);
|
||||
pMCTstat->GStatus |= 1 << GSB_ConfigRestored;
|
||||
#endif
|
||||
|
||||
if (is_fam15h()) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_Dis_Fam15\n");
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
mct_ForceNBPState0_Dis_Fam15(pMCTstat, pDCTstat);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NodesWmem = 0;
|
||||
node_sys_base = 0;
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
/* Zero out data structures to avoid false detection of DIMMs */
|
||||
memset(pDCTstat, 0, sizeof(struct DCTStatStruc));
|
||||
|
||||
/* Initialize data structures */
|
||||
pDCTstat->Node_ID = Node;
|
||||
pDCTstat->dev_host = PA_HOST(Node);
|
||||
pDCTstat->dev_map = PA_MAP(Node);
|
||||
pDCTstat->dev_dct = PA_DCT(Node);
|
||||
pDCTstat->dev_nbmisc = PA_NBMISC(Node);
|
||||
pDCTstat->dev_link = PA_LINK(Node);
|
||||
pDCTstat->dev_nbctl = PA_NBCTL(Node);
|
||||
pDCTstat->NodeSysBase = node_sys_base;
|
||||
|
||||
if (mctGet_NVbits(NV_PACK_TYPE) == PT_GR) {
|
||||
uint32_t dword;
|
||||
pDCTstat->Dual_Node_Package = 1;
|
||||
|
||||
/* Get the internal node number */
|
||||
dword = Get_NB32(pDCTstat->dev_nbmisc, 0xe8);
|
||||
dword = (dword >> 30) & 0x3;
|
||||
pDCTstat->Internal_Node_ID = dword;
|
||||
} else {
|
||||
pDCTstat->Dual_Node_Package = 0;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "%s: mct_init Node %d\n", __func__, Node);
|
||||
mct_init(pMCTstat, pDCTstat);
|
||||
mctNodeIDDebugPort_D();
|
||||
pDCTstat->NodePresent = NodePresent_D(Node);
|
||||
if (pDCTstat->NodePresent) {
|
||||
pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node);
|
||||
|
||||
printk(BIOS_DEBUG, "%s: mct_InitialMCT_D\n", __func__);
|
||||
mct_InitialMCT_D(pMCTstat, pDCTstat);
|
||||
|
||||
printk(BIOS_DEBUG, "%s: mctSMBhub_Init\n", __func__);
|
||||
mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node */
|
||||
|
||||
printk(BIOS_DEBUG, "%s: mct_preInitDCT\n", __func__);
|
||||
mct_preInitDCT(pMCTstat, pDCTstat);
|
||||
}
|
||||
node_sys_base = pDCTstat->NodeSysBase;
|
||||
node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F;
|
||||
}
|
||||
|
||||
/* If the boot fails make sure training is attempted after reset */
|
||||
nvram = 0;
|
||||
set_option("allow_spd_nvram_cache_restore", &nvram);
|
||||
|
||||
#if CONFIG(DIMM_VOLTAGE_SET_SUPPORT)
|
||||
printk(BIOS_DEBUG, "%s: DIMMSetVoltage\n", __func__);
|
||||
DIMMSetVoltages(pMCTstat, pDCTstatA); /* Set the DIMM voltages (mainboard specific) */
|
||||
#endif
|
||||
if (!CONFIG(DIMM_VOLTAGE_SET_SUPPORT)) {
|
||||
/* Assume 1.5V operation */
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (!pDCTstat->NodePresent)
|
||||
continue;
|
||||
|
||||
for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
|
||||
if (pDCTstat->DIMMValid & (1 << dimm))
|
||||
pDCTstat->DimmConfiguredVoltage[dimm] = 0x1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If DIMM configuration has not changed since last boot restore training values */
|
||||
allow_config_restore = 1;
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (pDCTstat->NodePresent)
|
||||
if (!pDCTstat->spd_data.nvram_spd_match)
|
||||
allow_config_restore = 0;
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
* Stability issues have arisen on multiple Family 15h systems
|
||||
* when configuration restoration is enabled. In all cases these
|
||||
* stability issues resolved by allowing the RAM to go through a
|
||||
* full training cycle.
|
||||
*
|
||||
* Debug and reenable this!
|
||||
*/
|
||||
allow_config_restore = 0;
|
||||
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (pDCTstat->NodePresent) {
|
||||
printk(BIOS_DEBUG, "%s: mctSMBhub_Init\n", __func__);
|
||||
mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node*/
|
||||
|
||||
printk(BIOS_DEBUG, "%s: mct_initDCT\n", __func__);
|
||||
mct_initDCT(pMCTstat, pDCTstat);
|
||||
if (pDCTstat->ErrCode == SC_FatalErr) {
|
||||
goto fatalexit; /* any fatal errors?*/
|
||||
} else if (pDCTstat->ErrCode < SC_StopError) {
|
||||
NodesWmem++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NodesWmem == 0) {
|
||||
printk(BIOS_ALERT, "Unable to detect valid memory on any nodes. Halting!\n");
|
||||
goto fatalexit;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
|
||||
SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/
|
||||
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: HTMemMapInit_D\n");
|
||||
HTMemMapInit_D(pMCTstat, pDCTstatA); /* Map local memory into system address space.*/
|
||||
mctHookAfterHTMap();
|
||||
|
||||
if (!is_fam15h()) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n");
|
||||
CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mctHookAfterCPU\n");
|
||||
mctHookAfterCPU(); /* Setup external northbridge(s) */
|
||||
|
||||
/* FIXME
|
||||
* Previous training values should only be used if the current desired
|
||||
* speed is the same as the speed used in the previous boot.
|
||||
* How to get the desired speed at this point in the code?
|
||||
*/
|
||||
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: DQSTiming_D\n");
|
||||
DQSTiming_D(pMCTstat, pDCTstatA, allow_config_restore); /* Get Receiver Enable and DQS signal timing*/
|
||||
|
||||
if (!is_fam15h()) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n");
|
||||
UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */
|
||||
}
|
||||
|
||||
if (!allow_config_restore) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: :OtherTiming\n");
|
||||
mct_OtherTiming(pMCTstat, pDCTstatA);
|
||||
}
|
||||
|
||||
if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) { /* RESET# if 1st pass of DIMM spare enabled*/
|
||||
goto restartinit;
|
||||
}
|
||||
|
||||
InterleaveNodes_D(pMCTstat, pDCTstatA);
|
||||
InterleaveChannels_D(pMCTstat, pDCTstatA);
|
||||
|
||||
ecc_enabled = 1;
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (pDCTstat->NodePresent)
|
||||
if (!is_ecc_enabled(pMCTstat, pDCTstat))
|
||||
ecc_enabled = 0;
|
||||
}
|
||||
|
||||
if (ecc_enabled) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n");
|
||||
if (!ECCInit_D(pMCTstat, pDCTstatA)) { /* Setup ECC control and ECC check-bits*/
|
||||
/* Memory was not cleared during ECC setup */
|
||||
/* mctDoWarmResetMemClr_D(); */
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
|
||||
MCTMemClr_D(pMCTstat,pDCTstatA);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_fam15h()) {
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n");
|
||||
CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */
|
||||
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n");
|
||||
UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */
|
||||
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_Dis_Fam15\n");
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
mct_ForceNBPState0_Dis_Fam15(pMCTstat, pDCTstat);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_fam15h()) {
|
||||
enable_cc6 = 0;
|
||||
if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS)
|
||||
enable_cc6 = !!nvram;
|
||||
|
||||
if (enable_cc6) {
|
||||
uint8_t num_nodes;
|
||||
|
||||
num_nodes = 0;
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (pDCTstat->NodePresent)
|
||||
num_nodes++;
|
||||
}
|
||||
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (pDCTstat->NodePresent)
|
||||
set_up_cc6_storage_fam15(pMCTstat, pDCTstat, num_nodes);
|
||||
}
|
||||
|
||||
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
|
||||
struct DCTStatStruc *pDCTstat;
|
||||
pDCTstat = pDCTstatA + Node;
|
||||
|
||||
if (pDCTstat->NodePresent) {
|
||||
set_cc6_save_enable(pMCTstat, pDCTstat, 1);
|
||||
lock_dram_config(pMCTstat, pDCTstat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mct_FinalMCT_D(pMCTstat, pDCTstatA);
|
||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D Done: Global Status: %x\n", pMCTstat->GStatus);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fatalexit:
|
||||
die("mct_d: fatalexit");
|
||||
}
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
struct DCTStatStruc { /* A per Node structure*/
|
||||
/* DCTStatStruct_F - start */
|
||||
u8 Node_ID; /* Node ID of current controller */
|
||||
uint8_t Internal_Node_ID; /* Internal Node ID of the current controller */
|
||||
uint8_t Dual_Node_Package; /* 1 = Dual node package (G34) */
|
||||
uint8_t stopDCT[2]; /* Set if the DCT will be stopped */
|
||||
u8 ErrCode; /* Current error condition of Node
|
||||
0= no error
|
||||
1= Variance Error, DCT is running but not in an optimal configuration.
|
||||
2= Stop Error, DCT is NOT running
|
||||
3= Fatal Error, DCT/MCT initialization has been halted.*/
|
||||
u32 ErrStatus; /* Error Status bit Field */
|
||||
u32 Status; /* Status bit Field*/
|
||||
u8 DIMMAddr[8]; /* SPD address of DIMM controlled by MA0_CS_L[0,1]*/
|
||||
/* SPD address of..MB0_CS_L[0,1]*/
|
||||
/* SPD address of..MA1_CS_L[0,1]*/
|
||||
/* SPD address of..MB1_CS_L[0,1]*/
|
||||
/* SPD address of..MA2_CS_L[0,1]*/
|
||||
/* SPD address of..MB2_CS_L[0,1]*/
|
||||
/* SPD address of..MA3_CS_L[0,1]*/
|
||||
/* SPD address of..MB3_CS_L[0,1]*/
|
||||
u16 DIMMPresent; /*For each bit n 0..7, 1 = DIMM n is present.
|
||||
DIMM# Select Signal
|
||||
0 MA0_CS_L[0,1]
|
||||
1 MB0_CS_L[0,1]
|
||||
2 MA1_CS_L[0,1]
|
||||
3 MB1_CS_L[0,1]
|
||||
4 MA2_CS_L[0,1]
|
||||
5 MB2_CS_L[0,1]
|
||||
6 MA3_CS_L[0,1]
|
||||
7 MB3_CS_L[0,1]*/
|
||||
u16 DIMMValid; /* For each bit n 0..7, 1 = DIMM n is valid and is/will be configured*/
|
||||
u16 DIMMMismatch; /* For each bit n 0..7, 1 = DIMM n is mismatched, channel B is always considered the mismatch */
|
||||
u16 DIMMSPDCSE; /* For each bit n 0..7, 1 = DIMM n SPD checksum error*/
|
||||
u16 DimmECCPresent; /* For each bit n 0..7, 1 = DIMM n is ECC capable.*/
|
||||
u16 DimmPARPresent; /* For each bit n 0..7, 1 = DIMM n is ADR/CMD Parity capable.*/
|
||||
u16 Dimmx4Present; /* For each bit n 0..7, 1 = DIMM n contains x4 data devices.*/
|
||||
u16 Dimmx8Present; /* For each bit n 0..7, 1 = DIMM n contains x8 data devices.*/
|
||||
u16 Dimmx16Present; /* For each bit n 0..7, 1 = DIMM n contains x16 data devices.*/
|
||||
u16 DIMM2Kpage; /* For each bit n 0..7, 1 = DIMM n contains 1K page devices.*/
|
||||
u8 MAload[2]; /* Number of devices loading MAA bus*/
|
||||
/* Number of devices loading MAB bus*/
|
||||
u8 MAdimms[2]; /*Number of DIMMs loading CH A*/
|
||||
/* Number of DIMMs loading CH B*/
|
||||
u8 DATAload[2]; /*Number of ranks loading CH A DATA*/
|
||||
/* Number of ranks loading CH B DATA*/
|
||||
u8 DIMMAutoSpeed; /*Max valid Mfg. Speed of DIMMs
|
||||
1 = 200MHz
|
||||
2 = 266MHz
|
||||
3 = 333MHz
|
||||
4 = 400MHz
|
||||
5 = 533MHz*/
|
||||
u8 DIMMCASL; /* Min valid Mfg. CL bitfield
|
||||
0 = 2.0
|
||||
1 = 3.0
|
||||
2 = 4.0
|
||||
3 = 5.0
|
||||
4 = 6.0 */
|
||||
u16 DIMMTrcd; /* Minimax Trcd*40 (ns) of DIMMs*/
|
||||
u16 DIMMTrp; /* Minimax Trp*40 (ns) of DIMMs*/
|
||||
u16 DIMMTrtp; /* Minimax Trtp*40 (ns) of DIMMs*/
|
||||
u16 DIMMTras; /* Minimax Tras*40 (ns) of DIMMs*/
|
||||
u16 DIMMTrc; /* Minimax Trc*40 (ns) of DIMMs*/
|
||||
u16 DIMMTwr; /* Minimax Twr*40 (ns) of DIMMs*/
|
||||
u16 DIMMTrrd; /* Minimax Trrd*40 (ns) of DIMMs*/
|
||||
u16 DIMMTwtr; /* Minimax Twtr*40 (ns) of DIMMs*/
|
||||
u8 Speed; /* Bus Speed (to set Controller)
|
||||
1 = 200MHz
|
||||
2 = 266MHz
|
||||
3 = 333MHz
|
||||
4 = 400MHz */
|
||||
u8 CASL; /* CAS latency DCT setting
|
||||
0 = 2.0
|
||||
1 = 3.0
|
||||
2 = 4.0
|
||||
3 = 5.0
|
||||
4 = 6.0 */
|
||||
u8 Trcd; /* DCT Trcd (busclocks) */
|
||||
u8 Trp; /* DCT Trp (busclocks) */
|
||||
u8 Trtp; /* DCT Trtp (busclocks) */
|
||||
u8 Tras; /* DCT Tras (busclocks) */
|
||||
u8 Trc; /* DCT Trc (busclocks) */
|
||||
u8 Twr; /* DCT Twr (busclocks) */
|
||||
u8 Trrd; /* DCT Trrd (busclocks) */
|
||||
u8 Twtr; /* DCT Twtr (busclocks) */
|
||||
u8 Trfc[4]; /* DCT Logical DIMM0 Trfc
|
||||
0 = 75ns (for 256Mb devs)
|
||||
1 = 105ns (for 512Mb devs)
|
||||
2 = 127.5ns (for 1Gb devs)
|
||||
3 = 195ns (for 2Gb devs)
|
||||
4 = 327.5ns (for 4Gb devs) */
|
||||
/* DCT Logical DIMM1 Trfc (see Trfc0 for format) */
|
||||
/* DCT Logical DIMM2 Trfc (see Trfc0 for format) */
|
||||
/* DCT Logical DIMM3 Trfc (see Trfc0 for format) */
|
||||
u16 CSPresent; /* For each bit n 0..7, 1 = Chip-select n is present */
|
||||
u16 CSTestFail; /* For each bit n 0..7, 1 = Chip-select n is present but disabled */
|
||||
u32 DCTSysBase; /* BASE[39:8] (system address) of this Node's DCTs. */
|
||||
u32 DCTHoleBase; /* If not zero, BASE[39:8] (system address) of dram hole for HW remapping. Dram hole exists on this Node's DCTs. */
|
||||
u32 DCTSysLimit; /* LIMIT[39:8] (system address) of this Node's DCTs */
|
||||
u16 PresetmaxFreq; /* Maximum OEM defined DDR frequency
|
||||
200 = 200MHz (DDR400)
|
||||
266 = 266MHz (DDR533)
|
||||
333 = 333MHz (DDR667)
|
||||
400 = 400MHz (DDR800) */
|
||||
u8 _2Tmode; /* 1T or 2T CMD mode (slow access mode)
|
||||
1 = 1T
|
||||
2 = 2T */
|
||||
u8 TrwtTO; /* DCT TrwtTO (busclocks)*/
|
||||
u8 Twrrd; /* DCT Twrrd (busclocks)*/
|
||||
u8 Twrwr; /* DCT Twrwr (busclocks)*/
|
||||
u8 Trdrd; /* DCT Trdrd (busclocks)*/
|
||||
u32 CH_ODC_CTL[2]; /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 00h*/
|
||||
u32 CH_ADDR_TMG[2]; /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 04h*/
|
||||
/* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 20h*/
|
||||
/* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 24h*/
|
||||
u16 CH_EccDQSLike[2]; /* CHA DQS ECC byte like...*/
|
||||
u8 CH_EccDQSScale[2]; /* CHA DQS ECC byte scale*/
|
||||
/* CHA DQS ECC byte like...*/
|
||||
/* CHA DQS ECC byte scale*/
|
||||
u8 MaxAsyncLat; /* Max Asynchronous Latency (ns)*/
|
||||
/* NOTE: Not used in Barcelona - u8 CH_D_RCVRDLY[2][4]; */
|
||||
/* CHA DIMM 0 - 4 Receiver Enable Delay*/
|
||||
/* CHB DIMM 0 - 4 Receiver Enable Delay */
|
||||
/* NOTE: Not used in Barcelona - u8 CH_D_B_DQS[2][2][8]; */
|
||||
/* CHA Byte 0-7 Write DQS Delay */
|
||||
/* CHA Byte 0-7 Read DQS Delay */
|
||||
/* CHB Byte 0-7 Write DQS Delay */
|
||||
/* CHB Byte 0-7 Read DQS Delay */
|
||||
u32 PtrPatternBufA; /* Ptr on stack to aligned DQS testing pattern*/
|
||||
u32 PtrPatternBufB; /* Ptr on stack to aligned DQS testing pattern*/
|
||||
u8 Channel; /* Current Channel (0= CH A, 1 = CH B)*/
|
||||
u8 ByteLane; /* Current Byte Lane (0..7)*/
|
||||
u8 Direction; /* Current DQS-DQ training write direction (0 = read, 1 = write)*/
|
||||
u8 Pattern; /* Current pattern*/
|
||||
u8 DQSDelay; /* Current DQS delay value*/
|
||||
u32 TrainErrors; /* Current Training Errors*/
|
||||
|
||||
u32 AMC_TSC_DeltaLo; /* Time Stamp Counter measurement of AMC, Low dword*/
|
||||
u32 AMC_TSC_DeltaHi; /* Time Stamp Counter measurement of AMC, High dword*/
|
||||
/* NOTE: Not used in Barcelona - */
|
||||
u8 CH_D_DIR_MaxMin_B_Dly[2][2][2][8];
|
||||
/* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/
|
||||
/* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/
|
||||
/* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/
|
||||
/* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/
|
||||
/* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/
|
||||
/* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/
|
||||
/* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/
|
||||
/* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/
|
||||
uint64_t LogicalCPUID; /* The logical CPUID of the node*/
|
||||
u16 DimmQRPresent; /* QuadRank DIMM present?*/
|
||||
u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/
|
||||
u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/
|
||||
u16 DimmYr06; /* Bitmap indicating which Dimms have a manufactur's year code <= 2006*/
|
||||
u16 DimmWk2406; /* Bitmap indicating which Dimms have a manufactur's week code <= 24 of 2006 (June)*/
|
||||
u16 DimmDRPresent; /* Bitmap indicating that Dual Rank Dimms are present*/
|
||||
u16 DimmPlPresent; /* Bitmap indicating that Planar (1) or Stacked (0) Dimms are present.*/
|
||||
u16 ChannelTrainFai; /* Bitmap showing the channel information about failed Chip Selects
|
||||
0 in any bit field indicates Channel 0
|
||||
1 in any bit field indicates Channel 1 */
|
||||
u16 DIMMTfaw; /* Minimax Tfaw*16 (ns) of DIMMs */
|
||||
u8 Tfaw; /* DCT Tfaw (busclocks) */
|
||||
u16 CSUsrTestFail; /* Chip selects excluded by user */
|
||||
/* DCTStatStruct_F - end */
|
||||
|
||||
u16 CH_MaxRdLat[2][2]; /* Max Read Latency (nclks) [dct][pstate] */
|
||||
/* Max Read Latency (ns) for DCT 1*/
|
||||
u8 CH_D_DIR_B_DQS[2][4][2][9]; /* [A/B] [DIMM1-4] [R/W] [DQS] */
|
||||
/* CHA DIMM0 Byte 0 - 7 and Check Write DQS Delay*/
|
||||
/* CHA DIMM0 Byte 0 - 7 and Check Read DQS Delay*/
|
||||
/* CHA DIMM1 Byte 0 - 7 and Check Write DQS Delay*/
|
||||
/* CHA DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
|
||||
/* CHB DIMM0 Byte 0 - 7 and Check Write DQS Delay*/
|
||||
/* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/
|
||||
/* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/
|
||||
/* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
|
||||
u16 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */
|
||||
/* CHA DIMM 0 Receiver Enable Delay*/
|
||||
/* CHA DIMM 1 Receiver Enable Delay*/
|
||||
/* CHA DIMM 2 Receiver Enable Delay*/
|
||||
/* CHA DIMM 3 Receiver Enable Delay*/
|
||||
|
||||
/* CHB DIMM 0 Receiver Enable Delay*/
|
||||
/* CHB DIMM 1 Receiver Enable Delay*/
|
||||
/* CHB DIMM 2 Receiver Enable Delay*/
|
||||
/* CHB DIMM 3 Receiver Enable Delay*/
|
||||
u16 CH_D_BC_RCVRDLY[2][4];
|
||||
/* CHA DIMM 0 - 4 Check Byte Receiver Enable Delay*/
|
||||
/* CHB DIMM 0 - 4 Check Byte Receiver Enable Delay*/
|
||||
u8 DIMMValidDCT[2]; /* DIMM# in DCT0*/
|
||||
/* DIMM# in DCT1*/
|
||||
u16 CSPresent_DCT[2]; /* DCT# CS mapping */
|
||||
u16 MirrPresU_NumRegR; /* Address mapping from edge connect to DIMM present for unbuffered dimm
|
||||
Number of registers on the dimm for registered dimm */
|
||||
u8 MaxDCTs; /* Max number of DCTs in system*/
|
||||
/* NOTE: removed u8 DCT. Use ->dev_ for pci R/W; */ /*DCT pointer*/
|
||||
u8 GangedMode; /* Ganged mode enabled, 0 = disabled, 1 = enabled*/
|
||||
u8 DRPresent; /* Family 10 present flag, 0 = not Fam10, 1 = Fam10*/
|
||||
u32 NodeSysLimit; /* BASE[39:8],for DCT0+DCT1 system address*/
|
||||
u8 WrDatGrossH;
|
||||
u8 DqsRcvEnGrossL;
|
||||
/* NOTE: Not used - u8 NodeSpeed */ /* Bus Speed (to set Controller) */
|
||||
/* 1 = 200MHz */
|
||||
/* 2 = 266MHz */
|
||||
/* 3 = 333MHz */
|
||||
/* NOTE: Not used - u8 NodeCASL */ /* CAS latency DCT setting */
|
||||
/* 0 = 2.0 */
|
||||
/* 1 = 3.0 */
|
||||
/* 2 = 4.0 */
|
||||
/* 3 = 5.0 */
|
||||
/* 4 = 6.0 */
|
||||
u8 TrwtWB;
|
||||
u8 CurrRcvrCHADelay; /* for keep current RcvrEnDly of chA*/
|
||||
u16 T1000; /* get the T1000 figure (cycle time (ns)*1K)*/
|
||||
u8 DqsRcvEn_Pass; /* for TrainRcvrEn byte lane pass flag*/
|
||||
u8 DqsRcvEn_Saved; /* for TrainRcvrEn byte lane saved flag*/
|
||||
u8 SeedPass1Remainder; /* for Phy assisted DQS receiver enable training*/
|
||||
|
||||
/* for second pass - Second pass should never run for Fam10*/
|
||||
/* NOTE: Not used for Barcelona - u8 CH_D_B_RCVRDLY_1[2][4][8]; */ /* CHA DIMM 0 Receiver Enable Delay */
|
||||
/* CHA DIMM 1 Receiver Enable Delay*/
|
||||
/* CHA DIMM 2 Receiver Enable Delay*/
|
||||
/* CHA DIMM 3 Receiver Enable Delay*/
|
||||
|
||||
/* CHB DIMM 0 Receiver Enable Delay*/
|
||||
/* CHB DIMM 1 Receiver Enable Delay*/
|
||||
/* CHB DIMM 2 Receiver Enable Delay*/
|
||||
/* CHB DIMM 3 Receiver Enable Delay*/
|
||||
|
||||
u8 ClToNB_flag; /* is used to restore ClLinesToNbDis bit after memory */
|
||||
u32 NodeSysBase; /* for channel interleave usage */
|
||||
|
||||
/* Fam15h specific backup variables */
|
||||
uint8_t SwNbPstateLoDis;
|
||||
uint8_t NbPstateDisOnP0;
|
||||
uint8_t NbPstateThreshold;
|
||||
uint8_t NbPstateHi;
|
||||
|
||||
/* New for LB Support */
|
||||
u8 NodePresent;
|
||||
u32 dev_host;
|
||||
u32 dev_map;
|
||||
u32 dev_dct;
|
||||
u32 dev_nbmisc;
|
||||
u32 dev_link;
|
||||
u32 dev_nbctl;
|
||||
u8 TargetFreq;
|
||||
u8 TargetCASL;
|
||||
uint32_t CtrlWrd3;
|
||||
uint32_t CtrlWrd4;
|
||||
uint32_t CtrlWrd5;
|
||||
u8 DqsRdWrPos_Saved;
|
||||
u8 DqsRcvEnGrossMax;
|
||||
u8 DqsRcvEnGrossMin;
|
||||
u8 WrDatGrossMax;
|
||||
u8 WrDatGrossMin;
|
||||
uint8_t tcwl_delay[2];
|
||||
|
||||
u16 RegMan1Present; /* DIMM present bitmap of Register manufacture 1 */
|
||||
u16 RegMan2Present; /* DIMM present bitmap of Register manufacture 2 */
|
||||
|
||||
struct _sMCTStruct *C_MCTPtr;
|
||||
struct _sDCTStruct *C_DCTPtr[2];
|
||||
/* struct _sDCTStruct *C_DCT1Ptr; */
|
||||
|
||||
struct _sMCTStruct s_C_MCTPtr;
|
||||
struct _sDCTStruct s_C_DCTPtr[2];
|
||||
/* struct _sDCTStruct s_C_DCT1Ptr[8]; */
|
||||
|
||||
/* DIMM supported voltage bitmap ([2:0]: 1.25V, 1.35V, 1.5V) */
|
||||
uint8_t DimmSupportedVoltages[MAX_DIMMS_SUPPORTED];
|
||||
uint32_t DimmConfiguredVoltage[MAX_DIMMS_SUPPORTED]; /* mV */
|
||||
|
||||
uint8_t DimmRows[MAX_DIMMS_SUPPORTED];
|
||||
uint8_t DimmCols[MAX_DIMMS_SUPPORTED];
|
||||
uint8_t DimmRanks[MAX_DIMMS_SUPPORTED];
|
||||
uint8_t DimmBanks[MAX_DIMMS_SUPPORTED];
|
||||
uint8_t DimmWidth[MAX_DIMMS_SUPPORTED];
|
||||
uint64_t DimmChipSize[MAX_DIMMS_SUPPORTED];
|
||||
uint32_t DimmChipWidth[MAX_DIMMS_SUPPORTED];
|
||||
uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED];
|
||||
uint8_t DimmLoadReduced[MAX_DIMMS_SUPPORTED];
|
||||
|
||||
uint64_t DimmManufacturerID[MAX_DIMMS_SUPPORTED];
|
||||
char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1];
|
||||
uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED];
|
||||
uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED];
|
||||
|
||||
struct amd_spd_node_data spd_data;
|
||||
|
||||
/* NOTE: This must remain the last entry in this structure */
|
||||
struct DCTPersistentStatStruc persistentData;
|
||||
} __attribute__((packed, aligned(4)));
|
|
@ -0,0 +1,44 @@
|
|||
/******************************************************************************
|
||||
* $Workfile:: cache_as_ram.S
|
||||
*
|
||||
* Description: CAR setup called from bootblock_crt0.S.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "gcccar.inc"
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/post_code.h>
|
||||
|
||||
/*
|
||||
* on entry:
|
||||
* mm0: BIST (ignored)
|
||||
* mm2_mm1: timestamp at bootblock_protected_mode_entry
|
||||
*/
|
||||
|
||||
.global bootblock_pre_c_entry
|
||||
bootblock_pre_c_entry:
|
||||
|
||||
post_code(0xa0)
|
||||
|
||||
AMD_ENABLE_STACK
|
||||
|
||||
/* Align the stack and keep aligned for call to bootblock_c_entry() */
|
||||
and $0xfffffff0, %esp
|
||||
sub $8, %esp
|
||||
|
||||
movd %mm2, %eax
|
||||
pushl %eax /* tsc[63:32] */
|
||||
movd %mm1, %eax
|
||||
pushl %eax /* tsc[31:0] */
|
||||
|
||||
before_carstage:
|
||||
post_code(0xa2)
|
||||
|
||||
call bootblock_c_entry
|
||||
/* Never reached */
|
||||
|
||||
.halt_forever:
|
||||
post_code(POST_DEAD_CODE)
|
||||
hlt
|
||||
jmp .halt_forever
|
|
@ -0,0 +1,106 @@
|
|||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/amd/msr.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <smp/node.h>
|
||||
#include <bootblock_common.h>
|
||||
#include <amdblocks/agesawrapper.h>
|
||||
#include <amdblocks/agesawrapper_call.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/northbridge.h>
|
||||
#include <soc/southbridge.h>
|
||||
#include <amdblocks/psp.h>
|
||||
#include <timestamp.h>
|
||||
#include <halt.h>
|
||||
|
||||
#if CONFIG_PI_AGESA_TEMP_RAM_BASE < 0x100000
|
||||
#error "Error: CONFIG_PI_AGESA_TEMP_RAM_BASE must be >= 1MB"
|
||||
#endif
|
||||
#if CONFIG_PI_AGESA_CAR_HEAP_BASE < 0x100000
|
||||
#error "Error: CONFIG_PI_AGESA_CAR_HEAP_BASE must be >= 1MB"
|
||||
#endif
|
||||
|
||||
/* Set the MMIO Configuration Base Address, Bus Range, and misc MTRRs. */
|
||||
static void amd_initmmio(void)
|
||||
{
|
||||
msr_t mmconf;
|
||||
msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
|
||||
int mtrr;
|
||||
|
||||
mmconf.hi = 0;
|
||||
mmconf.lo = CONFIG_MMCONF_BASE_ADDRESS | MMIO_RANGE_EN
|
||||
| fms(CONFIG_MMCONF_BUS_NUMBER) << MMIO_BUS_RANGE_SHIFT;
|
||||
wrmsr(MMIO_CONF_BASE, mmconf);
|
||||
|
||||
/*
|
||||
* todo: AGESA currently writes variable MTRRs. Once that is
|
||||
* corrected, un-hardcode this MTRR.
|
||||
*
|
||||
* Be careful not to use get_free_var_mtrr/set_var_mtrr pairs
|
||||
* where all cores execute the path. Both cores within a compute
|
||||
* unit share MTRRs. Programming core0 has the appearance of
|
||||
* modifying core1 too. Using the pair again will create
|
||||
* duplicate copies.
|
||||
*/
|
||||
mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_FLASH;
|
||||
set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
|
||||
|
||||
mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_CAR_HEAP;
|
||||
set_var_mtrr(mtrr, CONFIG_PI_AGESA_CAR_HEAP_BASE,
|
||||
CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_WRBACK);
|
||||
|
||||
mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_TEMPRAM;
|
||||
set_var_mtrr(mtrr, CONFIG_PI_AGESA_TEMP_RAM_BASE,
|
||||
CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_UNCACHEABLE);
|
||||
}
|
||||
|
||||
asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
|
||||
{
|
||||
amd_initmmio();
|
||||
/*
|
||||
* Call lib/bootblock.c main with BSP, shortcut for APs
|
||||
*/
|
||||
if (!boot_cpu()) { // ./src/include/smp/node.h:#define boot_cpu(x) 1
|
||||
void (*ap_romstage_entry)(void) =
|
||||
(void (*)(void))get_ap_entry_ptr();
|
||||
|
||||
ap_romstage_entry(); /* execution does not return */
|
||||
halt();
|
||||
}
|
||||
|
||||
/* TSC cannot be relied upon. Override the TSC value passed in. */
|
||||
bootblock_main_with_basetime(timestamp_get());
|
||||
}
|
||||
|
||||
void bootblock_soc_early_init(void)
|
||||
{
|
||||
/*
|
||||
* This call (sb_reset_i2c_slaves) was originally early at
|
||||
* bootblock_c_entry, but had to be moved here. There was an
|
||||
* unexplained delay in the middle of the i2c transaction when
|
||||
* we had it in bootblock_c_entry. Moving it to this point
|
||||
* (or adding delays) fixes the issue. It seems like the processor
|
||||
* just pauses but we don't know why.
|
||||
*/
|
||||
sb_reset_i2c_slaves();
|
||||
bootblock_fch_early_init();
|
||||
post_code(0x90);
|
||||
}
|
||||
|
||||
void bootblock_soc_init(void)
|
||||
{
|
||||
if (CONFIG(STONEYRIDGE_UART))
|
||||
assert(CONFIG_UART_FOR_CONSOLE >= 0
|
||||
&& CONFIG_UART_FOR_CONSOLE <= 1);
|
||||
|
||||
u32 val = cpuid_eax(1);
|
||||
printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
|
||||
|
||||
bootblock_fch_init();
|
||||
|
||||
/* Initialize any early i2c buses. */
|
||||
i2c_soc_early_init();
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
#include <stdint.h>
|
||||
#include <device/pci_ops.h>
|
||||
|
||||
#define IO_MEM_PORT_DECODE_ENABLE_5 0x48
|
||||
#define IO_MEM_PORT_DECODE_ENABLE_6 0x4a
|
||||
#define SPI_BASE_ADDRESS 0xa0
|
||||
|
||||
#define SPI_CONTROL_1 0xc
|
||||
#define TEMPORARY_SPI_BASE_ADDRESS 0xfec10000
|
||||
|
||||
/*
|
||||
* Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
|
||||
*
|
||||
* Hardware should enable LPC ROM by pin straps. This function does not
|
||||
* handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
|
||||
*
|
||||
* The SB700 power-on default is to map 512K ROM space.
|
||||
*
|
||||
* Details: AMD SB700/710/750 BIOS Developer's Guide (BDG), Rev. 1.00,
|
||||
* PN 43366_sb7xx_bdg_pub_1.00, June 2009, section 3.1, page 14.
|
||||
*/
|
||||
static void sb700_enable_rom(void)
|
||||
{
|
||||
u8 reg8;
|
||||
u32 dword;
|
||||
pci_devfn_t dev;
|
||||
|
||||
dev = PCI_DEV(0, 0x14, 3);
|
||||
|
||||
reg8 = pci_io_read_config8(dev, IO_MEM_PORT_DECODE_ENABLE_5);
|
||||
if (CONFIG(SPI_FLASH))
|
||||
/* Disable decode of variable LPC ROM address ranges 1 and 2. */
|
||||
reg8 &= ~((1 << 3) | (1 << 4));
|
||||
else
|
||||
/* Decode variable LPC ROM address ranges 1 and 2. */
|
||||
reg8 |= (1 << 3) | (1 << 4);
|
||||
pci_io_write_config8(dev, IO_MEM_PORT_DECODE_ENABLE_5, reg8);
|
||||
|
||||
/* LPC ROM address range 1: */
|
||||
/* Enable LPC ROM range mirroring start at 0x000e(0000). */
|
||||
pci_io_write_config16(dev, 0x68, 0x000e);
|
||||
/* Enable LPC ROM range mirroring end at 0x000f(ffff). */
|
||||
pci_io_write_config16(dev, 0x6a, 0x000f);
|
||||
|
||||
/* LPC ROM address range 2: */
|
||||
/*
|
||||
* Enable LPC ROM range start at:
|
||||
* 0xfff8(0000): 512KB
|
||||
* 0xfff0(0000): 1MB
|
||||
* 0xffe0(0000): 2MB
|
||||
* 0xffc0(0000): 4MB
|
||||
* 0xff80(0000): 8MB
|
||||
*/
|
||||
pci_io_write_config16(dev, 0x6c, 0x10000 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
|
||||
/* Enable LPC ROM range end at 0xffff(ffff). */
|
||||
pci_io_write_config16(dev, 0x6e, 0xffff);
|
||||
|
||||
/* SB700 LPC Bridge 0x48.
|
||||
* Turn on all LPC IO Port decode enables
|
||||
*/
|
||||
pci_io_write_config32(dev, 0x44, 0xffffffff);
|
||||
|
||||
/* SB700 LPC Bridge 0x48.
|
||||
* BIT0: Port Enable for SuperIO 0x2E-0x2F
|
||||
* BIT1: Port Enable for SuperIO 0x4E-0x4F
|
||||
* BIT6: Port Enable for RTC IO 0x70-0x73
|
||||
*/
|
||||
reg8 = pci_io_read_config8(dev, IO_MEM_PORT_DECODE_ENABLE_5);
|
||||
reg8 |= (1 << 0) | (1 << 1) | (1 << 6);
|
||||
pci_io_write_config8(dev, IO_MEM_PORT_DECODE_ENABLE_5, reg8);
|
||||
|
||||
/* SB700 LPC Bridge 0x4a.
|
||||
* BIT5: Port Enable for Port 0x80
|
||||
*/
|
||||
reg8 = pci_io_read_config8(dev, IO_MEM_PORT_DECODE_ENABLE_6);
|
||||
reg8 |= (1 << 5);
|
||||
pci_io_write_config8(dev, IO_MEM_PORT_DECODE_ENABLE_6, reg8);
|
||||
}
|
||||
|
||||
static void sb700_configure_rom(void)
|
||||
{
|
||||
pci_devfn_t dev;
|
||||
uint32_t dword;
|
||||
|
||||
dev = PCI_DEV(0, 0x14, 3);
|
||||
|
||||
if (CONFIG(SOUTHBRIDGE_AMD_SB700_33MHZ_SPI)) {
|
||||
uint32_t prev_spi_cfg;
|
||||
volatile uint32_t *spi_mmio;
|
||||
|
||||
/* Temporarily set up SPI access to change SPI speed */
|
||||
prev_spi_cfg = dword = pci_io_read_config32(dev, SPI_BASE_ADDRESS);
|
||||
dword &= ~(0x7ffffff << 5); /* SPI_BaseAddr */
|
||||
dword |= TEMPORARY_SPI_BASE_ADDRESS & (0x7ffffff << 5);
|
||||
dword |= (0x1 << 1); /* SpiRomEnable = 1 */
|
||||
pci_io_write_config32(dev, SPI_BASE_ADDRESS, dword);
|
||||
|
||||
spi_mmio = (void *)(TEMPORARY_SPI_BASE_ADDRESS + SPI_CONTROL_1);
|
||||
dword = *spi_mmio;
|
||||
dword &= ~(0x3 << 12); /* NormSpeed = 0x1 */
|
||||
dword |= (0x1 << 12);
|
||||
*spi_mmio = dword;
|
||||
|
||||
/* Restore previous SPI access */
|
||||
pci_io_write_config32(dev, SPI_BASE_ADDRESS, prev_spi_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
static void bootblock_southbridge_init(void)
|
||||
{
|
||||
sb700_enable_rom();
|
||||
sb700_configure_rom();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue