Chapter 3: cleared

This commit is contained in:
Adrien Bourmault 2024-08-22 19:18:34 +02:00
parent cfd5194fbc
commit 0df1574eee
Signed by: neox
GPG Key ID: 57BC26A3687116F6
25 changed files with 5561 additions and 724 deletions

View File

@ -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 = {Intels Management Engine is a Security Hazard, and Users Need a Way to Disable It},
author = {Danny OBrien},
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}
}

View File

@ -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={OBrien},
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}{Intels 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

View File

@ -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}%

View File

@ -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>

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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)));

View File

@ -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

View File

@ -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();
}

View File

@ -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