Merge remote-tracking branch 'upstream/master' into system76_cleanup
2
3rdparty/libgfxinit
vendored
2
3rdparty/libhwbase
vendored
2
3rdparty/vboot
vendored
@@ -16,6 +16,12 @@ This is an (incomplete) list of POST codes emitted by coreboot v4.
|
||||
0x66 Devices have been enumerated
|
||||
0x88 Devices have been configured
|
||||
0x89 Devices have been enabled
|
||||
0xe0 Boot media (e.g. SPI ROM) is corrupt
|
||||
0xe1 Resource stored within CBFS is corrupt
|
||||
0xe2 Vendor binary (e.g. FSP) generated a fatal error
|
||||
0xe3 RAM could not be initialized
|
||||
0xe4 Critical hardware component could not initialize
|
||||
0xe5 Video subsystem failed to initialize
|
||||
0xf8 Entry into elf boot
|
||||
0xf3 Jumping to payload
|
||||
|
||||
|
@@ -1165,8 +1165,6 @@ saved .config file. As always, a 'select' statement overrides any specified
|
||||
- coreboot has added the glob operator '*' for the 'source' keyword.
|
||||
- coreboot’s Kconfig always defines variables except for strings. In other
|
||||
Kconfig implementations, bools set to false/0/no are not defined.
|
||||
- IS_ENABLED() is ‘false’ for undefined variables and ‘0’ variables. In Linux
|
||||
(where the macro comes from) it’s ‘true’ as soon as the variable is defined.
|
||||
- coreboot’s version of Kconfig adds the KCONFIG_STRICT environment variable to
|
||||
error out if there are any issues in the Kconfig files. In the Linux kernel,
|
||||
Kconfig will generate a warning, but will still output an updated .config or
|
||||
|
@@ -5,10 +5,10 @@
|
||||
If you already have an account, skip to Part 2.
|
||||
|
||||
Otherwise, go to <https://review.coreboot.org> in your preferred web browser.
|
||||
Select **Register** in the upper right corner.
|
||||
Select **Sign in** in the upper right corner.
|
||||
|
||||
Select the appropriate sign-in. For example, if you have a Google account,
|
||||
select **Google OAuth2** (gerrit-oauth-provider plugin)".**Note:** Your
|
||||
select **Google OAuth2** (gerrit-oauth-provider plugin). **Note:** Your
|
||||
username for the account will be the username of the account you used to
|
||||
sign-in with. (ex. your Google username).
|
||||
|
||||
@@ -17,7 +17,7 @@ sign-in with. (ex. your Google username).
|
||||
If you prefer to use an HTTP password instead, skip to Part 2b.
|
||||
|
||||
For the most up-to-date instructions on how to set up SSH keys with Gerrit go to
|
||||
<https://gerrit-documentation.storage.googleapis.com/Documentation/2.14.2/user-upload.html#configure_ssh)>
|
||||
<https://gerrit-documentation.storage.googleapis.com/Documentation/2.14.2/user-upload.html#configure_ssh>
|
||||
and follow the instructions there. Then, skip to Part 3.
|
||||
|
||||
Additionally, that section of the Web site provides explanation on starting
|
||||
@@ -35,13 +35,13 @@ doing so could overwrite an existing key.
|
||||
In the upper right corner, select your name and click on **Settings**.
|
||||
Select **SSH Public Keys** on the left-hand side.
|
||||
|
||||
In a terminal, run "ssh-keygen" and confirm the default path ".ssh/id_rsa".
|
||||
In a terminal, run `ssh-keygen` and confirm the default path `.ssh/id_rsa`.
|
||||
|
||||
Make a passphrase -- remember this phrase. It will be needed whenever you use
|
||||
this RSA Public Key. **Note:** You might want to use a short password, or
|
||||
forego the password altogether as you will be using it very often.
|
||||
|
||||
Open "id_rsa.pub", copy all contents and paste into the textbox under
|
||||
Open `id_rsa.pub`, copy all contents and paste into the textbox under
|
||||
"Add SSH Public Key" in the https://review.coreboot.org webpage.
|
||||
|
||||
## Part 2b: Setting up an HTTP Password
|
||||
@@ -51,7 +51,7 @@ after you select your name and click on **Settings** on the left-hand side, rath
|
||||
than selecting **SSH Public Keys**, select **HTTP Password**.
|
||||
|
||||
Click **Generate Password**. This should fill the "Password" box with a password. Copy
|
||||
the password, and add the following to your $HOME/.netrc file:
|
||||
the password, and add the following to your `$HOME/.netrc` file:
|
||||
|
||||
machine review.coreboot.org login YourUserNameHere password YourPasswordHere
|
||||
|
||||
@@ -61,15 +61,19 @@ just generated.
|
||||
## Part 3: Clone coreboot and configure it for submitting patches
|
||||
|
||||
On Gerrit, click on the **Browse** tab in the upper left corner and select
|
||||
**Repositories**. From the listing, select the "coreboot" repo. You may have
|
||||
**Repositories**. From the listing, select the "coreboot" repo. You may have
|
||||
to click the next page arrow at the bottom a few times to find it.
|
||||
|
||||
If you are using SSH keys, select **ssh** from the tabs under "Project
|
||||
coreboot" and run the "clone with commit-msg hook" command that's provided.
|
||||
This should prompt you for your id_rsa passphrase, if you previously set one.
|
||||
|
||||
**Note:** if the **ssh** option is not showing, check that you have a username
|
||||
set. Click the profile picture at the top right and select **User Settings**,
|
||||
then set your username in the **Profile** section.
|
||||
|
||||
If you are using HTTP, instead, select **http** from the tabs under "Project coreboot"
|
||||
and run the command that appears
|
||||
and run the command that appears.
|
||||
|
||||
Now is a good time to configure your global git identity, if you haven't
|
||||
already.
|
||||
@@ -87,13 +91,13 @@ and other configurations.
|
||||
|
||||
An easy first commit to make is fixing existing checkpatch errors and warnings
|
||||
in the source files. To see errors that are already present, build the files in
|
||||
the repository by running 'make lint' in the coreboot directory. Alternatively,
|
||||
if you want to run 'make lint' on a specific directory, run:
|
||||
the repository by running `make lint` in the coreboot directory. Alternatively,
|
||||
if you want to run `make lint` on a specific directory, run:
|
||||
|
||||
for file in $(git ls-files | grep src/amd/quadcore); do \
|
||||
for file in $(git ls-files | grep <filepath>); do \
|
||||
util/lint/checkpatch.pl --file $file --terse; done
|
||||
|
||||
where <filepath> is the filepath of the directory (ex. src/cpu/amd/car).
|
||||
where `filepath` is the filepath of the directory (ex. `src/cpu/amd/car`).
|
||||
|
||||
Any changes made to files under the src directory are made locally,
|
||||
and can be submitted for review.
|
||||
@@ -116,7 +120,7 @@ To commit the change, run
|
||||
git commit -s
|
||||
|
||||
**Note:** The -s adds a signed-off-by line by the committer. Your commit should be
|
||||
signed off with your name and email (i.e. **Your Name** **<Your Email>**, based on
|
||||
signed off with your name and email (i.e. **Your Name** **\<Your Email\>**, based on
|
||||
what you set with git config earlier).
|
||||
|
||||
Running git commit first checks for any errors and warnings using lint. If
|
||||
@@ -130,65 +134,73 @@ The first line of your commit message is your commit summary. This is a brief
|
||||
one-line description of what you changed in the files using the template
|
||||
below:
|
||||
|
||||
`<filepath>: Short description`
|
||||
*ex. cpu/amd/pi/00630F01: Fix checkpatch warnings and errors*
|
||||
<filepath>: Short description
|
||||
|
||||
For example,
|
||||
|
||||
cpu/amd/pi/00630F01: Fix checkpatch warnings and errors
|
||||
|
||||
**Note:** It is good practice to use present tense in your descriptions
|
||||
and do not punctuate your summary.
|
||||
|
||||
Then hit Enter. The next paragraph should be a more in-depth explanation of the
|
||||
changes you've made to the files. Again, it is good practice to use present
|
||||
tense.
|
||||
*ex. Fix space prohibited between function name and open parenthesis,
|
||||
line over 80 characters, unnecessary braces for single statement blocks,
|
||||
space required before open brace errors and warnings.*
|
||||
tense. Ex.
|
||||
|
||||
Fix space prohibited between function name and open parenthesis,
|
||||
line over 80 characters, unnecessary braces for single statement blocks,
|
||||
space required before open brace errors and warnings.
|
||||
|
||||
When you have finished writing your commit message, save and exit the text
|
||||
editor. You have finished committing your change. If, after submitting your
|
||||
commit, you wish to make changes to it, running "git commit --amend" allows
|
||||
commit, you wish to make changes to it, running `git commit --amend` allows
|
||||
you to take back your commit and amend it.
|
||||
|
||||
When you are done with your commit, run 'git push' to push your commit to
|
||||
When you are done with your commit, run `git push` to push your commit to
|
||||
coreboot.org. **Note:** To submit as a draft, use
|
||||
'git push origin HEAD:refs/drafts/master' Submitting as a draft means that
|
||||
`git push origin HEAD:refs/drafts/master`. Submitting as a draft means that
|
||||
your commit will be on coreboot.org, but is only visible to those you add
|
||||
as reviewers.
|
||||
|
||||
This has been a quick primer on how to submit a change to Gerrit for review
|
||||
using git. You may wish to review the [Gerrit code review workflow
|
||||
using git. You may wish to review the [Gerrit code review workflow
|
||||
documentation](https://gerrit-review.googlesource.com/Documentation/intro-user.html#code-review),
|
||||
especially if you plan to work on multiple changes at the same time.
|
||||
|
||||
## Part 4b: Using git cola to stage and submit a commit
|
||||
|
||||
If git cola is not installed on your machine, see
|
||||
https://git-cola.github.io/downloads.html for download instructions.
|
||||
<https://git-cola.github.io/downloads.html> for download instructions.
|
||||
|
||||
After making some edits to src files, rather than run "git add," run
|
||||
'git cola' from the command line. You should see all of the files
|
||||
After making some edits to src files, rather than run `git add`, run
|
||||
`git cola` from the command line. You should see all of the files
|
||||
edited under "Modified".
|
||||
|
||||
In the textbox labeled "Commit summary" provide a brief one-line
|
||||
description of what you changed in the files according to the template
|
||||
below:
|
||||
|
||||
`<filepath>: Short description`
|
||||
*ex. cpu/amd/pi/00630F01: Fix checkpatch warnings and errors*
|
||||
<filepath>: Short description
|
||||
|
||||
For example,
|
||||
|
||||
cpu/amd/pi/00630F01: Fix checkpatch warnings and errors
|
||||
|
||||
**Note:** It is good practice to use present tense in your descriptions
|
||||
and do not punctuate your short description.
|
||||
|
||||
In the larger text box labeled 'Extended description...' provide a more
|
||||
in-depth explanation of the changes you've made to the files. Again, it
|
||||
is good practice to use present tense.
|
||||
*ex. Fix space prohibited between function name and open parenthesis,
|
||||
line over 80 characters, unnecessary braces for single statement blocks,
|
||||
space required before open brace errors and warnings.*
|
||||
is good practice to use present tense. Ex.
|
||||
|
||||
Fix space prohibited between function name and open parenthesis,
|
||||
line over 80 characters, unnecessary braces for single statement blocks,
|
||||
space required before open brace errors and warnings.
|
||||
|
||||
Then press Enter two times to move the cursor to below your description.
|
||||
To the left of the text boxes, there is an icon with an downward arrow.
|
||||
Press the arrow and select "Sign Off." Make sure that you are signing off
|
||||
with your name and email (i.e. **Your Name** **<Your Email>**, based on what
|
||||
with your name and email (i.e. **Your Name** **\<Your Email\>**, based on what
|
||||
you set with git config earlier).
|
||||
|
||||
Now, review each of your changes and mark either individual changes or
|
||||
@@ -214,30 +226,30 @@ Note: Be sure to add any other changes that haven't already been
|
||||
explained in the extended description.
|
||||
|
||||
When ready, select 'Commit' again. Once all errors have been satisfied
|
||||
and the commit succeeds, move to the command line and run 'git push'.
|
||||
**Note:** To submit as a draft, use 'git push origin HEAD:refs/drafts/master'
|
||||
and the commit succeeds, move to the command line and run `git push`.
|
||||
**Note:** To submit as a draft, use `git push origin HEAD:refs/drafts/master`.
|
||||
Submitting as a draft means that your commit will be on coreboot.org, but is
|
||||
only visible to those you add as reviewers.
|
||||
|
||||
## Part 5: Getting your commit reviewed
|
||||
|
||||
Your commits can now be seen on review.coreboot.org if you select “Your”
|
||||
and click on “Changes” and can be reviewed by others. Your code will
|
||||
Your commits can now be seen on review.coreboot.org if you select "Your"
|
||||
and click on "Changes" and can be reviewed by others. Your code will
|
||||
first be reviewed by build bot (Jenkins), which will either give you a warning
|
||||
or verify a successful build; if so, your commit will receive a +1. Other
|
||||
users may also give your commit +1. For a commit to be merged, it needs
|
||||
to receive a +2.**Note:** A +1 and a +1 does not make a +2. Only certain users
|
||||
users may also give your commit +1. For a commit to be merged, it needs
|
||||
to receive a +2. **Note:** A +1 and a +1 does not make a +2. Only certain users
|
||||
can give a +2.
|
||||
|
||||
## Part 6 (optional): bash-git-prompt
|
||||
|
||||
To help make it easier to understand the state of the git repository
|
||||
without running 'git status' or 'git log', there is a way to make the
|
||||
without running `git status` or `git log`, there is a way to make the
|
||||
command line show the status of the repository at every point. This
|
||||
is through bash-git-prompt.
|
||||
|
||||
Instructions for installing this are found at:
|
||||
https://github.com/magicmonty/bash-git-prompt
|
||||
<https://github.com/magicmonty/bash-git-prompt>.
|
||||
**Note:** Feel free to search for different versions of git prompt,
|
||||
as this one is specific to bash.
|
||||
|
||||
@@ -250,7 +262,7 @@ Run the following two commands in the command line:
|
||||
**Note:** cd will change your directory to your home directory, so the
|
||||
git clone command will be run there.
|
||||
|
||||
Finally, open the ~/.bashrc file and append the following two lines:
|
||||
Finally, open the `~/.bashrc` file and append the following two lines:
|
||||
|
||||
GIT_PROMPT_ONLY_IN_REPO=1
|
||||
source ~/.bash-git-prompt/gitprompt.sh
|
||||
@@ -260,7 +272,7 @@ its state.
|
||||
|
||||
There also are additional configurations that you can change depending on your
|
||||
preferences. If you wish to do so, look at the "All configs for .bashrc" section
|
||||
on https://github.com/magicmonty/bash-git-prompt. Listed in that section are
|
||||
on <https://github.com/magicmonty/bash-git-prompt>. Listed in that section are
|
||||
various lines that you can copy, uncomment and add to your .bashrc file to
|
||||
change the configurations. Example configurations include avoid fetching remote
|
||||
status, and supporting versions of Git older than 1.7.10.
|
||||
@@ -273,7 +285,7 @@ Suppose you would like to update a commit that has already been pushed to the
|
||||
remote repository. If the commit you wish to update is the most recent
|
||||
commit you have made, after making your desired changes, stage the files
|
||||
(either using git add or in git cola), and amend the commit. To do so,
|
||||
if you are using the command line, run "git commit --amend." If you are
|
||||
if you are using the command line, run `git commit --amend`. If you are
|
||||
using git cola, click on the gear icon located on the upper left side under
|
||||
**Commit** and select **Amend Last Commit** in the drop down menu. Then, stage
|
||||
the files you have changed, commit the changes, and run git push to push the
|
||||
|
BIN
Documentation/mainboard/asus/p8h61-m_pro.jpg
Normal file
After Width: | Height: | Size: 68 KiB |
103
Documentation/mainboard/asus/p8h61-m_pro.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# ASUS P8H61-M Pro
|
||||
|
||||
This page describes how to run coreboot on the [ASUS P8H61-M Pro].
|
||||
|
||||
## Flashing coreboot
|
||||
|
||||
```eval_rst
|
||||
+---------------------+------------+
|
||||
| Type | Value |
|
||||
+=====================+============+
|
||||
| Socketed flash | yes |
|
||||
+---------------------+------------+
|
||||
| Model | W25Q32BV |
|
||||
+---------------------+------------+
|
||||
| Size | 4 MiB |
|
||||
+---------------------+------------+
|
||||
| Package | DIP-8 |
|
||||
+---------------------+------------+
|
||||
| Write protection | no |
|
||||
+---------------------+------------+
|
||||
| Dual BIOS feature | no |
|
||||
+---------------------+------------+
|
||||
| Internal flashing | yes |
|
||||
+---------------------+------------+
|
||||
```
|
||||
|
||||
The flash IC is located right next to one of the SATA ports:
|
||||

|
||||
|
||||
### Internal programming
|
||||
|
||||
The main SPI flash can be accessed using [flashrom]. By default, only
|
||||
the BIOS region of the flash is writable. If you wish to change any
|
||||
other region (Management Engine or flash descriptor), then an external
|
||||
programmer is required.
|
||||
|
||||
The following command may be used to flash coreboot:
|
||||
|
||||
```
|
||||
$ sudo flashrom --noverify-all --ifd -i bios -p internal -w coreboot.rom
|
||||
```
|
||||
|
||||
The use of `--noverify-all` is required since the Management Engine
|
||||
region is not readable even by the host.
|
||||
|
||||
## Known issues
|
||||
|
||||
- There is no automatic, OS-independent fan control. This is because
|
||||
the super I/O hardware monitor can only obtain valid CPU temperature
|
||||
readings from the PECI agent, whose complete initialisation is not
|
||||
publicly documented. The `coretemp` driver can still be used for
|
||||
accurate CPU temperature readings.
|
||||
|
||||
- me_cleaner breaks LPC bus and attached components!
|
||||
- PS/2 mouse doesn't work
|
||||
|
||||
## Untested
|
||||
|
||||
- parallel port
|
||||
- EHCI debug
|
||||
- S/PDIF audio
|
||||
|
||||
## Working
|
||||
|
||||
- PS/2 keyboard
|
||||
- PCIe graphics
|
||||
- USB
|
||||
- Gigabit Ethernet
|
||||
- Integrated graphics
|
||||
- SATA
|
||||
- Serial port
|
||||
- hardware monitor (see [Known issues](#known-issues) for caveats)
|
||||
- front panel audio
|
||||
- Native raminit (2 x 2GB, DDR3-1333)
|
||||
- Native graphics init (libgfxinit)
|
||||
- Wake-on-LAN
|
||||
- TPM on TPM-header
|
||||
|
||||
## Technology
|
||||
|
||||
```eval_rst
|
||||
+------------------+--------------------------------------------------+
|
||||
| Northbridge | :doc:`../../northbridge/intel/sandybridge/index` |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Southbridge | bd82x6x |
|
||||
+------------------+--------------------------------------------------+
|
||||
| CPU | model_206ax |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Super I/O | Nuvoton NCT6776 |
|
||||
+------------------+--------------------------------------------------+
|
||||
| EC | None |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Coprocessor | Intel Management Engine |
|
||||
+------------------+--------------------------------------------------+
|
||||
```
|
||||
|
||||
## Extra resources
|
||||
|
||||
- [Flash chip datasheet][W25Q32BV]
|
||||
|
||||
[ASUS P8H61-M Pro]: https://www.asus.com/Motherboards/P8H61M_Pro/
|
||||
[W25Q32BV]: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf
|
||||
[flashrom]: https://flashrom.org/Flashrom
|
83
Documentation/mainboard/facebook/fbg1701.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Facebook FBG-1701
|
||||
|
||||
This page describes how to run coreboot on the Facebook FBG1701.
|
||||
|
||||
FBG1701 are assembled with different onboard memory modules:
|
||||
Rev 1.0 Onboard Samsung K4B8G1646D-MYKO memory
|
||||
Rev 1.1 and 1.2 Onboard Micron MT41K512M16HA-125A memory
|
||||
|
||||
Use make menuconfig to configure `onboard memory manufacturer` in Mainboard
|
||||
menu.
|
||||
|
||||
## Required blobs
|
||||
|
||||
This board currently requires:
|
||||
fsp blob 3rdparty/fsp/BraswellFspBinPkg/FspBin/BSWFSP.fd
|
||||
Microcode Intel Braswell cpuid 1046C4 version 410
|
||||
(Used pre-build binary retrieved from Intel site)
|
||||
|
||||
## Flashing coreboot
|
||||
|
||||
### Internal programming
|
||||
|
||||
The main SPI flash can be accessed using [flashrom].
|
||||
|
||||
### External programming
|
||||
|
||||
The system has an internal flash chip which is a 8 MiB soldered SOIC-8 chip.
|
||||
This chip is located to the top middle side of the board. It's located
|
||||
between SoC and Q7 connector. Use clip (or solder wires) to program
|
||||
the chip.
|
||||
Specifically, it's a Winbond W25Q64FW (1.8V), whose datasheet can be found
|
||||
[here][W25Q64FW].
|
||||
|
||||
The system has an external flash chip which is a 8 MiB soldered SOIC-8 chip.
|
||||
This chip is located in the middle of carrier board close to the flex cable
|
||||
connection.
|
||||
Specifically, it's a Winbond W25Q64FV (3.3V), whose datasheet can be found
|
||||
[here][W25Q64FV].
|
||||
|
||||
## Known issues
|
||||
|
||||
- None
|
||||
|
||||
## Untested
|
||||
|
||||
- hardware monitor
|
||||
- SDIO
|
||||
- Full Embedded Controller support
|
||||
|
||||
## Working
|
||||
|
||||
- USB
|
||||
- Gigabit Ethernet
|
||||
- integrated graphics
|
||||
- flashrom
|
||||
- external graphics
|
||||
- PCIe
|
||||
- eMMC
|
||||
- SATA
|
||||
- serial port
|
||||
- SMBus
|
||||
- HDA
|
||||
- initialization with FSP MR2
|
||||
- SeaBIOS payload
|
||||
- Embedded Linux (Ubuntu 4.15+)
|
||||
|
||||
## Technology
|
||||
|
||||
```eval_rst
|
||||
+------------------+--------------------------------------------------+
|
||||
| SoC | Intel Atom Processor N3710 |
|
||||
+------------------+--------------------------------------------------+
|
||||
| CPU | Intel Braswell (N3710) |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Super I/O, EC | ITE8256 |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Coprocessor | Intel Management Engine |
|
||||
+------------------+--------------------------------------------------+
|
||||
```
|
||||
|
||||
[W25Q64FW]: https://www.winbond.com/resource-files/w25q64fw%20revn%2005182017%20sfdp.pdf
|
||||
[W25Q64FV]: https://www.winbond.com/resource-files/w25q64fv%20revs%2007182017.pdf
|
||||
[flashrom]: https://flashrom.org/Flashrom
|
82
Documentation/mainboard/hp/8760w.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# HP EliteBook 8760w
|
||||
|
||||
This page describes how to run coreboot on the [HP EliteBook 8760w].
|
||||
|
||||
## Flashing coreboot
|
||||
|
||||
```eval_rst
|
||||
+---------------------+------------+
|
||||
| Type | Value |
|
||||
+=====================+============+
|
||||
| Socketed flash | no |
|
||||
+---------------------+------------+
|
||||
| Model | W25Q64.V |
|
||||
+---------------------+------------+
|
||||
| Size | 8 MiB |
|
||||
+---------------------+------------+
|
||||
| Package | SOIC-8 |
|
||||
+---------------------+------------+
|
||||
| Write protection | no |
|
||||
+---------------------+------------+
|
||||
| Dual BIOS feature | no |
|
||||
+---------------------+------------+
|
||||
| In circuit flashing | yes |
|
||||
+---------------------+------------+
|
||||
| Internal flashing | yes |
|
||||
+---------------------+------------+
|
||||
```
|
||||
|
||||
## Required proprietary blobs
|
||||
|
||||
- Intel Firmware Descriptor, ME and GbE firmware
|
||||
- EC: please read [EliteBook Series](elitebook_series)
|
||||
|
||||
## Flashing instructions
|
||||
|
||||
HP EliteBook 8760w has an 8MB SOIC-8 flash chip on the bottom of the
|
||||
mainboard. You just need to remove the service cover, and use an SOIC-8
|
||||
clip to read and flash the chip.
|
||||
|
||||

|
||||
|
||||
## Untested
|
||||
|
||||
- dock: serial port, parallel port, ...
|
||||
- TPM
|
||||
- S3 suspend/resume
|
||||
- Gigabit Ethernet
|
||||
|
||||
## Working
|
||||
|
||||
- i7-2630QM, 0+4G+8G+0
|
||||
- i7-3720QM, 8G+8G+8G+8G
|
||||
- Arch Linux boot from SeaBIOS payload
|
||||
- EHCI debug: the port is at the right side, next to the charging port
|
||||
- SATA
|
||||
- eSATA
|
||||
- USB2 and USB3
|
||||
- keyboard, touchpad, trackpad
|
||||
- WLAN
|
||||
- WWAN
|
||||
- EC ACPI
|
||||
- Using `me_cleaner`
|
||||
|
||||
## Technology
|
||||
|
||||
```eval_rst
|
||||
+------------------+--------------------------------------------------+
|
||||
| Northbridge | :doc:`../../northbridge/intel/sandybridge/index` |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Southbridge | bd82x6x |
|
||||
+------------------+--------------------------------------------------+
|
||||
| CPU | model_206ax |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Super I/O | SMSC LPC47n217 |
|
||||
+------------------+--------------------------------------------------+
|
||||
| EC | SMSC KBC1126 |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Coprocessor | Intel Management Engine |
|
||||
+------------------+--------------------------------------------------+
|
||||
```
|
||||
|
||||
[HP EliteBook 8760w]: https://support.hp.com/us-en/product/hp-elitebook-8760w-mobile-workstation/5071180
|
BIN
Documentation/mainboard/hp/8760w_flash.jpg
Normal file
After Width: | Height: | Size: 54 KiB |
111
Documentation/mainboard/hp/elitebook_series.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# HP EliteBook series
|
||||
|
||||
This document is about HP EliteBook series laptops up to Ivy Bridge era
|
||||
which use SMSC KBC1126 as embedded controller.
|
||||
|
||||
## EC
|
||||
|
||||
SMSC KBC1098/KBC1126 has been used in HP EliteBooks for many generations.
|
||||
They use similar EC firmware that will load other code and data from the
|
||||
SPI flash chip, so we need to put some firmware blobs to the coreboot image.
|
||||
|
||||
The following document takes EliteBook 2760p as an example.
|
||||
|
||||
First, you need to extract the blobs needed by EC firmware using util/kbc1126.
|
||||
You can extract them from your backup firmware image, or firmware update
|
||||
provided by HP with [unar] as follows:
|
||||
|
||||
```bash
|
||||
wget https://ftp.hp.com/pub/softpaq/sp79501-80000/sp79710.exe
|
||||
unar sp79710.exe
|
||||
${COREBOOT_DIR}/util/kbc1126/kbc1126_ec_dump sp79710/Rompaq/68SOU.BIN
|
||||
mv 68SOU.BIN.fw1 ${COREBOOT_DIR}/2760p-fw1.bin
|
||||
mv 68SOU.BIN.fw2 ${COREBOOT_DIR}/2760p-fw2.bin
|
||||
```
|
||||
|
||||
When you config coreboot, select:
|
||||
|
||||
```text
|
||||
Chipset --->
|
||||
[*] Add firmware images for KBC1126 EC
|
||||
(2760p-fw1.bin) KBC1126 firmware #1 path and filename
|
||||
(2760p-fw2.bin) KBC1126 filename #2 path and filename
|
||||
```
|
||||
|
||||
## Super I/O
|
||||
|
||||
EliteBook 8000 series laptops have SMSC LPC47n217 Super I/O to provide
|
||||
a serial port and a parallel port, you can debug the laptop via this
|
||||
serial port.
|
||||
|
||||
## porting
|
||||
|
||||
To port coreboot to an HP EliteBook laptop, you need to do the following:
|
||||
|
||||
- select Kconfig option `EC_HP_KBC1126`
|
||||
- select Kconfig option `SUPERIO_SMSC_LPC47N217` if there is LPC47n217 Super I/O
|
||||
- initialize EC and Super I/O in romstage
|
||||
- add EC and Super I/O support to devicetree.cb
|
||||
|
||||
To get the related values for EC in devicetree.cb, you need to extract the EFI
|
||||
module EcThermalInit from the vendor UEFI firmware with [UEFITool]. Usually,
|
||||
`ec_data_port`, `ec_cmd_port` and `ec_ctrl_reg` has the following values:
|
||||
|
||||
- For xx60 series: 0x60, 0x64, 0xca
|
||||
- For xx70 series: 0x62, 0x66, 0x81
|
||||
|
||||
You can use [radare2] and the following [r2pipe] Python script to find
|
||||
these values from the EcThermalInit EFI module:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
|
||||
# install radare2 and use `pip3 install --user r2pipe` to install r2pipe
|
||||
|
||||
import r2pipe
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
fn = "ecthermalinit.efi"
|
||||
else:
|
||||
fn = sys.argv[1]
|
||||
|
||||
r2 = r2pipe.open(fn)
|
||||
r2.cmd("aa")
|
||||
entryf = r2.cmdj("pdfj")
|
||||
|
||||
for insn in entryf["ops"]:
|
||||
if "lea r8" in insn["opcode"]:
|
||||
_callback = insn["ptr"]
|
||||
break
|
||||
|
||||
r2.cmd("af @ {}".format(_callback))
|
||||
callbackf_insns = r2.cmdj("pdfj @ {}".format(_callback))["ops"]
|
||||
|
||||
def find_port(addr):
|
||||
ops = r2.cmdj("pdfj @ {}".format(addr))["ops"]
|
||||
for insn in ops:
|
||||
if "lea r8d" in insn["opcode"]:
|
||||
return insn["ptr"]
|
||||
|
||||
ctrl_reg_found = False
|
||||
|
||||
for i in range(0, len(callbackf_insns)):
|
||||
if not ctrl_reg_found and "mov cl" in callbackf_insns[i]["opcode"]:
|
||||
ctrl_reg_found = True
|
||||
ctrl_reg = callbackf_insns[i]["ptr"]
|
||||
print("ec_ctrl_reg = 0x%02x" % ctrl_reg)
|
||||
cmd_port = find_port(callbackf_insns[i+1]["jump"])
|
||||
data_port = find_port(callbackf_insns[i+3]["jump"])
|
||||
print("ec_cmd_port = 0x%02x\nec_data_port = 0x%02x" % (cmd_port, data_port))
|
||||
|
||||
if "mov bl" in callbackf_insns[i]["opcode"]:
|
||||
ctrl_value = callbackf_insns[i]["ptr"]
|
||||
print("ec_fan_ctrl_value = 0x%02x" % ctrl_value)
|
||||
```
|
||||
|
||||
|
||||
[unar]: https://theunarchiver.com/command-line
|
||||
[UEFITool]: https://github.com/LongSoft/UEFITool
|
||||
[radare2]: https://radare.org/
|
||||
[r2pipe]: https://github.com/radare/radare2-r2pipe
|
@@ -6,6 +6,7 @@ This section contains documentation about coreboot on specific mainboards.
|
||||
|
||||
- [F2A85-M](asus/f2a85-m.md)
|
||||
- [P8H61-M LX](asus/p8h61-m_lx.md)
|
||||
- [P8H61-M Pro](asus/p8h61-m_pro.md)
|
||||
|
||||
## ASRock
|
||||
|
||||
@@ -29,6 +30,10 @@ The boards in this section are not real mainboards, but emulators.
|
||||
- [IceLake RVP](intel/icelake_rvp.md)
|
||||
- [KBLRVP11](intel/kblrvp11.md)
|
||||
|
||||
## Facebook
|
||||
|
||||
- [FBG-1701](facebook/fbg1701.md)
|
||||
|
||||
## Foxconn
|
||||
|
||||
- [D41S](foxconn/d41s.md)
|
||||
@@ -44,11 +49,17 @@ The boards in this section are not real mainboards, but emulators.
|
||||
## Open Cellular
|
||||
|
||||
- [Elgon](opencellular/elgon.md)
|
||||
- [Rotundu](opencellular/rotundu.md)
|
||||
|
||||
## HP
|
||||
|
||||
- [Compaq 8200 Elite SFF](hp/compaq_8200_sff.md)
|
||||
|
||||
### EliteBook series
|
||||
|
||||
- [EliteBook common](hp/elitebook_series.md)
|
||||
- [EliteBook 8760w](hp/8760w.md)
|
||||
|
||||
## Lenovo
|
||||
|
||||
- [Mainboard codenames](lenovo/codenames.md)
|
||||
@@ -74,6 +85,10 @@ The boards in this section are not real mainboards, but emulators.
|
||||
|
||||
- [MS-7707](msi/ms7707/ms7707.md)
|
||||
|
||||
## Roda
|
||||
|
||||
- [RK9 Flash Header](roda/rk9/flash_header.md)
|
||||
|
||||
## SiFive
|
||||
|
||||
- [SiFive HiFive Unleashed](sifive/hifive-unleashed.md)
|
||||
@@ -81,3 +96,7 @@ The boards in this section are not real mainboards, but emulators.
|
||||
## Supermicro
|
||||
|
||||
- [X10SLM+-F](supermicro/x10slm-f.md)
|
||||
|
||||
## UP
|
||||
|
||||
- [Squared](up/squared/index.md)
|
||||
|
76
Documentation/mainboard/opencellular/rotundu.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Rutundu
|
||||
|
||||
This page describes how to run coreboot on the [Rotundu] compute board
|
||||
from [OpenCellular].
|
||||
|
||||
## TODO
|
||||
|
||||
* Configure UART
|
||||
* EC interface
|
||||
|
||||
## Flashing coreboot
|
||||
|
||||
```eval_rst
|
||||
+---------------------+------------+
|
||||
| Type | Value |
|
||||
+=====================+============+
|
||||
| Socketed flash | no |
|
||||
+---------------------+------------+
|
||||
| Model | W25Q128 |
|
||||
+---------------------+------------+
|
||||
| Size | 16 MiB |
|
||||
+---------------------+------------+
|
||||
| In circuit flashing | yes |
|
||||
+---------------------+------------+
|
||||
| Package | SOIC-8 |
|
||||
+---------------------+------------+
|
||||
| Write protection | No |
|
||||
+---------------------+------------+
|
||||
| Dual BIOS feature | No |
|
||||
+---------------------+------------+
|
||||
| Internal flashing | yes |
|
||||
+---------------------+------------+
|
||||
```
|
||||
|
||||
### Internal programming
|
||||
|
||||
The SPI flash can be accessed using [flashrom].
|
||||
|
||||
### External programming
|
||||
|
||||
The GBCv1 board does have a pinheader to flash the SOIC-8 in circuit.
|
||||
Directly connecting a Pomona test-clip on the flash is also possible.
|
||||
|
||||
**Closeup view of SOIC-8 flash IC**
|
||||
|
||||
![][rotundu_flash]
|
||||
|
||||
[rotundu_flash]: rotundu_flash.jpg
|
||||
|
||||
**SPI header**
|
||||
|
||||
![][rotundu_header2]
|
||||
|
||||
[rotundu_header2]: rotundu_header2.jpg
|
||||
|
||||
**SPI header pinout**
|
||||
|
||||
Dediprog compatible pinout.
|
||||
|
||||
![][rotundu_j16]
|
||||
|
||||
[rotundu_j16]: rotundu_j16.png
|
||||
|
||||
## Technology
|
||||
|
||||
```eval_rst
|
||||
+------------------+--------------------------------------------------+
|
||||
| SoC | Intel Baytrail |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Coprocessor | Intel ME |
|
||||
+------------------+--------------------------------------------------+
|
||||
```
|
||||
|
||||
[Rotundu]: https://github.com/Telecominfraproject/OpenCellular
|
||||
[OpenCellular]: https://code.fb.com/connectivity/introducing-opencellular-an-open-source-wireless-access-platform/
|
||||
[flashrom]: https://flashrom.org/Flashrom
|
BIN
Documentation/mainboard/opencellular/rotundu_flash.jpg
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
Documentation/mainboard/opencellular/rotundu_header2.jpg
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
Documentation/mainboard/opencellular/rotundu_j16.png
Normal file
After Width: | Height: | Size: 20 KiB |
23
Documentation/mainboard/roda/rk9/flash_header.md
Normal file
@@ -0,0 +1,23 @@
|
||||
Roda RK9 Flash Header
|
||||
=====================
|
||||
|
||||
There is a 5x2 pin, 1.27mm pitch header *J1* south of the BIOS flash. It
|
||||
follows the pinout of the Dediprog adaptor board:
|
||||
|
||||
+------+
|
||||
| 1 2 | 1: HOLD 2 2: CS 2
|
||||
| 3 4 | 3: CS 1 4: VCC
|
||||
| 5 6 | 5: MISO 6: HOLD 1
|
||||
| 7 8 | 7: 8: CLK
|
||||
| 9 10 | 9: GND 10: MOSI
|
||||
+------+
|
||||
|
||||
Pins 3 to 10 directly map to the regular SPI flash pinout.
|
||||
|
||||
There is also a *JP17* around. Ideally, it should be closed during
|
||||
programming (isolates the SPI bus from the southbridge):
|
||||
|
||||
+---+
|
||||
| 1 | 1: SF100-I/O3
|
||||
| 2 | 2: GND
|
||||
+---+
|
BIN
Documentation/mainboard/up/squared/bottom.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
99
Documentation/mainboard/up/squared/index.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Squared
|
||||
|
||||
## Overview
|
||||
### Top
|
||||
![][overview_top]
|
||||
|
||||
### Bottom
|
||||
![][overview_bottom]
|
||||
|
||||
## Mainboard components
|
||||
### Platform
|
||||
```eval_rst
|
||||
+------------------+----------------------------------+
|
||||
| CPU | Intel Atom, Celeron, Pentium |
|
||||
+------------------+----------------------------------+
|
||||
| PCH | Intel Apollo Lake |
|
||||
+------------------+----------------------------------+
|
||||
| EC / Super IO | N/A |
|
||||
+------------------+----------------------------------+
|
||||
| Coprocessor | Intel TXE 3.0 |
|
||||
+------------------+----------------------------------+
|
||||
```
|
||||
|
||||
### Flash chip
|
||||
```eval_rst
|
||||
+---------------------+------------+
|
||||
| Type | Value |
|
||||
+=====================+============+
|
||||
| Socketed flash | no |
|
||||
+---------------------+------------+
|
||||
| Vendor | Winbond |
|
||||
+---------------------+------------+
|
||||
| Model | W25Q128FW |
|
||||
+---------------------+------------+
|
||||
| Voltage | 1.8V |
|
||||
+---------------------+------------+
|
||||
| Size | 16 MiB |
|
||||
+---------------------+------------+
|
||||
| Package | SOIC-8 |
|
||||
+---------------------+------------+
|
||||
| Write protection | No |
|
||||
+---------------------+------------+
|
||||
| Internal flashing | No |
|
||||
+---------------------+------------+
|
||||
| In curcuit flashing | Yes |
|
||||
+---------------------+------------+
|
||||
```
|
||||
|
||||
## Board status
|
||||
### Working
|
||||
- bootblock, romstage, ramstage
|
||||
- Serial console UART0, UART1
|
||||
- SPI flash console
|
||||
- iGPU init with libgfxinit
|
||||
- LAN1, LAN2
|
||||
- USB2, USB3
|
||||
- HDMI, DisplayPort
|
||||
- eMMC
|
||||
- flashing with flashrom externally
|
||||
|
||||
### Work in progress
|
||||
- Documentation
|
||||
- ACPI
|
||||
|
||||
### Not working / Known issues
|
||||
- Generally SeaBIOS works, but it can't find the CBFS region and therefore it can't load seavgabios. This is because of changes at the Apollolake platform.
|
||||
|
||||
### Untested
|
||||
- GPIO pin header
|
||||
- 60 pin EXHAT
|
||||
- Camera interface
|
||||
- MIPI-CSI2 2-lane (2MP)
|
||||
- MIPI-CSI2 4-lane (8MP)
|
||||
- SATA3
|
||||
- USB3 OTG
|
||||
- embedded DisplayPort
|
||||
- M.2 slot
|
||||
- mini PCIe
|
||||
- flashing with flashrom internally using Linux
|
||||
|
||||
## Building and flashing coreboot
|
||||
### Building
|
||||
|
||||
```bash
|
||||
make distclean
|
||||
touch .config
|
||||
./util/scripts/config --enable VENDOR_UP
|
||||
./util/scripts/config --enable BOARD_UP_SQUARED
|
||||
./util/scripts/config --enable NEED_IFWI
|
||||
./util/scripts/config --enable HAVE_IFD_BIN
|
||||
./util/scripts/config --set-str IFWI_FILE_NAME "<path_to_your_bios_region>"
|
||||
./util/scripts/config --set-str IFD_BIN_PATH "<path_to_your_ifd_region>"
|
||||
make olddefconfig
|
||||
```
|
||||
|
||||
### Flashing
|
||||
|
||||
[overview_top]: top.jpg
|
||||
[overview_bottom]: bottom.jpg
|
BIN
Documentation/mainboard/up/squared/top.jpg
Normal file
After Width: | Height: | Size: 33 KiB |
@@ -6,3 +6,4 @@ This section contains documentation about coreboot on specific Intel "Sandy Brid
|
||||
|
||||
- [Native Ram Initialization](nri.md)
|
||||
- [RAM initialization feature matrix](nri_features.md)
|
||||
- [ME Cleaner](me_cleaner.md)
|
||||
|
20
Documentation/northbridge/intel/sandybridge/me_cleaner.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# ME Cleaner
|
||||
It's possible to 'clean' the ME partition within the flash medium as part
|
||||
of the build process. While cleaning as much code as possible is removed
|
||||
from the ME firmware partition. In this state the ME errors out and doesn't
|
||||
operate any more.
|
||||
|
||||
**Using a 'cleaned' ME partition may lead to issues and its use should be
|
||||
carefully evaulated.**
|
||||
|
||||
## Observations with 'cleaned' ME
|
||||
|
||||
* Instable LPC bus
|
||||
* SuperIO is malfunctioning
|
||||
* TPM is malfunctioning
|
||||
* Random system shutdowns on high bus activity
|
||||
|
||||
## Filing bug reports
|
||||
|
||||
Always test with unmodified IFD and ME section before reporting bugs to the
|
||||
coreboot project.
|
8
Documentation/vendorcode/eltan/index.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Eltan vendorcode-specific documentation
|
||||
|
||||
This section contains documentation about coreboot on Eltan specific
|
||||
vendorcode.
|
||||
|
||||
## Sections
|
||||
|
||||
- [Security](security.md)
|
39
Documentation/vendorcode/eltan/security.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Eltan Security
|
||||
|
||||
## Security
|
||||
This code enables measured boot and verified boot support.
|
||||
Verified boot is available in coreboot, but based on ChromeOS. This vendorcode
|
||||
uses a small encryption library and leave much more space in flash for the
|
||||
payload.
|
||||
|
||||
## Hashing Library
|
||||
The library suppports SHA-1, SHA-256 and SHA-512. The required routines of
|
||||
`3rdparty/vboot/firmware/2lib` are used.
|
||||
|
||||
## Measured boot
|
||||
measured boot support will use TPM2 device if available. The items specified
|
||||
in `mb_log_list[]` will be measured.
|
||||
|
||||
## Verified boot
|
||||
verified boot support will use TPM2 device if available. The items specified
|
||||
in the next table will be verified:
|
||||
* `bootblock_verify_list[]`
|
||||
* `verify_item_t romstage_verify_list[]`
|
||||
* `ram_stage_additional_list[]`
|
||||
* `ramstage_verify_list[]`
|
||||
* `payload_verify_list[]`
|
||||
* `oprom_verify_list[]`
|
||||
|
||||
## Enabling support
|
||||
|
||||
* Measured boot can be enabled using **CONFIG_MBOOT**
|
||||
* Create mb_log_list table with list of item to measure
|
||||
* Create tables bootblock_verify_list[], verify_item_t romstage_verify_list[],
|
||||
ram_stage_additional_list[], ramstage_verify_list[], payload_verify_list[],
|
||||
oprom_verify_list[]
|
||||
* Verified boot can be enabled using **CONFIG_VERIFIED_BOOT**
|
||||
* Added Kconfig values for verbose console output
|
||||
|
||||
## Debugging
|
||||
|
||||
You can enable verbose console output in *menuconfig*.
|
@@ -382,6 +382,12 @@ M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/supermicro/x10slm-f/
|
||||
|
||||
FACEBOOK FBG1701 MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/facebook/fbg1701/
|
||||
|
||||
AMD FAMILY10H & FAMILY15H (NON-AGESA) CPUS & NORTHBRIDGE
|
||||
M: Timothy Pearson <tpearson@raptorengineeringinc.com>
|
||||
S: Supported
|
||||
|
@@ -31,7 +31,7 @@ CONFIG_OVERRIDE_DEVICETREE:=$(call strip_quotes, $(CONFIG_OVERRIDE_DEVICETREE))
|
||||
# misleadingly named, this is the coreboot version
|
||||
ifeq ($(KERNELVERSION),)
|
||||
ifeq ($(BUILD_TIMELESS),1)
|
||||
KERNELVERSION := TIMELESS
|
||||
KERNELVERSION := -TIMELESS--LESSTIME-
|
||||
else
|
||||
KERNELVERSION := $(strip $(if $(GIT),\
|
||||
$(shell git describe --dirty --always || git describe),\
|
||||
@@ -401,7 +401,7 @@ endif
|
||||
CFLAGS_common += -pipe -g -nostdinc -std=gnu11
|
||||
CFLAGS_common += -nostdlib -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS_common += -Wwrite-strings -Wredundant-decls -Wno-trigraphs
|
||||
CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time
|
||||
CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time -Wtype-limits
|
||||
CFLAGS_common += -fno-common -ffreestanding -fno-builtin -fomit-frame-pointer
|
||||
CFLAGS_common += -ffunction-sections -fdata-sections -fno-pie
|
||||
ifeq ($(CONFIG_COMPILER_GCC),y)
|
||||
|
@@ -103,15 +103,10 @@ static void show_config_space(WINDOW *win, int row, int col, int index)
|
||||
static int pci_module_redraw(WINDOW *win)
|
||||
{
|
||||
unsigned int bus, slot, func;
|
||||
int i, last;
|
||||
int i;
|
||||
|
||||
print_module_title(win, "PCI Device List");
|
||||
|
||||
last = menu_first + MENU_VISIBLE;
|
||||
|
||||
if (last > devices_index)
|
||||
last = devices_index;
|
||||
|
||||
for (i = 0; i < MENU_VISIBLE; i++) {
|
||||
int item = menu_first + i;
|
||||
|
||||
|
1
payloads/external/LinuxBoot/targets/linux.mk
vendored
@@ -12,6 +12,7 @@
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
SHELL := /bin/bash
|
||||
|
||||
ARCH-$(CONFIG_LINUXBOOT_X86_64)=x86_64
|
||||
ARCH-$(CONFIG_LINUXBOOT_X86)=x86
|
||||
|
9
payloads/external/Makefile.inc
vendored
@@ -229,7 +229,9 @@ endif
|
||||
ifeq ($(CONFIG_BUILD_IPXE),y)
|
||||
PXE_ROM_FILE:=payloads/external/iPXE/ipxe/ipxe.rom
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PXE_ADD_SCRIPT),y)
|
||||
PXE_CONFIG_SCRIPT:=$(abspath $(patsubst "%",%,$(CONFIG_PXE_SCRIPT)))
|
||||
endif
|
||||
ifeq ($(CONFIG_CONSOLE_SERIAL)$(CONFIG_DRIVERS_UART_8250IO),yy)
|
||||
IPXE_UART=COM$(call int-add,$(CONFIG_UART_FOR_CONSOLE) 1)
|
||||
endif
|
||||
@@ -244,7 +246,7 @@ cbfs-files-$(CONFIG_PXE_ROM)$(CONFIG_BUILD_IPXE) += pci$(CONFIG_PXE_ROM_ID).rom
|
||||
pci$(CONFIG_PXE_ROM_ID).rom-file := $(PXE_ROM_FILE)
|
||||
pci$(CONFIG_PXE_ROM_ID).rom-type := raw
|
||||
|
||||
payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG)
|
||||
payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG) $(PXE_CONFIG_SCRIPT)
|
||||
$(MAKE) -C payloads/external/iPXE all \
|
||||
CROSS_COMPILE="$(CROSS_COMPILE_$(ARCH-ramstage-y))" \
|
||||
PXE_ROM_PCI_ID=$(PXE_ROM_PCI_ID) \
|
||||
@@ -253,6 +255,9 @@ payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG)
|
||||
CONSOLE_SERIAL=$(IPXE_SERIAL_CONSOLE) \
|
||||
IPXE_UART=$(IPXE_UART) \
|
||||
CONFIG_TTYS0_BAUD=$(CONFIG_TTYS0_BAUD) \
|
||||
CONFIG_SCRIPT=$(PXE_CONFIG_SCRIPT) \
|
||||
CONFIG_HAS_SCRIPT=$(CONFIG_PXE_ADD_SCRIPT) \
|
||||
CONFIG_PXE_NO_PROMT=$(CONFIG_PXE_NO_PROMT) \
|
||||
MFLAGS= MAKEFLAGS=
|
||||
|
||||
# LinuxBoot
|
||||
|
26
payloads/external/iPXE/Kconfig
vendored
@@ -87,5 +87,31 @@ config PXE_SERIAL_CONSOLE
|
||||
|
||||
Unselect to let only SeaBIOS handle printing output.
|
||||
|
||||
config PXE_NO_PROMT
|
||||
bool "Do not show prompt to boot from PXE"
|
||||
default n
|
||||
depends on BUILD_IPXE
|
||||
help
|
||||
Don't wait for the user to press Ctrl-B.
|
||||
The PXE still can be run as it shows up in SeaBIOS's payload list.
|
||||
|
||||
config PXE_ADD_SCRIPT
|
||||
bool "Embed an iPXE script for automated provisioning"
|
||||
depends on BUILD_IPXE
|
||||
default n
|
||||
help
|
||||
Enable to embed a script that is run instead of an iPXE shell.
|
||||
|
||||
config PXE_SCRIPT
|
||||
string "Embedded iPXE script path and filename"
|
||||
depends on PXE_ADD_SCRIPT
|
||||
default ""
|
||||
help
|
||||
Path to a script that is embedded into the iPXE binary.
|
||||
Example: startup.ipxe
|
||||
|
||||
Uses the ipxe script instead showing the prompt:
|
||||
"Press Ctrl-B to start iPXE..."
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
21
payloads/external/iPXE/Makefile
vendored
@@ -54,15 +54,34 @@ ifeq ($(CONSOLE_SERIAL),yy)
|
||||
sed 's|#define\s*COMCONSOLE.*|#define COMCONSOLE $(IPXE_UART)|' "$(project_dir)/src/config/serial.h" > "$(project_dir)/src/config/serial.h.tmp"
|
||||
sed 's|#define\s*COMSPEED.*|#define COMSPEED $(CONFIG_TTYS0_BAUD)|' "$(project_dir)/src/config/serial.h.tmp" > "$(project_dir)/src/config/serial.h"
|
||||
endif
|
||||
ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMT)),)
|
||||
cp "$(project_dir)/src/config/general.h" "$(project_dir)/src/config/general.h.cb"
|
||||
endif
|
||||
ifeq ($(CONFIG_HAS_SCRIPT),y)
|
||||
sed 's|//#define\s*IMAGE_SCRIPT.*|#define IMAGE_SCRIPT|' "$(project_dir)/src/config/general.h" > "$(project_dir)/src/config/general.h.tmp"
|
||||
mv "$(project_dir)/src/config/general.h.tmp" "$(project_dir)/src/config/general.h"
|
||||
endif
|
||||
ifeq ($(CONFIG_PXE_NO_PROMT),y)
|
||||
sed 's|#define\s*BANNER_TIMEOUT.*|#define BANNER_TIMEOUT 0|' "$(project_dir)/src/config/general.h" > "$(project_dir)/src/config/general.h.tmp"
|
||||
mv "$(project_dir)/src/config/general.h.tmp" "$(project_dir)/src/config/general.h"
|
||||
endif
|
||||
|
||||
build: config
|
||||
build: config $(CONFIG_SCRIPT)
|
||||
ifeq ($(CONFIG_HAS_SCRIPT),y)
|
||||
echo " MAKE $(project_name) $(TAG-y) EMBED=$(CONFIG_SCRIPT)"
|
||||
$(MAKE) -C $(project_dir)/src bin/$(PXE_ROM_PCI_ID).rom EMBED=$(CONFIG_SCRIPT)
|
||||
else
|
||||
echo " MAKE $(project_name) $(TAG-y)"
|
||||
$(MAKE) -C $(project_dir)/src bin/$(PXE_ROM_PCI_ID).rom
|
||||
endif
|
||||
cp $(project_dir)/src/bin/$(PXE_ROM_PCI_ID).rom $(project_dir)/ipxe.rom
|
||||
ifeq ($(CONSOLE_SERIAL),yy)
|
||||
cp "$(project_dir)/src/config/console.h.cb" "$(project_dir)/src/config/console.h"
|
||||
cp "$(project_dir)/src/config/serial.h.cb" "$(project_dir)/src/config/serial.h"
|
||||
endif
|
||||
ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMT)),)
|
||||
cp "$(project_dir)/src/config/general.h.cb" "$(project_dir)/src/config/general.h"
|
||||
endif
|
||||
|
||||
clean:
|
||||
test -d $(project_dir) && $(MAKE) -C $(project_dir)/src veryclean || exit 0
|
||||
|
@@ -258,6 +258,11 @@ config IPQ40XX_SERIAL_CONSOLE
|
||||
depends on SERIAL_CONSOLE
|
||||
default n
|
||||
|
||||
config QCS405_SERIAL_CONSOLE
|
||||
bool "QCS405 SOC compatible serial port driver"
|
||||
depends on SERIAL_CONSOLE
|
||||
default n
|
||||
|
||||
config PL011_SERIAL_CONSOLE
|
||||
bool "PL011 compatible serial port driver"
|
||||
depends on 8250_SERIAL_CONSOLE
|
||||
|
@@ -1,3 +1,5 @@
|
||||
CONFIG_LP_CHROMEOS=y
|
||||
CONFIG_LP_ARCH_ARM64=y
|
||||
CONFIG_LP_TIMER_ARM64_ARCH=y
|
||||
CONFIG_LP_SERIAL_CONSOLE=y
|
||||
CONFIG_LP_QCS405_SERIAL_CONSOLE=y
|
||||
|
@@ -37,6 +37,7 @@ libc-$(CONFIG_LP_8250_SERIAL_CONSOLE) += serial/8250.c serial/serial.c
|
||||
libc-$(CONFIG_LP_S5P_SERIAL_CONSOLE) += serial/s5p.c serial/serial.c
|
||||
libc-$(CONFIG_LP_IPQ806X_SERIAL_CONSOLE) += serial/ipq806x.c serial/serial.c
|
||||
libc-$(CONFIG_LP_IPQ40XX_SERIAL_CONSOLE) += serial/ipq40xx.c serial/serial.c
|
||||
libc-$(CONFIG_LP_QCS405_SERIAL_CONSOLE) += serial/qcs405.c serial/serial.c
|
||||
libc-$(CONFIG_LP_PC_KEYBOARD) += i8042/keyboard.c
|
||||
libc-$(CONFIG_LP_PC_MOUSE) += i8042/mouse.c
|
||||
libc-$(CONFIG_LP_PC_I8042) += i8042/i8042.c
|
||||
|
@@ -63,6 +63,7 @@
|
||||
#define I8042_KBCMD_EN 0xf4
|
||||
#define I8042_KBCMD_DEFAULT_DIS 0xf5
|
||||
#define I8042_KBCMD_SET_DEFAULT 0xf6
|
||||
#define I8042_KBCMD_ACK 0xfa
|
||||
#define I8042_KBCMD_RESEND 0xfe
|
||||
#define I8042_KBCMD_RESET 0xff
|
||||
|
||||
|
@@ -172,7 +172,7 @@ static unsigned char keyboard_cmd(unsigned char cmd)
|
||||
{
|
||||
i8042_write_data(cmd);
|
||||
|
||||
return i8042_wait_read_ps2() == 0xfa;
|
||||
return i8042_wait_read_ps2() == I8042_KBCMD_ACK;
|
||||
}
|
||||
|
||||
int keyboard_havechar(void)
|
||||
@@ -258,6 +258,7 @@ int keyboard_getchar(void)
|
||||
/* vulcan nerve pinch */
|
||||
if ((modifier & KB_MOD_ALT) && reset_handler)
|
||||
reset_handler();
|
||||
/* fallthrough */
|
||||
default:
|
||||
ret = 0;
|
||||
}
|
||||
@@ -296,7 +297,8 @@ int keyboard_set_layout(char *country)
|
||||
|
||||
static struct console_input_driver cons = {
|
||||
.havekey = keyboard_havechar,
|
||||
.getchar = keyboard_getchar
|
||||
.getchar = keyboard_getchar,
|
||||
.input_type = CONSOLE_INPUT_TYPE_EC,
|
||||
};
|
||||
|
||||
void keyboard_init(void)
|
||||
@@ -315,19 +317,42 @@ void keyboard_init(void)
|
||||
/* Enable first PS/2 port */
|
||||
i8042_cmd(I8042_CMD_EN_KB);
|
||||
|
||||
/* Reset keyboard and self test (keyboard side) */
|
||||
ret = keyboard_cmd(I8042_KBCMD_RESET);
|
||||
if (!ret) {
|
||||
printf("ERROR: Keyboard reset failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set scancode set 1 */
|
||||
ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE);
|
||||
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))
|
||||
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) {
|
||||
printf("ERROR: Keyboard set scancode failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = keyboard_cmd(I8042_SCANCODE_SET_1);
|
||||
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))
|
||||
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) {
|
||||
printf("ERROR: Keyboard scancode set#1 failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set default parameters.
|
||||
* Fix for broken QEMU ps/2 make scancodes.
|
||||
*/
|
||||
ret = keyboard_cmd(0xf6);
|
||||
if (!ret) {
|
||||
printf("ERROR: Keyboard set default params failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable scanning */
|
||||
ret = keyboard_cmd(I8042_KBCMD_EN);
|
||||
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))
|
||||
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) {
|
||||
printf("ERROR: Keyboard enable scanning failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
console_add_input_driver(&cons);
|
||||
}
|
||||
|
@@ -98,7 +98,8 @@ static void serial_hardware_init(int speed, int word_bits,
|
||||
|
||||
static struct console_input_driver consin = {
|
||||
.havekey = &serial_havechar,
|
||||
.getchar = &serial_getchar
|
||||
.getchar = &serial_getchar,
|
||||
.input_type = CONSOLE_INPUT_TYPE_UART,
|
||||
};
|
||||
|
||||
static struct console_output_driver consout = {
|
||||
|
@@ -560,6 +560,7 @@ void serial_console_init(void)
|
||||
|
||||
consin.havekey = serial_havechar;
|
||||
consin.getchar = serial_getchar;
|
||||
consin.input_type = CONSOLE_INPUT_TYPE_UART;
|
||||
|
||||
consout.putchar = serial_putchar;
|
||||
|
||||
|
@@ -352,6 +352,7 @@ void serial_console_init(void)
|
||||
|
||||
consin.havekey = serial_havechar;
|
||||
consin.getchar = serial_getchar;
|
||||
consin.input_type = CONSOLE_INPUT_TYPE_UART;
|
||||
|
||||
consout.putchar = serial_putchar;
|
||||
|
||||
|
555
payloads/libpayload/drivers/serial/qcs405.c
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012, 2014, 2016, 2019, The Linux Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libpayload.h>
|
||||
|
||||
#define UART_DM_CLK_RX_TX_BIT_RATE 0xFF
|
||||
|
||||
enum MSM_BOOT_UART_DM_PARITY_MODE {
|
||||
MSM_BOOT_UART_DM_NO_PARITY,
|
||||
MSM_BOOT_UART_DM_ODD_PARITY,
|
||||
MSM_BOOT_UART_DM_EVEN_PARITY,
|
||||
MSM_BOOT_UART_DM_SPACE_PARITY
|
||||
};
|
||||
|
||||
/* UART Stop Bit Length */
|
||||
enum MSM_BOOT_UART_DM_STOP_BIT_LEN {
|
||||
MSM_BOOT_UART_DM_SBL_9_16,
|
||||
MSM_BOOT_UART_DM_SBL_1,
|
||||
MSM_BOOT_UART_DM_SBL_1_9_16,
|
||||
MSM_BOOT_UART_DM_SBL_2
|
||||
};
|
||||
|
||||
/* UART Bits per Char */
|
||||
enum MSM_BOOT_UART_DM_BITS_PER_CHAR {
|
||||
MSM_BOOT_UART_DM_5_BPS,
|
||||
MSM_BOOT_UART_DM_6_BPS,
|
||||
MSM_BOOT_UART_DM_7_BPS,
|
||||
MSM_BOOT_UART_DM_8_BPS
|
||||
};
|
||||
|
||||
/* 8-N-1 Configuration */
|
||||
#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \
|
||||
(MSM_BOOT_UART_DM_SBL_1 << 2) | \
|
||||
(MSM_BOOT_UART_DM_8_BPS << 4))
|
||||
|
||||
/* UART_DM Registers */
|
||||
|
||||
/* UART Operational Mode Register */
|
||||
#define MSM_BOOT_UART_DM_MR1(base) ((base) + 0x00)
|
||||
#define MSM_BOOT_UART_DM_MR2(base) ((base) + 0x04)
|
||||
#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8)
|
||||
#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7)
|
||||
|
||||
#define PERIPH_BLK_BLSP 1
|
||||
|
||||
/* UART Clock Selection Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0xA0)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0x08)
|
||||
#endif
|
||||
|
||||
/* UART DM TX FIFO Registers - 4 */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x100+(4*(x)))
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x70+(4*(x)))
|
||||
#endif
|
||||
|
||||
/* UART Command Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_CR(base) ((base) + 0xA8)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_CR(base) ((base) + 0x10)
|
||||
#endif
|
||||
#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0)
|
||||
#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1)
|
||||
#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2)
|
||||
#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3)
|
||||
|
||||
/* UART Channel Command */
|
||||
#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4)
|
||||
#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4) << 11)
|
||||
#define MSM_BOOT_UART_DM_CR_CH_CMD(x) \
|
||||
(MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) | MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x))
|
||||
#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0)
|
||||
#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1)
|
||||
#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2)
|
||||
#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4)
|
||||
#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5)
|
||||
#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8)
|
||||
#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9)
|
||||
#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C)
|
||||
#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10)
|
||||
#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14)
|
||||
|
||||
/*UART General Command */
|
||||
#define MSM_UART_DM_CR_GENERAL_CMD(x) ((x) << 8)
|
||||
|
||||
#define MSM_BOOT_UART_DM_GCMD_NULL MSM_UART_DM_CR_GENERAL_CMD(0)
|
||||
#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_UART_DM_CR_GENERAL_CMD(1)
|
||||
#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_UART_DM_CR_GENERAL_CMD(2)
|
||||
#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_UART_DM_CR_GENERAL_CMD(3)
|
||||
#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_UART_DM_CR_GENERAL_CMD(4)
|
||||
#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_UART_DM_CR_GENERAL_CMD(5)
|
||||
#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_UART_DM_CR_GENERAL_CMD(6)
|
||||
|
||||
/* UART Interrupt Mask Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0xB0)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0x14)
|
||||
#endif
|
||||
|
||||
#define MSM_BOOT_UART_DM_TXLEV (1 << 0)
|
||||
#define MSM_BOOT_UART_DM_RXHUNT (1 << 1)
|
||||
#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2)
|
||||
#define MSM_BOOT_UART_DM_RXSTALE (1 << 3)
|
||||
#define MSM_BOOT_UART_DM_RXLEV (1 << 4)
|
||||
#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5)
|
||||
#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6)
|
||||
#define MSM_BOOT_UART_DM_TX_READY (1 << 7)
|
||||
#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8)
|
||||
#define MSM_BOOT_UART_DM_TX_DONE (1 << 9)
|
||||
#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10)
|
||||
#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11)
|
||||
#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12)
|
||||
|
||||
#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \
|
||||
MSM_BOOT_UART_DM_TXLEV | \
|
||||
MSM_BOOT_UART_DM_RXSTALE)
|
||||
|
||||
/* UART Interrupt Programming Register */
|
||||
#define MSM_BOOT_UART_DM_IPR(base) ((base) + 0x18)
|
||||
#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f
|
||||
#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */
|
||||
|
||||
/* UART Transmit/Receive FIFO Watermark Register */
|
||||
#define MSM_BOOT_UART_DM_TFWR(base) ((base) + 0x1C)
|
||||
/* Interrupt is generated when FIFO level is less than or equal to this value */
|
||||
#define MSM_BOOT_UART_DM_TFW_VALUE 0
|
||||
|
||||
#define MSM_BOOT_UART_DM_RFWR(base) ((base) + 0x20)
|
||||
/*Interrupt generated when no of words in RX FIFO is greater than this value */
|
||||
#define MSM_BOOT_UART_DM_RFW_VALUE 0
|
||||
|
||||
/* UART Hunt Character Register */
|
||||
#define MSM_BOOT_UART_DM_HCR(base) ((base) + 0x24)
|
||||
|
||||
/* Used for RX transfer initialization */
|
||||
#define MSM_BOOT_UART_DM_DMRX(base) ((base) + 0x34)
|
||||
|
||||
/* Default DMRX value - any value bigger than FIFO size would be fine */
|
||||
#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220
|
||||
|
||||
/* Register to enable IRDA function */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0xB8)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0x38)
|
||||
#endif
|
||||
|
||||
/* UART Data Mover Enable Register */
|
||||
#define MSM_BOOT_UART_DM_DMEN(base) ((base) + 0x3C)
|
||||
|
||||
/* Number of characters for Transmission */
|
||||
#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base) ((base) + 0x040)
|
||||
|
||||
/* UART RX FIFO Base Address */
|
||||
#define MSM_BOOT_UART_DM_BADR(base) ((base) + 0x44)
|
||||
|
||||
/* UART Status Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x0A4)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x008)
|
||||
#endif
|
||||
#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0)
|
||||
#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1)
|
||||
#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2)
|
||||
#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3)
|
||||
#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4)
|
||||
#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5)
|
||||
#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6)
|
||||
#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7)
|
||||
#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8)
|
||||
|
||||
/* UART Receive FIFO Registers - 4 in numbers */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x140 + (4*(x)))
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x70 + (4*(x)))
|
||||
#endif
|
||||
|
||||
/* UART Masked Interrupt Status Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0xAC)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0x10)
|
||||
#endif
|
||||
|
||||
/* UART Interrupt Status Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0xB4)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0x14)
|
||||
#endif
|
||||
|
||||
/* Number of characters received since the end of last RX transfer */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0xBC)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0x38)
|
||||
#endif
|
||||
|
||||
/* UART TX FIFO Status Register */
|
||||
#define MSM_BOOT_UART_DM_TXFS(base) ((base) + 0x4C)
|
||||
#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6)
|
||||
#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31)
|
||||
#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9)
|
||||
#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13)
|
||||
|
||||
/* UART RX FIFO Status Register */
|
||||
#define MSM_BOOT_UART_DM_RXFS(base) ((base) + 0x50)
|
||||
#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6)
|
||||
#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31)
|
||||
#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9)
|
||||
#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13)
|
||||
|
||||
/* Macros for Common Errors */
|
||||
#define MSM_BOOT_UART_DM_E_FAILURE 1
|
||||
#define MSM_BOOT_UART_DM_E_TIMEOUT 2
|
||||
#define MSM_BOOT_UART_DM_E_INVAL 3
|
||||
#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4
|
||||
#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5
|
||||
|
||||
#define UART1_DM_BASE ((void *)0x078af000)
|
||||
#define UART2_DM_BASE ((void *)0x078b1000)
|
||||
|
||||
enum {
|
||||
BLSP1_UART1,
|
||||
BLSP1_UART2,
|
||||
};
|
||||
|
||||
#define FIFO_DATA_SIZE 4
|
||||
|
||||
struct uart_params_t {
|
||||
void *uart_dm_base;
|
||||
unsigned int blsp_uart;
|
||||
};
|
||||
|
||||
static struct console_input_driver consin = {
|
||||
.havekey = serial_havechar,
|
||||
.getchar = serial_getchar,
|
||||
};
|
||||
|
||||
static struct console_output_driver consout = {
|
||||
.putchar = serial_putchar,
|
||||
};
|
||||
|
||||
static struct uart_params_t uart_board_param = {};
|
||||
|
||||
/**
|
||||
* msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
|
||||
* @uart_dm_base: UART controller base address
|
||||
*/
|
||||
static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
|
||||
{
|
||||
/* Reset receiver */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CMD_RESET_RX);
|
||||
|
||||
/* Enable receiver */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CR_RX_ENABLE);
|
||||
write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_DMRX_DEF_VALUE);
|
||||
|
||||
/* Clear stale event */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
|
||||
|
||||
/* Enable stale event */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int msm_boot_uart_dm_init(void *uart_dm_base);
|
||||
|
||||
static int valid_data = 0;
|
||||
|
||||
static unsigned int word = 0;
|
||||
|
||||
/**
|
||||
* msm_boot_uart_dm_read - reads a word from the RX FIFO.
|
||||
* @data: location where the read data is stored
|
||||
* @count: no of valid data in the FIFO
|
||||
*
|
||||
* Reads a word from the RX FIFO. If no data is available
|
||||
* returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
|
||||
*/
|
||||
static unsigned int
|
||||
msm_boot_uart_dm_read(unsigned int *data, int *count)
|
||||
{
|
||||
static int total_rx_data = 0;
|
||||
static int rx_data_read = 0;
|
||||
void *base;
|
||||
uint32_t status_reg;
|
||||
|
||||
base = uart_board_param.uart_dm_base;
|
||||
|
||||
if (data == NULL)
|
||||
return MSM_BOOT_UART_DM_E_INVAL;
|
||||
|
||||
status_reg = read32(MSM_BOOT_UART_DM_MISR(base));
|
||||
|
||||
/* Check for DM_RXSTALE for RX transfer to finish */
|
||||
while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
|
||||
status_reg = read32(MSM_BOOT_UART_DM_MISR(base));
|
||||
return MSM_BOOT_UART_DM_E_RX_NOT_READY;
|
||||
}
|
||||
|
||||
/* Check for Overrun error. We'll just reset Error Status */
|
||||
if (read32(MSM_BOOT_UART_DM_SR(base)) &
|
||||
MSM_BOOT_UART_DM_SR_UART_OVERRUN) {
|
||||
write32(MSM_BOOT_UART_DM_CR(base),
|
||||
MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
|
||||
total_rx_data = rx_data_read = 0;
|
||||
msm_boot_uart_dm_init(base);
|
||||
return MSM_BOOT_UART_DM_E_RX_NOT_READY;
|
||||
}
|
||||
|
||||
/* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
|
||||
if (total_rx_data == 0)
|
||||
total_rx_data = read32(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
|
||||
|
||||
/* Data available in FIFO; read a word. */
|
||||
*data = read32(MSM_BOOT_UART_DM_RF(base, 0));
|
||||
|
||||
/* increment the total count of chars we've read so far */
|
||||
rx_data_read += FIFO_DATA_SIZE;
|
||||
|
||||
/* actual count of valid data in word */
|
||||
*count = ((total_rx_data < rx_data_read) ?
|
||||
(FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
|
||||
FIFO_DATA_SIZE);
|
||||
|
||||
/* If there are still data left in FIFO we'll read them before
|
||||
* initializing RX Transfer again
|
||||
*/
|
||||
if (rx_data_read < total_rx_data)
|
||||
return 0;
|
||||
|
||||
msm_boot_uart_dm_init_rx_transfer(base);
|
||||
total_rx_data = rx_data_read = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void serial_putchar(unsigned int data)
|
||||
{
|
||||
int num_of_chars = 1;
|
||||
void *base = uart_board_param.uart_dm_base;
|
||||
|
||||
if (data == '\n') {
|
||||
num_of_chars++;
|
||||
data = (data << 8) | '\r';
|
||||
}
|
||||
|
||||
/* Wait until transmit FIFO is empty. */
|
||||
while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
|
||||
MSM_BOOT_UART_DM_SR_TXEMT))
|
||||
udelay(1);
|
||||
/*
|
||||
* TX FIFO is ready to accept new character(s). First write number of
|
||||
* characters to be transmitted.
|
||||
*/
|
||||
write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
|
||||
|
||||
/* And now write the character(s) */
|
||||
write32(MSM_BOOT_UART_DM_TF(base, 0), data);
|
||||
}
|
||||
|
||||
/*
|
||||
* msm_boot_uart_dm_reset - resets UART controller
|
||||
* @base: UART controller base address
|
||||
*/
|
||||
static unsigned int msm_boot_uart_dm_reset(void *base)
|
||||
{
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX);
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX);
|
||||
write32(MSM_BOOT_UART_DM_CR(base),
|
||||
MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR);
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* msm_boot_uart_dm_init - initilaizes UART controller
|
||||
* @uart_dm_base: UART controller base address
|
||||
*/
|
||||
unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
|
||||
{
|
||||
/* Configure UART mode registers MR1 and MR2 */
|
||||
/* Hardware flow control isn't supported */
|
||||
write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
|
||||
|
||||
/* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
|
||||
write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_8_N_1_MODE);
|
||||
|
||||
/* Configure Interrupt Mask register IMR */
|
||||
write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_IMR_ENABLED);
|
||||
|
||||
/*
|
||||
* Configure Tx and Rx watermarks configuration registers
|
||||
* TX watermark value is set to 0 - interrupt is generated when
|
||||
* FIFO level is less than or equal to 0
|
||||
*/
|
||||
write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_TFW_VALUE);
|
||||
|
||||
/* RX watermark value */
|
||||
write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_RFW_VALUE);
|
||||
|
||||
/* Configure Interrupt Programming Register */
|
||||
/* Set initial Stale timeout value */
|
||||
write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB);
|
||||
|
||||
/* Configure IRDA if required */
|
||||
/* Disabling IRDA mode */
|
||||
write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
|
||||
|
||||
/* Configure hunt character value in HCR register */
|
||||
/* Keep it in reset state */
|
||||
write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
|
||||
|
||||
/*
|
||||
* Configure Rx FIFO base address
|
||||
* Both TX/RX shares same SRAM and default is half-n-half.
|
||||
* Sticking with default value now.
|
||||
* As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
|
||||
* We have found RAM_ADDR_WIDTH = 0x7f
|
||||
*/
|
||||
|
||||
/* Issue soft reset command */
|
||||
msm_boot_uart_dm_reset(uart_dm_base);
|
||||
|
||||
/* Enable/Disable Rx/Tx DM interfaces */
|
||||
/* Data Mover not currently utilized. */
|
||||
write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
|
||||
|
||||
/* Enable transmitter */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CR_TX_ENABLE);
|
||||
|
||||
/* Initialize Receive Path */
|
||||
msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* serial_havechar - checks if data available for reading
|
||||
*
|
||||
* Returns 1 if data available, 0 otherwise
|
||||
*/
|
||||
int serial_havechar(void)
|
||||
{
|
||||
/* Return if data is already read */
|
||||
if (valid_data)
|
||||
return 1;
|
||||
|
||||
/* Read data from the FIFO */
|
||||
if (msm_boot_uart_dm_read(&word, &valid_data) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* qcs405_serial_getc - reads a character
|
||||
*
|
||||
* Returns the character read from serial port.
|
||||
*/
|
||||
int serial_getchar(void)
|
||||
{
|
||||
uint8_t byte;
|
||||
|
||||
while (!serial_havechar())
|
||||
; /* wait for incoming data */
|
||||
|
||||
byte = (uint8_t)(word & 0xff);
|
||||
word = word >> 8;
|
||||
valid_data--;
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
/* For simplicity sake let's rely on coreboot initalizing the UART. */
|
||||
void serial_console_init(void)
|
||||
{
|
||||
struct cb_serial *sc_ptr = lib_sysinfo.serial;
|
||||
|
||||
if (!sc_ptr)
|
||||
return;
|
||||
|
||||
uart_board_param.uart_dm_base = (void *)(uintptr_t)sc_ptr->baseaddr;
|
||||
|
||||
/* TODO: We should rely on coreboot init. */
|
||||
msm_boot_uart_dm_init(uart_board_param.uart_dm_base);
|
||||
|
||||
console_add_output_driver(&consout);
|
||||
console_add_input_driver(&consin);
|
||||
}
|
@@ -84,7 +84,8 @@ static struct console_output_driver s5p_serial_output =
|
||||
static struct console_input_driver s5p_serial_input =
|
||||
{
|
||||
.havekey = &serial_havechar,
|
||||
.getchar = &serial_getchar
|
||||
.getchar = &serial_getchar,
|
||||
.input_type = CONSOLE_INPUT_TYPE_UART,
|
||||
};
|
||||
|
||||
void serial_init(void)
|
||||
|
@@ -108,6 +108,9 @@ static int ahci_dev_init(hba_ctrl_t *const ctrl,
|
||||
|
||||
const int ncs = HBA_CAPS_DECODE_NCS(ctrl->caps);
|
||||
|
||||
if (ahci_cmdengine_stop(port))
|
||||
return 1;
|
||||
|
||||
/* Allocate command list, one command table and received FIS. */
|
||||
cmd_t *const cmdlist = memalign(1024, ncs * sizeof(cmd_t));
|
||||
cmdtable_t *const cmdtable = memalign(128, sizeof(cmdtable_t));
|
||||
@@ -121,12 +124,10 @@ static int ahci_dev_init(hba_ctrl_t *const ctrl,
|
||||
memset((void *)rcvd_fis, '\0', sizeof(*rcvd_fis));
|
||||
|
||||
/* Set command list base and received FIS base. */
|
||||
if (ahci_cmdengine_stop(port))
|
||||
return 1;
|
||||
port->cmdlist_base = virt_to_phys(cmdlist);
|
||||
port->frameinfo_base = virt_to_phys(rcvd_fis);
|
||||
if (ahci_cmdengine_start(port))
|
||||
return 1;
|
||||
goto _cleanup_ret;
|
||||
/* Put port into active state. */
|
||||
port->cmd_stat |= HBA_PxCMD_ICC_ACTIVE;
|
||||
|
||||
@@ -178,6 +179,8 @@ _cleanup_ret:
|
||||
/* Clean up (not reached for initialized devices). */
|
||||
if (dev)
|
||||
free(dev);
|
||||
/* Only free if stopping succeeds, since otherwise the controller may
|
||||
still use the resources for DMA. */
|
||||
if (!ahci_cmdengine_stop(port)) {
|
||||
port->cmdlist_base = 0;
|
||||
port->frameinfo_base = 0;
|
||||
|
@@ -287,6 +287,21 @@ struct cb_macs {
|
||||
struct mac_address mac_addrs[0];
|
||||
};
|
||||
|
||||
#define CB_TAG_MMC_INFO 0x0035
|
||||
struct cb_mmc_info {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
/*
|
||||
* Passes the early mmc status to payload to indicate if firmware
|
||||
* successfully sent CMD0, CMD1 to the card or not. In case of
|
||||
* success, the payload can skip the first step of the initialization
|
||||
* sequence which is to send CMD0, and instead start by sending CMD1
|
||||
* as described in Jedec Standard JESD83-B1 section 6.4.3.
|
||||
* passes 1 on success
|
||||
*/
|
||||
int32_t early_cmd1_status;
|
||||
};
|
||||
|
||||
#define CB_TAG_SERIALNO 0x002a
|
||||
#define CB_MAX_SERIALNO_LENGTH 32
|
||||
|
||||
|
@@ -350,6 +350,9 @@ int set_option_from_string(const struct nvram_accessor *nvram, struct cb_cmos_op
|
||||
typedef enum {
|
||||
CONSOLE_INPUT_TYPE_UNKNOWN = 0,
|
||||
CONSOLE_INPUT_TYPE_USB,
|
||||
CONSOLE_INPUT_TYPE_EC,
|
||||
CONSOLE_INPUT_TYPE_UART,
|
||||
CONSOLE_INPUT_TYPE_GPIO,
|
||||
} console_input_type;
|
||||
|
||||
void console_init(void);
|
||||
@@ -431,9 +434,12 @@ void hexdump(const void *memory, size_t length);
|
||||
void fatal(const char *msg) __attribute__((noreturn));
|
||||
|
||||
/* Count Leading Zeroes: clz(0) == 32, clz(0xf) == 28, clz(1 << 31) == 0 */
|
||||
static inline int clz(u32 x) { return x ? __builtin_clz(x) : sizeof(x) * 8; }
|
||||
static inline int clz(u32 x)
|
||||
{
|
||||
return x ? __builtin_clz(x) : (int)sizeof(x) * 8;
|
||||
}
|
||||
/* Integer binary logarithm (rounding down): log2(0) == -1, log2(5) == 2 */
|
||||
static inline int log2(u32 x) { return sizeof(x) * 8 - clz(x) - 1; }
|
||||
static inline int log2(u32 x) { return (int)sizeof(x) * 8 - clz(x) - 1; }
|
||||
/* Find First Set: __ffs(0xf) == 0, __ffs(0) == -1, __ffs(1 << 31) == 31 */
|
||||
static inline int __ffs(u32 x) { return log2(x & (u32)(-(s32)x)); }
|
||||
/** @} */
|
||||
|
@@ -129,6 +129,7 @@ struct sysinfo_t {
|
||||
uint64_t mtc_start;
|
||||
uint32_t mtc_size;
|
||||
void *chromeos_vpd;
|
||||
int mmc_early_wake_status;
|
||||
};
|
||||
|
||||
extern struct sysinfo_t lib_sysinfo;
|
||||
|
@@ -102,6 +102,13 @@ static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
|
||||
info->vbnv_size = vbnv->range_size;
|
||||
}
|
||||
|
||||
static void cb_parse_mmc_info(unsigned char *ptr, struct sysinfo_t *info)
|
||||
{
|
||||
struct cb_mmc_info *mmc_info = (struct cb_mmc_info *)ptr;
|
||||
|
||||
info->mmc_early_wake_status = mmc_info->early_cmd1_status;
|
||||
}
|
||||
|
||||
static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
|
||||
{
|
||||
int i;
|
||||
@@ -399,6 +406,9 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
|
||||
case CB_TAG_SPI_FLASH:
|
||||
cb_parse_spi_flash(ptr, info);
|
||||
break;
|
||||
case CB_TAG_MMC_INFO:
|
||||
cb_parse_mmc_info(ptr, info);
|
||||
break;
|
||||
case CB_TAG_MTC:
|
||||
cb_parse_mtc(ptr, info);
|
||||
break;
|
||||
|
40
src/Kconfig
@@ -277,6 +277,21 @@ config BOOTSPLASH_FILE
|
||||
The path and filename of the file to use as graphical bootsplash
|
||||
screen. The file format has to be jpg.
|
||||
|
||||
config RAMPAYLOAD
|
||||
bool "Enable coreboot flow without executing ramstage"
|
||||
default n
|
||||
depends on ARCH_X86
|
||||
help
|
||||
If this option is enabled, coreboot flow will skip ramstage
|
||||
loading and execution of ramstage to load payload.
|
||||
|
||||
Instead it is expected to load payload from postcar stage itself.
|
||||
|
||||
In this flow coreboot will perform basic x86 initialization
|
||||
(DRAM resource allocation), MTRR programming,
|
||||
Skip PCI enumeration logic and only allocate BAR for fixed devices
|
||||
(bootable devices, TPM over GSPI).
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Mainboard"
|
||||
@@ -1143,31 +1158,6 @@ config GENERIC_GPIO_LIB
|
||||
implies configurability usually found on SoCs, particularly the
|
||||
ability to control internal pull resistors.
|
||||
|
||||
config GENERIC_SPD_BIN
|
||||
bool
|
||||
help
|
||||
If enabled, add support for adding spd.hex files in cbfs as spd.bin
|
||||
and locating it runtime to load SPD. Additionally provide provision to
|
||||
fetch SPD over SMBus.
|
||||
|
||||
config DIMM_MAX
|
||||
int
|
||||
default 4
|
||||
help
|
||||
Total number of memory DIMM slots available on motherboard.
|
||||
It is multiplication of number of channel to number of DIMMs per
|
||||
channel
|
||||
|
||||
config DIMM_SPD_SIZE
|
||||
int
|
||||
default 256
|
||||
help
|
||||
Total SPD size that will be used for DIMM.
|
||||
Ex: DDR3 256, DDR4 512.
|
||||
|
||||
config SPD_READ_BY_WORD
|
||||
bool
|
||||
|
||||
config BOOTBLOCK_CUSTOM
|
||||
# To be selected by arch, SoC or mainboard if it does not want use the normal
|
||||
# src/lib/bootblock.c#main() C entry point.
|
||||
|
@@ -38,7 +38,6 @@ static void run_payload(struct prog *prog)
|
||||
void arch_prog_run(struct prog *prog)
|
||||
{
|
||||
void (*doit)(void *);
|
||||
void *arg;
|
||||
|
||||
if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {
|
||||
run_payload(prog);
|
||||
@@ -46,7 +45,6 @@ void arch_prog_run(struct prog *prog)
|
||||
}
|
||||
|
||||
doit = prog_entry(prog);
|
||||
arg = prog_entry_arg(prog);
|
||||
|
||||
doit(prog_entry_arg(prog));
|
||||
}
|
||||
|
@@ -24,8 +24,8 @@ config ARCH_RISCV_M
|
||||
# one implementation that will not have it due
|
||||
# to security concerns.
|
||||
bool
|
||||
default n if ARCH_RISCV_M_DISABLED
|
||||
default y
|
||||
default y if ARCH_RISCV && !ARCH_RISCV_M_DISABLED
|
||||
default n
|
||||
|
||||
config ARCH_RISCV_S
|
||||
# S (supervisor) mode is for kernels. It is optional.
|
||||
|
@@ -193,7 +193,7 @@ verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S
|
||||
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
|
||||
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
|
||||
|
||||
verstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c
|
||||
verstage-y += cpu_common.c
|
||||
verstage-y += memset.c
|
||||
verstage-y += memcpy.c
|
||||
verstage-y += memmove.c
|
||||
@@ -230,7 +230,7 @@ romstage-y += boot.c
|
||||
romstage-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += gdt_init.S
|
||||
romstage-y += cbmem.c
|
||||
romstage-y += cbfs_and_run.c
|
||||
romstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c
|
||||
romstage-y += cpu_common.c
|
||||
romstage-$(CONFIG_EARLY_EBDA_INIT) += ebda.c
|
||||
romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
|
||||
romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
|
||||
|
@@ -218,6 +218,9 @@ void acpi_create_madt(acpi_madt_t *madt)
|
||||
|
||||
memset((void *)madt, 0, sizeof(acpi_madt_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "APIC", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -248,6 +251,9 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg)
|
||||
|
||||
memset((void *)mcfg, 0, sizeof(acpi_mcfg_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "MCFG", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -302,6 +308,9 @@ static void acpi_create_tcpa(acpi_tcpa_t *tcpa)
|
||||
if (!lasa)
|
||||
return;
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "TCPA", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -361,6 +370,9 @@ static void acpi_create_tpm2(acpi_tpm2_t *tpm2)
|
||||
if (!lasa)
|
||||
tpm2_log_len = 0;
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "TPM2", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -481,6 +493,9 @@ void acpi_create_srat(acpi_srat_t *srat,
|
||||
|
||||
memset((void *)srat, 0, sizeof(acpi_srat_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "SRAT", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -508,6 +523,9 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
|
||||
|
||||
memset((void *)dmar, 0, sizeof(acpi_dmar_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "DMAR", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -669,6 +687,9 @@ void acpi_create_slit(acpi_slit_t *slit,
|
||||
|
||||
memset((void *)slit, 0, sizeof(acpi_slit_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "SLIT", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -694,6 +715,9 @@ void acpi_create_hpet(acpi_hpet_t *hpet)
|
||||
|
||||
memset((void *)hpet, 0, sizeof(acpi_hpet_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "HPET", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -728,6 +752,9 @@ void acpi_create_vfct(struct device *device,
|
||||
|
||||
memset((void *)vfct, 0, sizeof(struct acpi_vfct));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "VFCT", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -754,6 +781,9 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs,
|
||||
|
||||
memset((void *)ivrs, 0, sizeof(acpi_ivrs_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "IVRS", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -807,6 +837,10 @@ void acpi_create_dbg2(acpi_dbg2_header_t *dbg2,
|
||||
current = (uintptr_t)dbg2;
|
||||
memset(dbg2, 0, sizeof(acpi_dbg2_header_t));
|
||||
header = &(dbg2->header);
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
header->revision = get_acpi_table_revision(DBG2);
|
||||
memcpy(header->signature, "DBG2", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
@@ -926,6 +960,9 @@ static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
|
||||
{
|
||||
acpi_header_t *header = &(rsdt->header);
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "RSDT", 4);
|
||||
memcpy(header->oem_id, oem_id, 6);
|
||||
@@ -946,6 +983,9 @@ static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id)
|
||||
{
|
||||
acpi_header_t *header = &(xsdt->header);
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
/* Fill out header fields. */
|
||||
memcpy(header->signature, "XSDT", 4);
|
||||
memcpy(header->oem_id, oem_id, 6);
|
||||
@@ -1046,7 +1086,8 @@ unsigned long acpi_create_hest_error_source(acpi_hest_t *hest,
|
||||
|
||||
memcpy(pos, data, data_len);
|
||||
len += data_len;
|
||||
header->length += len;
|
||||
if (header)
|
||||
header->length += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -1059,6 +1100,9 @@ void acpi_write_hest(acpi_hest_t *hest,
|
||||
|
||||
memset(hest, 0, sizeof(acpi_hest_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
memcpy(header->signature, "HEST", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
@@ -1080,6 +1124,9 @@ void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length)
|
||||
|
||||
memset(bert, 0, sizeof(acpi_bert_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
memcpy(header->signature, "BERT", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
@@ -1101,6 +1148,10 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
|
||||
acpi_header_t *header = &(fadt->header);
|
||||
|
||||
memset((void *) fadt, 0, sizeof(acpi_fadt_t));
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
memcpy(header->signature, "FACP", 4);
|
||||
header->length = sizeof(acpi_fadt_t);
|
||||
header->revision = get_acpi_table_revision(FADT);
|
||||
|
@@ -740,6 +740,9 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp,
|
||||
const struct acpi_dp *prop;
|
||||
size_t i, properties_added = 0;
|
||||
|
||||
if (!dp || !property_list)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < property_count; i++) {
|
||||
prop = &property_list[i];
|
||||
|
||||
@@ -775,6 +778,9 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp,
|
||||
struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
|
||||
uint64_t value)
|
||||
{
|
||||
if (!dp)
|
||||
return NULL;
|
||||
|
||||
struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_INTEGER, name);
|
||||
|
||||
if (new)
|
||||
@@ -786,6 +792,9 @@ struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
|
||||
struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
|
||||
const char *string)
|
||||
{
|
||||
if (!dp)
|
||||
return NULL;
|
||||
|
||||
struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_STRING, name);
|
||||
|
||||
if (new)
|
||||
@@ -797,6 +806,9 @@ struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
|
||||
struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name,
|
||||
const char *reference)
|
||||
{
|
||||
if (!dp)
|
||||
return NULL;
|
||||
|
||||
struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_REFERENCE, name);
|
||||
|
||||
if (new)
|
||||
@@ -810,7 +822,7 @@ struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
|
||||
{
|
||||
struct acpi_dp *new;
|
||||
|
||||
if (!child || child->type != ACPI_DP_TYPE_TABLE)
|
||||
if (!dp || !child || child->type != ACPI_DP_TYPE_TABLE)
|
||||
return NULL;
|
||||
|
||||
new = acpi_dp_new(dp, ACPI_DP_TYPE_CHILD, name);
|
||||
@@ -826,7 +838,7 @@ struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array)
|
||||
{
|
||||
struct acpi_dp *new;
|
||||
|
||||
if (!array || array->type != ACPI_DP_TYPE_TABLE)
|
||||
if (!dp || !array || array->type != ACPI_DP_TYPE_TABLE)
|
||||
return NULL;
|
||||
|
||||
new = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, array->name);
|
||||
@@ -842,7 +854,7 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
|
||||
struct acpi_dp *dp_array;
|
||||
int i;
|
||||
|
||||
if (len <= 0)
|
||||
if (!dp || len <= 0)
|
||||
return NULL;
|
||||
|
||||
dp_array = acpi_dp_new_table(name);
|
||||
@@ -862,6 +874,9 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
|
||||
const char *ref, int index, int pin,
|
||||
int active_low)
|
||||
{
|
||||
if (!dp)
|
||||
return NULL;
|
||||
|
||||
struct acpi_dp *gpio = acpi_dp_new_table(name);
|
||||
|
||||
if (!gpio)
|
||||
|
@@ -91,9 +91,7 @@
|
||||
_car_global_end = .;
|
||||
_car_relocatable_data_end = .;
|
||||
|
||||
#if (CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) || \
|
||||
CONFIG(NORTHBRIDGE_INTEL_IVYBRIDGE)) && \
|
||||
!CONFIG(USE_NATIVE_RAMINIT)
|
||||
#if CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) && !CONFIG(USE_NATIVE_RAMINIT)
|
||||
. = ABSOLUTE(0xff7e1000);
|
||||
_mrc_pool = .;
|
||||
. += 0x5000;
|
||||
|
@@ -219,6 +219,35 @@ static void set_cpu_ops(struct device *cpu)
|
||||
cpu->ops = driver ? driver->ops : NULL;
|
||||
}
|
||||
|
||||
/* Keep track of default apic ids for SMM. */
|
||||
static int cpus_default_apic_id[CONFIG_MAX_CPUS];
|
||||
|
||||
/*
|
||||
* When CPUID executes with EAX set to 1, additional processor identification
|
||||
* information is returned to EBX register:
|
||||
* Default APIC ID: EBX[31-24] - this number is the 8 bit ID that is assigned
|
||||
* to the local APIC on the processor during power on.
|
||||
*/
|
||||
static int initial_lapicid(void)
|
||||
{
|
||||
return cpuid_ebx(1) >> 24;
|
||||
}
|
||||
|
||||
/* Function to keep track of cpu default apic_id */
|
||||
void cpu_add_map_entry(unsigned int index)
|
||||
{
|
||||
cpus_default_apic_id[index] = initial_lapicid();
|
||||
}
|
||||
|
||||
/* Returns default APIC id based on logical_cpu number or < 0 on failure. */
|
||||
int cpu_get_apic_id(int logical_cpu)
|
||||
{
|
||||
if (logical_cpu >= CONFIG_MAX_CPUS || logical_cpu < 0)
|
||||
return -1;
|
||||
|
||||
return cpus_default_apic_id[logical_cpu];
|
||||
}
|
||||
|
||||
void cpu_initialize(unsigned int index)
|
||||
{
|
||||
/* Because we busy wait at the printk spinlock.
|
||||
@@ -308,3 +337,27 @@ void arch_bootstate_coreboot_exit(void)
|
||||
/* APs are waiting for work. Last thing to do is park them. */
|
||||
mp_park_aps();
|
||||
}
|
||||
|
||||
/*
|
||||
* Previously cpu_index() implementation assumes that cpu_index()
|
||||
* function will always getting called from coreboot context
|
||||
* (ESP stack pointer will always refer to coreboot).
|
||||
*
|
||||
* But with FSP_USES_MP_SERVICES_PPI implementation in coreboot this
|
||||
* assumption might not be true, where FSP context (stack pointer refers
|
||||
* to FSP) will request to get cpu_index().
|
||||
*
|
||||
* Hence new logic to use cpuid to fetch lapic id and matches with
|
||||
* cpus_default_apic_id[] variable to return correct cpu_index().
|
||||
*/
|
||||
int cpu_index(void)
|
||||
{
|
||||
int i;
|
||||
int lapic_id = initial_lapicid();
|
||||
|
||||
for (i = 0; i < CONFIG_MAX_CPUS; i++) {
|
||||
if (cpu_get_apic_id(i) == lapic_id)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@@ -502,7 +502,7 @@ void x86_exception(struct eregs *info)
|
||||
}
|
||||
#else /* !CONFIG_GDB_STUB */
|
||||
#define MDUMP_SIZE 0x80
|
||||
unsigned int logical_processor = 0;
|
||||
int logical_processor = 0;
|
||||
|
||||
#if ENV_RAMSTAGE
|
||||
logical_processor = cpu_index();
|
||||
|
@@ -56,11 +56,11 @@
|
||||
#define OEM_ID "COREv4" /* Must be exactly 6 bytes long! */
|
||||
|
||||
#if !defined(__ASSEMBLER__) && !defined(__ACPI__) && !defined(__ROMCC__)
|
||||
#include <stdint.h>
|
||||
#include <commonlib/helpers.h>
|
||||
#include <device/device.h>
|
||||
#include <uuid.h>
|
||||
#include <cper.h>
|
||||
#include <types.h>
|
||||
|
||||
#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
|
||||
#define ASLC "CORE" /* Must be exactly 4 bytes long! */
|
||||
@@ -838,14 +838,12 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs,
|
||||
unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
|
||||
unsigned long current));
|
||||
|
||||
#if ENV_RAMSTAGE && !defined(__SIMPLE_DEVICE__)
|
||||
void acpi_create_hpet(acpi_hpet_t *hpet);
|
||||
unsigned long acpi_write_hpet(struct device *device, unsigned long start,
|
||||
acpi_rsdp_t *rsdp);
|
||||
|
||||
/* cpu/intel/speedstep/acpi.c */
|
||||
void generate_cpu_entries(struct device *device);
|
||||
#endif
|
||||
|
||||
void acpi_create_mcfg(acpi_mcfg_t *mcfg);
|
||||
|
||||
|
@@ -261,13 +261,6 @@ static inline struct cpu_info *cpu_info(void)
|
||||
);
|
||||
return ci;
|
||||
}
|
||||
|
||||
static inline unsigned long cpu_index(void)
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
ci = cpu_info();
|
||||
return ci->index;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ROMCC__ // romcc is segfaulting in some cases
|
||||
@@ -374,4 +367,18 @@ uint32_t cpu_get_feature_flags_ecx(void);
|
||||
*/
|
||||
uint32_t cpu_get_feature_flags_edx(void);
|
||||
|
||||
/*
|
||||
* Previously cpu_index() implementation assumes that cpu_index()
|
||||
* function will always getting called from coreboot context
|
||||
* (ESP stack pointer will always refer to coreboot).
|
||||
*
|
||||
* But with FSP_USES_MP_SERVICES_PPI implementation in coreboot this
|
||||
* assumption might not be true, where FSP context (stack pointer refers
|
||||
* to FSP) will request to get cpu_index().
|
||||
*
|
||||
* Hence new logic to use cpuid to fetch lapic id and matches with
|
||||
* cpus_default_apic_id[] variable to return correct cpu_index().
|
||||
*/
|
||||
int cpu_index(void);
|
||||
|
||||
#endif /* ARCH_CPU_H */
|
||||
|
@@ -141,13 +141,16 @@ static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
|
||||
};
|
||||
|
||||
if (prog_locate(prog))
|
||||
die("Failed to locate after CAR program.\n");
|
||||
die_with_post_code(POST_INVALID_ROM,
|
||||
"Failed to locate after CAR program.\n");
|
||||
if (rmodule_stage_load(&rsl))
|
||||
die("Failed to load after CAR program.\n");
|
||||
die_with_post_code(POST_INVALID_ROM,
|
||||
"Failed to load after CAR program.\n");
|
||||
|
||||
/* Set the stack pointer within parameters of the program loaded. */
|
||||
if (rsl.params == NULL)
|
||||
die("No parameters found in after CAR program.\n");
|
||||
die_with_post_code(POST_INVALID_ROM,
|
||||
"No parameters found in after CAR program.\n");
|
||||
|
||||
finalize_load(rsl.params, pcf->stack);
|
||||
|
||||
|
@@ -30,6 +30,9 @@
|
||||
#include <memory_info.h>
|
||||
#include <spd.h>
|
||||
#include <cbmem.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <device/pci.h>
|
||||
#if CONFIG(CHROMEOS)
|
||||
#include <vendorcode/google/chromeos/gnvs.h>
|
||||
#endif
|
||||
@@ -50,6 +53,41 @@ static u8 smbios_checksum(u8 *p, u32 length)
|
||||
return -ret;
|
||||
}
|
||||
|
||||
/* Get the device type 41 from the dev struct */
|
||||
static u8 smbios_get_device_type_from_dev(struct device *dev)
|
||||
{
|
||||
u16 pci_basesubclass = (dev->class >> 8) & 0xFFFF;
|
||||
|
||||
switch (pci_basesubclass) {
|
||||
case PCI_CLASS_NOT_DEFINED:
|
||||
return SMBIOS_DEVICE_TYPE_OTHER;
|
||||
case PCI_CLASS_DISPLAY_VGA:
|
||||
case PCI_CLASS_DISPLAY_XGA:
|
||||
case PCI_CLASS_DISPLAY_3D:
|
||||
case PCI_CLASS_DISPLAY_OTHER:
|
||||
return SMBIOS_DEVICE_TYPE_VIDEO;
|
||||
case PCI_CLASS_STORAGE_SCSI:
|
||||
return SMBIOS_DEVICE_TYPE_SCSI;
|
||||
case PCI_CLASS_NETWORK_ETHERNET:
|
||||
return SMBIOS_DEVICE_TYPE_ETHERNET;
|
||||
case PCI_CLASS_NETWORK_TOKEN_RING:
|
||||
return SMBIOS_DEVICE_TYPE_TOKEN_RING;
|
||||
case PCI_CLASS_MULTIMEDIA_VIDEO:
|
||||
case PCI_CLASS_MULTIMEDIA_AUDIO:
|
||||
case PCI_CLASS_MULTIMEDIA_PHONE:
|
||||
case PCI_CLASS_MULTIMEDIA_OTHER:
|
||||
return SMBIOS_DEVICE_TYPE_SOUND;
|
||||
case PCI_CLASS_STORAGE_ATA:
|
||||
return SMBIOS_DEVICE_TYPE_PATA;
|
||||
case PCI_CLASS_STORAGE_SATA:
|
||||
return SMBIOS_DEVICE_TYPE_SATA;
|
||||
case PCI_CLASS_STORAGE_SAS:
|
||||
return SMBIOS_DEVICE_TYPE_SAS;
|
||||
default:
|
||||
return SMBIOS_DEVICE_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int smbios_add_string(u8 *start, const char *str)
|
||||
{
|
||||
@@ -140,7 +178,7 @@ void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id,
|
||||
struct smbios_type17 *t)
|
||||
{
|
||||
switch (mod_id) {
|
||||
case 0x2c80:
|
||||
case 0x9b85:
|
||||
t->manufacturer = smbios_add_string(t->eos,
|
||||
"Crucial");
|
||||
break;
|
||||
@@ -172,9 +210,9 @@ void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id,
|
||||
t->manufacturer = smbios_add_string(t->eos,
|
||||
"Hynix/Hyundai");
|
||||
break;
|
||||
case 0xb502:
|
||||
case 0x3486:
|
||||
t->manufacturer = smbios_add_string(t->eos,
|
||||
"SuperTalent");
|
||||
"Super Talent");
|
||||
break;
|
||||
case 0xcd04:
|
||||
t->manufacturer = smbios_add_string(t->eos,
|
||||
@@ -188,7 +226,7 @@ void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id,
|
||||
t->manufacturer = smbios_add_string(t->eos,
|
||||
"Elpida");
|
||||
break;
|
||||
case 0xff2c:
|
||||
case 0x2c80:
|
||||
t->manufacturer = smbios_add_string(t->eos,
|
||||
"Micron");
|
||||
break;
|
||||
@@ -962,7 +1000,7 @@ int smbios_write_type38(unsigned long *current, int *handle,
|
||||
|
||||
int smbios_write_type41(unsigned long *current, int *handle,
|
||||
const char *name, u8 instance, u16 segment,
|
||||
u8 bus, u8 device, u8 function)
|
||||
u8 bus, u8 device, u8 function, u8 device_type)
|
||||
{
|
||||
struct smbios_type41 *t = (struct smbios_type41 *)*current;
|
||||
int len = sizeof(struct smbios_type41);
|
||||
@@ -972,7 +1010,7 @@ int smbios_write_type41(unsigned long *current, int *handle,
|
||||
t->handle = *handle;
|
||||
t->length = len - 2;
|
||||
t->reference_designation = smbios_add_string(t->eos, name);
|
||||
t->device_type = SMBIOS_DEVICE_TYPE_OTHER;
|
||||
t->device_type = device_type;
|
||||
t->device_status = 1;
|
||||
t->device_type_instance = instance;
|
||||
t->segment_group_number = segment;
|
||||
@@ -999,6 +1037,38 @@ static int smbios_write_type127(unsigned long *current, int handle)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Generate Type41 entries from devicetree */
|
||||
static int smbios_walk_device_tree_type41(struct device *dev, int *handle,
|
||||
unsigned long *current)
|
||||
{
|
||||
static u8 type41_inst_cnt[SMBIOS_DEVICE_TYPE_COUNT + 1] = {};
|
||||
|
||||
if (dev->path.type != DEVICE_PATH_PCI)
|
||||
return 0;
|
||||
if (!dev->on_mainboard)
|
||||
return 0;
|
||||
|
||||
u8 device_type = smbios_get_device_type_from_dev(dev);
|
||||
|
||||
if (device_type == SMBIOS_DEVICE_TYPE_OTHER ||
|
||||
device_type == SMBIOS_DEVICE_TYPE_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
if (device_type > SMBIOS_DEVICE_TYPE_COUNT)
|
||||
return 0;
|
||||
|
||||
const char *name = get_pci_subclass_name(dev);
|
||||
|
||||
return smbios_write_type41(current, handle,
|
||||
name, // name
|
||||
type41_inst_cnt[device_type]++, // inst
|
||||
0, // segment
|
||||
dev->bus->secondary, //bus
|
||||
PCI_SLOT(dev->path.pci.devfn), // device
|
||||
PCI_FUNC(dev->path.pci.devfn), // func
|
||||
device_type);
|
||||
}
|
||||
|
||||
/* Generate Type9 entries from devicetree */
|
||||
static int smbios_walk_device_tree_type9(struct device *dev, int *handle,
|
||||
unsigned long *current)
|
||||
@@ -1062,6 +1132,7 @@ static int smbios_walk_device_tree(struct device *tree, int *handle,
|
||||
len += dev->ops->get_smbios_data(dev, handle, current);
|
||||
}
|
||||
len += smbios_walk_device_tree_type9(dev, handle, current);
|
||||
len += smbios_walk_device_tree_type41(dev, handle, current);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#define CBMEM_ID_IMD_SMALL 0x53a11439
|
||||
#define CBMEM_ID_MEMINFO 0x494D454D
|
||||
#define CBMEM_ID_MMA_DATA 0x4D4D4144
|
||||
#define CBMEM_ID_MMC_STATUS 0x4d4d4353
|
||||
#define CBMEM_ID_MPTABLE 0x534d5054
|
||||
#define CBMEM_ID_MRCDATA 0x4d524344
|
||||
#define CBMEM_ID_VAR_MRCDATA 0x4d524345
|
||||
@@ -100,6 +101,7 @@
|
||||
{ CBMEM_ID_IMD_SMALL, "IMD SMALL " }, \
|
||||
{ CBMEM_ID_MEMINFO, "MEM INFO " }, \
|
||||
{ CBMEM_ID_MMA_DATA, "MMA DATA " }, \
|
||||
{ CBMEM_ID_MMC_STATUS, "MMC STATUS " }, \
|
||||
{ CBMEM_ID_MPTABLE, "SMP TABLE " }, \
|
||||
{ CBMEM_ID_MRCDATA, "MRC DATA " }, \
|
||||
{ CBMEM_ID_VAR_MRCDATA, "VARMRC DATA" }, \
|
||||
|
@@ -291,9 +291,9 @@ struct lb_gpios {
|
||||
};
|
||||
|
||||
#define LB_TAG_VBNV 0x0019
|
||||
#define LB_TAB_VBOOT_HANDOFF 0x0020
|
||||
#define LB_TAB_VBOOT_WORKBUF 0x0034
|
||||
#define LB_TAB_DMA 0x0022
|
||||
#define LB_TAG_VBOOT_HANDOFF 0x0020
|
||||
#define LB_TAG_VBOOT_WORKBUF 0x0034
|
||||
#define LB_TAG_DMA 0x0022
|
||||
#define LB_TAG_RAM_OOPS 0x0023
|
||||
#define LB_TAG_MTC 0x002b
|
||||
struct lb_range {
|
||||
@@ -310,7 +310,7 @@ void lb_ramoops(struct lb_header *header);
|
||||
#define LB_TAG_CBMEM_CONSOLE 0x0017
|
||||
#define LB_TAG_MRC_CACHE 0x0018
|
||||
#define LB_TAG_ACPI_GNVS 0x0024
|
||||
#define LB_TAG_TCPA_LOG 0x0034
|
||||
#define LB_TAG_TCPA_LOG 0x0036
|
||||
#define LB_TAG_WIFI_CALIBRATION 0x0027
|
||||
#define LB_TAG_VPD 0x002c
|
||||
struct lb_cbmem_ref {
|
||||
@@ -385,6 +385,21 @@ struct mac_address {
|
||||
uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */
|
||||
};
|
||||
|
||||
#define LB_TAG_MMC_INFO 0x0035
|
||||
struct lb_mmc_info {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
/*
|
||||
* Passes the early mmc status to payload to indicate if firmware
|
||||
* successfully sent CMD0, CMD1 to the card or not. In case of
|
||||
* success, the payload can skip the first step of the initialization
|
||||
* sequence which is to send CMD0, and instead start by sending CMD1
|
||||
* as described in Jedec Standard JESD83-B1 section 6.4.3.
|
||||
* passes 1 on success
|
||||
*/
|
||||
int32_t early_cmd1_status;
|
||||
};
|
||||
|
||||
struct lb_macs {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
|
@@ -38,11 +38,11 @@
|
||||
#if CONFIG(COREBOOT_BUILD)
|
||||
#include <console/console.h>
|
||||
#include <halt.h>
|
||||
#define printf(...) printk(BIOS_ERR, __VA_ARGS__)
|
||||
#define HALT(x) halt()
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define HALT(x)
|
||||
#define printk(level, ...) printf(__VA_ARGS__)
|
||||
#define HALT(x) abort()
|
||||
#endif
|
||||
|
||||
static inline void *xmalloc_work(size_t size, const char *file,
|
||||
@@ -50,7 +50,7 @@ static inline void *xmalloc_work(size_t size, const char *file,
|
||||
{
|
||||
void *ret = malloc(size);
|
||||
if (!ret && size) {
|
||||
printf("%s/%s/line %d: Failed to malloc %zu bytes\n",
|
||||
printk(BIOS_ERR, "%s/%s/line %d: Failed to malloc %zu bytes\n",
|
||||
file, func, line, size);
|
||||
while (1)
|
||||
HALT(1);
|
||||
|
@@ -9,6 +9,7 @@ endif
|
||||
|
||||
smm-$(CONFIG_DEBUG_SMI) += init.c console.c vtxprintf.c printk.c
|
||||
smm-$(CONFIG_SMM_TSEG) += die.c
|
||||
smm-$(CONFIG_SMM_TSEG) += post.c
|
||||
|
||||
verstage-y += init.c
|
||||
verstage-y += printk.c
|
||||
|
@@ -36,4 +36,11 @@ void __noreturn die(const char *msg)
|
||||
die_notify();
|
||||
halt();
|
||||
}
|
||||
|
||||
/* Report a fatal error with a post code */
|
||||
void __noreturn die_with_post_code(uint8_t value, const char *msg)
|
||||
{
|
||||
post_code(value);
|
||||
die(msg);
|
||||
}
|
||||
#endif
|
||||
|
@@ -44,7 +44,6 @@ void __weak mainboard_post(uint8_t value)
|
||||
|
||||
DECLARE_SPIN_LOCK(cmos_post_lock)
|
||||
|
||||
#if ENV_RAMSTAGE
|
||||
void cmos_post_log(void)
|
||||
{
|
||||
u8 code = 0;
|
||||
@@ -82,7 +81,7 @@ void cmos_post_log(void)
|
||||
default:
|
||||
printk(BIOS_WARNING, "POST: Unexpected post code "
|
||||
"in previous boot: 0x%02x\n", code);
|
||||
#if CONFIG(ELOG)
|
||||
#if CONFIG(ELOG) && (ENV_RAMSTAGE || CONFIG(ELOG_PRERAM))
|
||||
elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code);
|
||||
#if CONFIG(CMOS_POST_EXTRA)
|
||||
if (extra)
|
||||
@@ -125,7 +124,6 @@ void post_log_clear(void)
|
||||
post_log_extra(0);
|
||||
}
|
||||
#endif /* CONFIG_CMOS_POST_EXTRA */
|
||||
#endif /* ENV_RAMSTAGE */
|
||||
|
||||
static void cmos_post_code(u8 value)
|
||||
{
|
||||
|
@@ -24,20 +24,6 @@
|
||||
#define SUPPORT_64BIT_INTS
|
||||
#endif
|
||||
|
||||
/* haha, don't need ctype.c */
|
||||
#define isdigit(c) ((c) >= '0' && (c) <= '9')
|
||||
#define is_digit isdigit
|
||||
#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
|
||||
|
||||
static int skip_atoi(const char **s)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (is_digit(**s))
|
||||
i = i*10 + *((*s)++) - '0';
|
||||
return i;
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
@@ -175,8 +161,8 @@ repeat:
|
||||
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
if (is_digit(*fmt)) {
|
||||
field_width = skip_atoi(&fmt);
|
||||
if (isdigit(*fmt)) {
|
||||
field_width = skip_atoi((char **)&fmt);
|
||||
} else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
@@ -191,8 +177,8 @@ repeat:
|
||||
precision = -1;
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if (is_digit(*fmt)) {
|
||||
precision = skip_atoi(&fmt);
|
||||
if (isdigit(*fmt)) {
|
||||
precision = skip_atoi((char **)&fmt);
|
||||
} else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
|
@@ -20,12 +20,13 @@
|
||||
* Largely based on the uboot-sunxi code.
|
||||
*/
|
||||
|
||||
#include "memmap.h"
|
||||
#include "twi.h"
|
||||
|
||||
#include <device/mmio.h>
|
||||
#include <delay.h>
|
||||
#include <device/i2c_simple.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "memmap.h"
|
||||
#include "twi.h"
|
||||
|
||||
#define TWI_BASE(n) (A1X_TWI0_BASE + 0x400 * (n))
|
||||
|
||||
|
@@ -17,6 +17,8 @@
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/msr.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "init_cpus.h"
|
||||
|
||||
#if CONFIG(HAVE_OPTION_TABLE)
|
||||
@@ -984,7 +986,6 @@ void cpuSetAMDMSR(uint8_t node_id)
|
||||
uint8_t nvram;
|
||||
u32 platform;
|
||||
uint64_t revision;
|
||||
uint8_t enable_c_states;
|
||||
uint8_t enable_cpb;
|
||||
|
||||
printk(BIOS_DEBUG, "cpuSetAMDMSR ");
|
||||
@@ -1060,21 +1061,16 @@ void cpuSetAMDMSR(uint8_t node_id)
|
||||
}
|
||||
|
||||
if (revision & (AMD_DR_Ex | AMD_FAM15_ALL)) {
|
||||
enable_c_states = 0;
|
||||
if (CONFIG(HAVE_ACPI_TABLES))
|
||||
if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
|
||||
enable_c_states = !!nvram;
|
||||
|
||||
if (enable_c_states) {
|
||||
/* Set up the C-state base address */
|
||||
msr_t c_state_addr_msr;
|
||||
c_state_addr_msr = rdmsr(MSR_CSTATE_ADDRESS);
|
||||
c_state_addr_msr.lo = ACPI_CPU_P_LVL2; /* CstateAddr = ACPI_CPU_P_LVL2 */
|
||||
wrmsr(MSR_CSTATE_ADDRESS, c_state_addr_msr);
|
||||
}
|
||||
if ((get_option(&nvram, "cpu_c_states") == CB_SUCCESS) &&
|
||||
(nvram)) {
|
||||
/* Set up the C-state base address */
|
||||
msr_t c_state_addr_msr;
|
||||
c_state_addr_msr = rdmsr(MSR_CSTATE_ADDRESS);
|
||||
c_state_addr_msr.lo = ACPI_CPU_P_LVL2;
|
||||
wrmsr(MSR_CSTATE_ADDRESS, c_state_addr_msr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
enable_c_states = 0;
|
||||
#endif
|
||||
|
||||
if (revision & AMD_FAM15_ALL) {
|
||||
|
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <stdint.h>
|
||||
#include <option.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/amd/msr.h>
|
||||
@@ -30,6 +29,7 @@
|
||||
#include <northbridge/amd/amdht/AsPsDefs.h>
|
||||
#include <northbridge/amd/amdmct/mct/mct.h>
|
||||
#include <northbridge/amd/amdmct/amddefs.h>
|
||||
#include <types.h>
|
||||
|
||||
static inline uint8_t is_fam15h(void)
|
||||
{
|
||||
|
@@ -95,13 +95,13 @@ void real_start_other_core(uint32_t nodeid, uint32_t cores)
|
||||
*/
|
||||
|
||||
/* Wait for the first core of each compute unit to start... */
|
||||
uint32_t timeout;
|
||||
for (i = 1; i < cores + 1; i++) {
|
||||
if (!(i & 0x1)) {
|
||||
uint32_t ap_apicid =
|
||||
get_boot_apic_id(nodeid, i);
|
||||
timeout = wait_cpu_state(ap_apicid,
|
||||
F10_APSTATE_ASLEEP, F10_APSTATE_ASLEEP);
|
||||
/* Timeout */
|
||||
wait_cpu_state(ap_apicid, F10_APSTATE_ASLEEP,
|
||||
F10_APSTATE_ASLEEP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,6 @@ subdirs-$(CONFIG_CPU_INTEL_SOCKET_P) += socket_p
|
||||
subdirs-$(CONFIG_CPU_INTEL_SOCKET_MPGA604) += socket_mPGA604
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_NEHALEM) += model_2065x
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += model_206ax
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += model_206ax
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_RANGELEY) += fsp_model_406dx
|
||||
subdirs-$(CONFIG_CPU_INTEL_SLOT_1) += slot_1
|
||||
|
@@ -20,6 +20,8 @@ config CPU_SPECIFIC_OPTIONS
|
||||
select TSC_SYNC_MFENCE
|
||||
select CPU_INTEL_COMMON
|
||||
select NO_FIXED_XIP_ROM_SIZE
|
||||
select PARALLEL_MP
|
||||
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
|
||||
|
||||
config BOOTBLOCK_CPU_INIT
|
||||
string
|
||||
@@ -29,4 +31,8 @@ config SMM_TSEG_SIZE
|
||||
hex
|
||||
default 0x800000
|
||||
|
||||
config SMM_RESERVED_SIZE
|
||||
hex
|
||||
default 0x100000
|
||||
|
||||
endif
|
||||
|
@@ -19,6 +19,10 @@ ramstage-y += acpi.c
|
||||
|
||||
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
|
||||
|
||||
romstage-y += stage_cache.c
|
||||
ramstage-y += stage_cache.c
|
||||
postcar-y += stage_cache.c
|
||||
|
||||
cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_2065x/microcode.bin
|
||||
|
||||
cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S
|
||||
|
@@ -20,6 +20,7 @@
|
||||
/* Nehalem bus clock is fixed at 133MHz */
|
||||
#define NEHALEM_BCLK 133
|
||||
|
||||
#define CORE_THREAD_COUNT_MSR 0x35
|
||||
#define MSR_FEATURE_CONFIG 0x13c
|
||||
#define MSR_FLEX_RATIO 0x194
|
||||
#define FLEX_RATIO_LOCK (1 << 20)
|
||||
@@ -79,4 +80,22 @@ void set_power_limits(u8 power_limit_1_time);
|
||||
int cpu_config_tdp_levels(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Region of SMM space is reserved for multipurpose use. It falls below
|
||||
* the IED region and above the SMM handler.
|
||||
*/
|
||||
#define RESERVED_SMM_SIZE CONFIG_SMM_RESERVED_SIZE
|
||||
#define RESERVED_SMM_OFFSET (CONFIG_SMM_TSEG_SIZE - RESERVED_SMM_SIZE)
|
||||
|
||||
/* Sanity check config options. */
|
||||
#if (CONFIG_SMM_TSEG_SIZE <= RESERVED_SMM_SIZE)
|
||||
# error "CONFIG_SMM_TSEG_SIZE <= RESERVED_SMM_SIZE"
|
||||
#endif
|
||||
#if (CONFIG_SMM_TSEG_SIZE < 0x800000)
|
||||
# error "CONFIG_SMM_TSEG_SIZE must at least be 8MiB"
|
||||
#endif
|
||||
#if ((CONFIG_SMM_TSEG_SIZE & (CONFIG_SMM_TSEG_SIZE - 1)) != 0)
|
||||
# error "CONFIG_SMM_TSEG_SIZE is not a power of 2"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -15,6 +15,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <arch/acpi.h>
|
||||
@@ -22,6 +23,7 @@
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/lapic.h>
|
||||
#include <cpu/x86/mp.h>
|
||||
#include <cpu/intel/microcode.h>
|
||||
#include <cpu/intel/speedstep.h>
|
||||
#include <cpu/intel/turbo.h>
|
||||
@@ -109,29 +111,6 @@ static acpi_cstate_t cstate_map[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
int cpu_get_apic_id_map(int *apic_id_map)
|
||||
{
|
||||
int i;
|
||||
struct cpuid_result result;
|
||||
unsigned int threads_per_package, threads_per_core;
|
||||
|
||||
/* Logical processors (threads) per core */
|
||||
result = cpuid_ext(0xb, 0);
|
||||
threads_per_core = result.ebx & 0xffff;
|
||||
|
||||
/* Logical processors (threads) per package */
|
||||
result = cpuid_ext(0xb, 1);
|
||||
threads_per_package = result.ebx & 0xffff;
|
||||
|
||||
for (i = 0; i < threads_per_package && i < CONFIG_MAX_CPUS; ++i) {
|
||||
apic_id_map[i] = (i % threads_per_core)
|
||||
+ ((i / threads_per_core) << 2);
|
||||
}
|
||||
|
||||
return threads_per_package;
|
||||
}
|
||||
|
||||
|
||||
int cpu_config_tdp_levels(void)
|
||||
{
|
||||
msr_t platform_info;
|
||||
@@ -250,58 +229,6 @@ static void configure_mca(void)
|
||||
wrmsr(IA32_MC0_STATUS + (i * 4), msr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize any extra cores/threads in this package.
|
||||
*/
|
||||
static void intel_cores_init(struct device *cpu)
|
||||
{
|
||||
struct cpuid_result result;
|
||||
unsigned int threads_per_package, threads_per_core, i;
|
||||
|
||||
/* Logical processors (threads) per core */
|
||||
result = cpuid_ext(0xb, 0);
|
||||
threads_per_core = result.ebx & 0xffff;
|
||||
|
||||
/* Logical processors (threads) per package */
|
||||
result = cpuid_ext(0xb, 1);
|
||||
threads_per_package = result.ebx & 0xffff;
|
||||
|
||||
/* Only initialize extra cores from BSP */
|
||||
if (cpu->path.apic.apic_id)
|
||||
return;
|
||||
|
||||
printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n",
|
||||
cpu->path.apic.apic_id, threads_per_package/threads_per_core,
|
||||
threads_per_core);
|
||||
|
||||
for (i = 1; i < threads_per_package; ++i) {
|
||||
struct device_path cpu_path;
|
||||
struct device *new;
|
||||
|
||||
/* Build the CPU device path */
|
||||
cpu_path.type = DEVICE_PATH_APIC;
|
||||
cpu_path.apic.apic_id =
|
||||
cpu->path.apic.apic_id + (i % threads_per_core)
|
||||
+ ((i / threads_per_core) << 2);
|
||||
|
||||
/* Allocate the new CPU device structure */
|
||||
new = alloc_dev(cpu->bus, &cpu_path);
|
||||
if (!new)
|
||||
continue;
|
||||
|
||||
printk(BIOS_DEBUG, "CPU: %u has core %u\n",
|
||||
cpu->path.apic.apic_id,
|
||||
new->path.apic.apic_id);
|
||||
|
||||
/* Start the new CPU */
|
||||
if (is_smp_boot() && !start_cpu(new)) {
|
||||
/* Record the error in cpu? */
|
||||
printk(BIOS_ERR, "CPU %u would not start!\n",
|
||||
new->path.apic.apic_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void model_2065x_init(struct device *cpu)
|
||||
{
|
||||
char processor_name[49];
|
||||
@@ -309,8 +236,6 @@ static void model_2065x_init(struct device *cpu)
|
||||
/* Turn on caching if we haven't already */
|
||||
x86_enable_cache();
|
||||
|
||||
intel_update_microcode_from_cbfs();
|
||||
|
||||
/* Clear out pending MCEs */
|
||||
configure_mca();
|
||||
|
||||
@@ -320,10 +245,6 @@ static void model_2065x_init(struct device *cpu)
|
||||
printk(BIOS_INFO, "CPU:lapic=%ld, boot_cpu=%d\n", lapicid(),
|
||||
boot_cpu());
|
||||
|
||||
/* Setup MTRRs based on physical address size */
|
||||
x86_setup_mtrrs_with_detect();
|
||||
x86_mtrr_check();
|
||||
|
||||
/* Setup Page Attribute Tables (PAT) */
|
||||
// TODO set up PAT
|
||||
|
||||
@@ -348,9 +269,75 @@ static void model_2065x_init(struct device *cpu)
|
||||
|
||||
/* Enable Turbo */
|
||||
enable_turbo();
|
||||
}
|
||||
|
||||
/* Start up extra cores */
|
||||
intel_cores_init(cpu);
|
||||
/* MP initialization support. */
|
||||
static const void *microcode_patch;
|
||||
|
||||
static void pre_mp_init(void)
|
||||
{
|
||||
/* Setup MTRRs based on physical address size. */
|
||||
x86_setup_mtrrs_with_detect();
|
||||
x86_mtrr_check();
|
||||
}
|
||||
|
||||
static int get_cpu_count(void)
|
||||
{
|
||||
msr_t msr;
|
||||
int num_threads;
|
||||
int num_cores;
|
||||
|
||||
msr = rdmsr(CORE_THREAD_COUNT_MSR);
|
||||
num_threads = (msr.lo >> 0) & 0xffff;
|
||||
num_cores = (msr.lo >> 16) & 0xffff;
|
||||
printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
|
||||
num_cores, num_threads);
|
||||
|
||||
return num_threads;
|
||||
}
|
||||
|
||||
static void get_microcode_info(const void **microcode, int *parallel)
|
||||
{
|
||||
microcode_patch = intel_microcode_find();
|
||||
*microcode = microcode_patch;
|
||||
*parallel = 1;
|
||||
}
|
||||
|
||||
static void per_cpu_smm_trigger(void)
|
||||
{
|
||||
/* Relocate the SMM handler. */
|
||||
smm_relocate();
|
||||
|
||||
/* After SMM relocation a 2nd microcode load is required. */
|
||||
intel_microcode_load_unlocked(microcode_patch);
|
||||
}
|
||||
|
||||
static void post_mp_init(void)
|
||||
{
|
||||
/* Now that all APs have been relocated as well as the BSP let SMIs
|
||||
* start flowing. */
|
||||
southbridge_smm_init();
|
||||
|
||||
/* Lock down the SMRAM space. */
|
||||
smm_lock();
|
||||
}
|
||||
|
||||
|
||||
static const struct mp_ops mp_ops = {
|
||||
.pre_mp_init = pre_mp_init,
|
||||
.get_cpu_count = get_cpu_count,
|
||||
.get_smm_info = smm_info,
|
||||
.get_microcode_info = get_microcode_info,
|
||||
.pre_mp_smm_init = smm_initialize,
|
||||
.per_cpu_smm_trigger = per_cpu_smm_trigger,
|
||||
.relocation_handler = smm_relocation_handler,
|
||||
.post_mp_init = post_mp_init,
|
||||
};
|
||||
|
||||
void bsp_init_and_start_aps(struct bus *cpu_bus)
|
||||
{
|
||||
if (mp_init_with_smm(cpu_bus, &mp_ops))
|
||||
printk(BIOS_ERR, "MP initialization failure.\n");
|
||||
}
|
||||
|
||||
static struct device_operations cpu_dev_ops = {
|
||||
|
30
src/cpu/intel/model_2065x/stage_cache.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 Google, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <cbmem.h>
|
||||
#include <stage_cache.h>
|
||||
#include <cpu/intel/smm/gen1/smi.h>
|
||||
#include "model_2065x.h"
|
||||
|
||||
void stage_cache_external_region(void **base, size_t *size)
|
||||
{
|
||||
/*
|
||||
* The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET.
|
||||
* The top of RAM is defined to be the TSEG base address.
|
||||
*/
|
||||
*size = RESERVED_SMM_SIZE;
|
||||
*base = (void *)((uintptr_t)northbridge_get_tseg_base()
|
||||
+ RESERVED_SMM_OFFSET);
|
||||
}
|
@@ -1,10 +1,7 @@
|
||||
config CPU_INTEL_MODEL_206AX
|
||||
bool
|
||||
|
||||
config CPU_INTEL_MODEL_306AX
|
||||
bool
|
||||
|
||||
if CPU_INTEL_MODEL_206AX || CPU_INTEL_MODEL_306AX
|
||||
if CPU_INTEL_MODEL_206AX
|
||||
|
||||
config CPU_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
|
@@ -17,11 +17,8 @@ void bsp_init_and_start_aps(struct bus *cpu_bus);
|
||||
|
||||
/* These helpers are for performing SMM relocation. */
|
||||
void southbridge_smm_init(void);
|
||||
void southbridge_trigger_smi(void);
|
||||
void southbridge_clear_smi_status(void);
|
||||
u32 northbridge_get_tseg_base(void);
|
||||
u32 northbridge_get_tseg_size(void);
|
||||
int cpu_get_apic_id_map(int *apic_id_map);
|
||||
void northbridge_write_smram(u8 smram);
|
||||
|
||||
bool cpu_has_alternative_smrr(void);
|
||||
|
@@ -100,60 +100,6 @@ static void write_smrr(struct smm_relocation_params *relo_params)
|
||||
}
|
||||
}
|
||||
|
||||
/* The relocation work is actually performed in SMM context, but the code
|
||||
* resides in the ramstage module. This occurs by trampolining from the default
|
||||
* SMRAM entry point to here. */
|
||||
static void asmlinkage cpu_smm_do_relocation(void *arg)
|
||||
{
|
||||
em64t101_smm_state_save_area_t *save_state;
|
||||
msr_t mtrr_cap;
|
||||
struct smm_relocation_params *relo_params;
|
||||
const struct smm_module_params *p;
|
||||
const struct smm_runtime *runtime;
|
||||
int cpu;
|
||||
|
||||
p = arg;
|
||||
runtime = p->runtime;
|
||||
relo_params = p->arg;
|
||||
cpu = p->cpu;
|
||||
|
||||
if (cpu >= CONFIG_MAX_CPUS) {
|
||||
printk(BIOS_CRIT,
|
||||
"Invalid CPU number assigned in SMM stub: %d\n", cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu);
|
||||
|
||||
/* All threads need to set IEDBASE and SMBASE in the save state area.
|
||||
* Since one thread runs at a time during the relocation the save state
|
||||
* is the same for all cpus. */
|
||||
save_state = (void *)(runtime->smbase + SMM_DEFAULT_SIZE -
|
||||
runtime->save_state_size);
|
||||
|
||||
/* The relocated handler runs with all CPUs concurrently. Therefore
|
||||
* stagger the entry points adjusting SMBASE downwards by save state
|
||||
* size * CPU num. */
|
||||
save_state->smbase = relo_params->smram_base -
|
||||
cpu * runtime->save_state_size;
|
||||
if (CONFIG_IED_REGION_SIZE != 0) {
|
||||
save_state->iedbase = relo_params->ied_base;
|
||||
|
||||
printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x @ %p\n",
|
||||
save_state->smbase, save_state->iedbase, save_state);
|
||||
} else {
|
||||
printk(BIOS_DEBUG, "New SMBASE=0x%08x @ %p\n",
|
||||
save_state->smbase, save_state);
|
||||
}
|
||||
|
||||
/* Write SMRR MSRs based on indicated support. */
|
||||
mtrr_cap = rdmsr(MTRR_CAP_MSR);
|
||||
if (mtrr_cap.lo & SMRR_SUPPORTED && relo_params->smrr_mask.lo != 0)
|
||||
write_smrr(relo_params);
|
||||
|
||||
southbridge_clear_smi_status();
|
||||
}
|
||||
|
||||
static void fill_in_relocation_params(struct smm_relocation_params *params)
|
||||
{
|
||||
/* All range registers are aligned to 4KiB */
|
||||
@@ -202,33 +148,6 @@ static void fill_in_relocation_params(struct smm_relocation_params *params)
|
||||
}
|
||||
}
|
||||
|
||||
static int install_relocation_handler(int *apic_id_map, int num_cpus,
|
||||
struct smm_relocation_params *relo_params)
|
||||
{
|
||||
/* The default SMM entry happens serially at the default location.
|
||||
* Therefore, there is only 1 concurrent save state area. Set the
|
||||
* stack size to the save state size, and call into the
|
||||
* do_relocation handler. */
|
||||
int save_state_size = sizeof(em64t101_smm_state_save_area_t);
|
||||
struct smm_loader_params smm_params = {
|
||||
.per_cpu_stack_size = save_state_size,
|
||||
.num_concurrent_stacks = num_cpus,
|
||||
.per_cpu_save_state_size = save_state_size,
|
||||
.num_concurrent_save_states = 1,
|
||||
.handler = &cpu_smm_do_relocation,
|
||||
.handler_arg = (void *)relo_params,
|
||||
};
|
||||
|
||||
default_smm_area = backup_default_smm_area();
|
||||
|
||||
if (smm_setup_relocation_handler(&smm_params))
|
||||
return -1;
|
||||
int i;
|
||||
for (i = 0; i < num_cpus; i++)
|
||||
smm_params.runtime->apic_id_to_cpu[i] = apic_id_map[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_ied_area(struct smm_relocation_params *params)
|
||||
{
|
||||
char *ied_base;
|
||||
@@ -248,94 +167,6 @@ static void setup_ied_area(struct smm_relocation_params *params)
|
||||
memset(ied_base + (1 << 20), 0, (32 << 10));
|
||||
}
|
||||
|
||||
static int install_permanent_handler(int *apic_id_map, int num_cpus,
|
||||
struct smm_relocation_params *relo_params)
|
||||
{
|
||||
/* There are num_cpus concurrent stacks and num_cpus concurrent save
|
||||
* state areas. Lastly, set the stack size to the save state size. */
|
||||
int save_state_size = sizeof(em64t101_smm_state_save_area_t);
|
||||
struct smm_loader_params smm_params = {
|
||||
.per_cpu_stack_size = save_state_size,
|
||||
.num_concurrent_stacks = num_cpus,
|
||||
.per_cpu_save_state_size = save_state_size,
|
||||
.num_concurrent_save_states = num_cpus,
|
||||
};
|
||||
|
||||
printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n",
|
||||
relo_params->smram_base);
|
||||
if (smm_load_module((void *)relo_params->smram_base,
|
||||
relo_params->smram_size, &smm_params))
|
||||
return -1;
|
||||
int i;
|
||||
for (i = 0; i < num_cpus; i++)
|
||||
smm_params.runtime->apic_id_to_cpu[i] = apic_id_map[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_smm_setup(void)
|
||||
{
|
||||
int num_cpus;
|
||||
int apic_id_map[CONFIG_MAX_CPUS];
|
||||
|
||||
printk(BIOS_DEBUG, "Setting up SMI for CPU\n");
|
||||
|
||||
fill_in_relocation_params(&smm_reloc_params);
|
||||
|
||||
/* enable the SMM memory window */
|
||||
northbridge_write_smram(D_OPEN | G_SMRAME | C_BASE_SEG);
|
||||
|
||||
if (CONFIG_IED_REGION_SIZE != 0)
|
||||
setup_ied_area(&smm_reloc_params);
|
||||
|
||||
num_cpus = cpu_get_apic_id_map(apic_id_map);
|
||||
if (num_cpus > CONFIG_MAX_CPUS) {
|
||||
printk(BIOS_CRIT,
|
||||
"Error: Hardware CPUs (%d) > MAX_CPUS (%d)\n",
|
||||
num_cpus, CONFIG_MAX_CPUS);
|
||||
}
|
||||
|
||||
if (install_relocation_handler(apic_id_map, num_cpus,
|
||||
&smm_reloc_params)) {
|
||||
printk(BIOS_CRIT, "SMM Relocation handler install failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (install_permanent_handler(apic_id_map, num_cpus,
|
||||
&smm_reloc_params)) {
|
||||
printk(BIOS_CRIT, "SMM Permanent handler install failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ensure the SMM handlers hit DRAM before performing first SMI. */
|
||||
/* TODO(adurbin): Is this really needed? */
|
||||
wbinvd();
|
||||
|
||||
/* close the SMM memory window and enable normal SMM */
|
||||
northbridge_write_smram(G_SMRAME | C_BASE_SEG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void smm_init(void)
|
||||
{
|
||||
/* Return early if CPU SMM setup failed. */
|
||||
if (cpu_smm_setup())
|
||||
return;
|
||||
|
||||
southbridge_smm_init();
|
||||
|
||||
/* Initiate first SMI to kick off SMM-context relocation. Note: this
|
||||
* SMI being triggered here queues up an SMI in the APs which are in
|
||||
* wait-for-SIPI state. Once an AP gets an SIPI it will service the SMI
|
||||
* at the SMM_DEFAULT_BASE before jumping to startup vector. */
|
||||
southbridge_trigger_smi();
|
||||
|
||||
printk(BIOS_DEBUG, "Relocation complete.\n");
|
||||
|
||||
/* Lock down the SMRAM space. */
|
||||
smm_lock();
|
||||
}
|
||||
|
||||
void smm_init_completion(void)
|
||||
{
|
||||
restore_default_smm_area(default_smm_area);
|
||||
|
@@ -21,4 +21,11 @@ config DCACHE_RAM_SIZE
|
||||
hex
|
||||
default 0x4000
|
||||
|
||||
config DCACHE_BSP_STACK_SIZE
|
||||
hex
|
||||
default 0x2000
|
||||
help
|
||||
The amount of anticipated stack usage in CAR by bootblock and
|
||||
other stages.
|
||||
|
||||
endif
|
||||
|
@@ -8,7 +8,9 @@ subdirs-y += ../microcode
|
||||
subdirs-y += ../hyperthreading
|
||||
subdirs-y += ../speedstep
|
||||
|
||||
cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S
|
||||
bootblock-y += ../car/bootblock.c
|
||||
bootblock-y += ../car/non-evict/cache_as_ram.S
|
||||
|
||||
postcar-y += ../car/non-evict/exit_car.S
|
||||
|
||||
romstage-y += ../car/romstage.c
|
||||
|
@@ -151,13 +151,6 @@ config X86_AMD_FIXED_MTRRS
|
||||
This option informs the MTRR code to use the RdMem and WrMem fields
|
||||
in the fixed MTRR MSRs.
|
||||
|
||||
config PLATFORM_USES_FSP1_0
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Selected for Intel processors/platform combinations that use the
|
||||
Intel Firmware Support Package (FSP) 1.0 for initialization.
|
||||
|
||||
config MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING
|
||||
def_bool n
|
||||
help
|
||||
|
@@ -24,7 +24,7 @@ void do_lapic_init(void)
|
||||
* see the Intel mp1.4 spec, page A-3
|
||||
*/
|
||||
|
||||
printk(BIOS_INFO, "Setting up local APIC...");
|
||||
printk(BIOS_INFO, "Setting up local APIC...\n");
|
||||
|
||||
/* Enable the local APIC */
|
||||
enable_lapic();
|
||||
|
@@ -291,6 +291,7 @@ int start_cpu(struct device *cpu)
|
||||
info = (struct cpu_info *)stack_top;
|
||||
info->index = index;
|
||||
info->cpu = cpu;
|
||||
cpu_add_map_entry(info->index);
|
||||
thread_init_cpu_info_non_bsp(info);
|
||||
|
||||
/* Advertise the new stack and index to start_cpu */
|
||||
@@ -549,6 +550,7 @@ void initialize_cpus(struct bus *cpu_bus)
|
||||
|
||||
/* Find the device structure for the boot CPU */
|
||||
info->cpu = alloc_find_dev(cpu_bus, &cpu_path);
|
||||
cpu_add_map_entry(info->index);
|
||||
|
||||
// why here? In case some day we can start core1 in amd_sibling_init
|
||||
if (is_smp_boot())
|
||||
|
@@ -135,20 +135,8 @@ struct mp_flight_plan {
|
||||
static int global_num_aps;
|
||||
static struct mp_flight_plan mp_info;
|
||||
|
||||
struct cpu_map {
|
||||
struct device *dev;
|
||||
/* Keep track of default apic ids for SMM. */
|
||||
int default_apic_id;
|
||||
};
|
||||
|
||||
/* Keep track of APIC and device structure for each CPU. */
|
||||
static struct cpu_map cpus[CONFIG_MAX_CPUS];
|
||||
|
||||
static inline void add_cpu_map_entry(const struct cpu_info *info)
|
||||
{
|
||||
cpus[info->index].dev = info->cpu;
|
||||
cpus[info->index].default_apic_id = cpuid_ebx(1) >> 24;
|
||||
}
|
||||
/* Keep track of device structure for each CPU. */
|
||||
static struct device *cpus_dev[CONFIG_MAX_CPUS];
|
||||
|
||||
static inline void barrier_wait(atomic_t *b)
|
||||
{
|
||||
@@ -212,9 +200,9 @@ static void asmlinkage ap_init(unsigned int cpu)
|
||||
|
||||
info = cpu_info();
|
||||
info->index = cpu;
|
||||
info->cpu = cpus[cpu].dev;
|
||||
info->cpu = cpus_dev[cpu];
|
||||
|
||||
add_cpu_map_entry(info);
|
||||
cpu_add_map_entry(info->index);
|
||||
thread_init_cpu_info_non_bsp(info);
|
||||
|
||||
/* Fix up APIC id with reality. */
|
||||
@@ -411,7 +399,7 @@ static int allocate_cpu_devices(struct bus *cpu_bus, struct mp_params *p)
|
||||
continue;
|
||||
}
|
||||
new->name = processor_name;
|
||||
cpus[i].dev = new;
|
||||
cpus_dev[i] = new;
|
||||
}
|
||||
|
||||
return max_cpus;
|
||||
@@ -589,7 +577,7 @@ static void init_bsp(struct bus *cpu_bus)
|
||||
printk(BIOS_CRIT, "BSP index(%d) != 0!\n", info->index);
|
||||
|
||||
/* Track BSP in cpu_map structures. */
|
||||
add_cpu_map_entry(info);
|
||||
cpu_add_map_entry(info->index);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -667,15 +655,6 @@ static void mp_initialize_cpu(void)
|
||||
cpu_initialize(info->index);
|
||||
}
|
||||
|
||||
/* Returns APIC id for coreboot CPU number or < 0 on failure. */
|
||||
int mp_get_apic_id(int logical_cpu)
|
||||
{
|
||||
if (logical_cpu >= CONFIG_MAX_CPUS || logical_cpu < 0)
|
||||
return -1;
|
||||
|
||||
return cpus[logical_cpu].default_apic_id;
|
||||
}
|
||||
|
||||
void smm_initiate_relocation_parallel(void)
|
||||
{
|
||||
if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
|
||||
@@ -769,7 +748,7 @@ static void adjust_smm_apic_id_map(struct smm_loader_params *smm_params)
|
||||
struct smm_runtime *runtime = smm_params->runtime;
|
||||
|
||||
for (i = 0; i < CONFIG_MAX_CPUS; i++)
|
||||
runtime->apic_id_to_cpu[i] = mp_get_apic_id(i);
|
||||
runtime->apic_id_to_cpu[i] = cpu_get_apic_id(i);
|
||||
}
|
||||
|
||||
static int install_relocation_handler(int num_cpus, size_t save_state_size)
|
||||
@@ -891,13 +870,20 @@ static int run_ap_work(struct mp_callback *val, long expire_us)
|
||||
int i;
|
||||
int cpus_accepted;
|
||||
struct stopwatch sw;
|
||||
int cur_cpu = cpu_index();
|
||||
int cur_cpu;
|
||||
|
||||
if (!CONFIG(PARALLEL_MP_AP_WORK)) {
|
||||
printk(BIOS_ERR, "APs already parked. PARALLEL_MP_AP_WORK not selected.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cur_cpu = cpu_index();
|
||||
|
||||
if (cur_cpu < 0) {
|
||||
printk(BIOS_ERR, "Invalid CPU index.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Signal to all the APs to run the func. */
|
||||
for (i = 0; i < ARRAY_SIZE(ap_callbacks); i++) {
|
||||
if (cur_cpu == i)
|
||||
@@ -939,6 +925,12 @@ static void ap_wait_for_instruction(void)
|
||||
return;
|
||||
|
||||
cur_cpu = cpu_index();
|
||||
|
||||
if (cur_cpu < 0) {
|
||||
printk(BIOS_ERR, "Invalid CPU index.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
per_cpu_slot = &ap_callbacks[cur_cpu];
|
||||
|
||||
while (1) {
|
||||
|
@@ -331,7 +331,6 @@ static void commit_fixed_mtrrs(void)
|
||||
|
||||
desc = &fixed_mtrr_desc[i];
|
||||
num_ranges = (desc->end - desc->begin) / desc->step;
|
||||
ASSERT(num_ranges > 0);
|
||||
for (j = 0; j < num_ranges; j += RANGES_PER_FIXED_MTRR) {
|
||||
msr_index[msr_num] = desc->msr_index_base +
|
||||
(j / RANGES_PER_FIXED_MTRR);
|
||||
@@ -355,6 +354,9 @@ static void commit_fixed_mtrrs(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that both arrays were fully initialized */
|
||||
ASSERT(msr_num == NUM_FIXED_MTRRS)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fixed_msrs); i++)
|
||||
printk(BIOS_DEBUG, "MTRR: Fixed MSR 0x%lx 0x%08x%08x\n",
|
||||
msr_index[i], fixed_msrs[i].hi, fixed_msrs[i].lo);
|
||||
|
@@ -116,12 +116,12 @@ void *map_2M_page(unsigned long page)
|
||||
static struct pg_table pgtbl[CONFIG_MAX_CPUS]
|
||||
__attribute__((aligned(4096)));
|
||||
static unsigned long mapped_window[CONFIG_MAX_CPUS];
|
||||
unsigned long index;
|
||||
int index;
|
||||
unsigned long window;
|
||||
void *result;
|
||||
int i;
|
||||
index = cpu_index();
|
||||
if (index >= CONFIG_MAX_CPUS)
|
||||
if (index < 0)
|
||||
return MAPPING_ERROR;
|
||||
window = page >> 10;
|
||||
if (window != mapped_window[index]) {
|
||||
|
@@ -340,6 +340,9 @@ static void compute_resources(struct bus *bus, struct resource *bridge,
|
||||
resource_t base;
|
||||
base = round(bridge->base, bridge->align);
|
||||
|
||||
if (!bus)
|
||||
return;
|
||||
|
||||
printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
|
||||
" limit: %llx\n", dev_path(bus->dev), resource2str(bridge),
|
||||
base, bridge->size, bridge->align,
|
||||
@@ -484,6 +487,9 @@ static void allocate_resources(struct bus *bus, struct resource *bridge,
|
||||
resource_t base;
|
||||
base = bridge->base;
|
||||
|
||||
if (!bus)
|
||||
return;
|
||||
|
||||
printk(BIOS_SPEW, "%s %s: base:%llx size:%llx align:%d gran:%d "
|
||||
"limit:%llx\n", dev_path(bus->dev),
|
||||
resource2str(bridge),
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <device/dram/ddr2.h>
|
||||
#include <lib.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
|
||||
/*==============================================================================
|
||||
* = DDR2 SPD decoding helpers
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <memory_info.h>
|
||||
#include <cbmem.h>
|
||||
#include <smbios.h>
|
||||
#include <types.h>
|
||||
|
||||
/*==============================================================================
|
||||
* = DDR3 SPD decoding helpers
|
||||
|
@@ -780,9 +780,6 @@ static int should_run_oprom(struct device *dev)
|
||||
*/
|
||||
should_run = display_init_required();
|
||||
|
||||
if (!should_run && CONFIG(VBOOT))
|
||||
should_run = vboot_wants_oprom();
|
||||
|
||||
if (!should_run)
|
||||
printk(BIOS_DEBUG, "Not running VGA Option ROM\n");
|
||||
return should_run;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016-2019 Kyösti Mälkki
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
@@ -14,62 +16,126 @@
|
||||
#include <console/console.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
#include <northbridge/amd/agesa/state_machine.h>
|
||||
#include <northbridge/amd/agesa/BiosCallOuts.h>
|
||||
#include <amdlib.h>
|
||||
#include <debug_util.h>
|
||||
#include <AGESA.h>
|
||||
#include <AMD.h>
|
||||
|
||||
#include <heapManager.h>
|
||||
|
||||
static const char undefined[] = "undefined";
|
||||
|
||||
/* Match order of enum AGESA_STRUCT_NAME. */
|
||||
static const char *AgesaFunctionNameStr[] = {
|
||||
"AmdInitRecovery", "AmdCreateStruct", "AmdInitEarly", "AmdInitEnv", "AmdInitLate",
|
||||
"AmdInitMid", "AmdInitPost", "AmdInitReset", "AmdInitResume", "AmdReleaseStruct",
|
||||
"AmdS3LateRestore","AmdS3Save", "AmdGetApicId", "AmdGetPciAddress", "AmdIdentifyCore",
|
||||
"AmdReadEventLog", "AmdGetAvailableExeCacheSize", "AmdLateRunApTask", "AmdIdentifyDimm",
|
||||
};
|
||||
|
||||
/* heapManager.h */
|
||||
static const char *HeapStatusStr[] = {
|
||||
"DoNotExistYet", "LocalCache", "TempMem", "SystemMem", "DoNotExistAnymore","S3Resume"
|
||||
};
|
||||
|
||||
/* This function has to match with enumeration of AGESA_STRUCT_NAME defined
|
||||
* inside AMD.h header file. Unfortunately those are different across
|
||||
* different vendorcode subtrees.
|
||||
*
|
||||
* TBD: Fix said header or move this function together with the strings above
|
||||
* under vendorcode/ tree.
|
||||
*/
|
||||
|
||||
const char *agesa_struct_name(int state)
|
||||
struct agesa_mapping
|
||||
{
|
||||
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE)
|
||||
if ((state < AMD_INIT_RECOVERY) || (state > AMD_IDENTIFY_DIMMS))
|
||||
return undefined;
|
||||
AGESA_STRUCT_NAME func;
|
||||
const char *name;
|
||||
uint32_t entry_id;
|
||||
uint32_t exit_id;
|
||||
};
|
||||
|
||||
int index = state - AMD_INIT_RECOVERY;
|
||||
#else
|
||||
state >>= 12;
|
||||
if ((state < AMD_INIT_RECOVERY >> 12) || (state > AMD_IDENTIFY_DIMMS >> 12))
|
||||
return undefined;
|
||||
|
||||
int index = state - (AMD_INIT_RECOVERY >> 12);
|
||||
static const struct agesa_mapping entrypoint[] = {
|
||||
{
|
||||
.func = AMD_INIT_RESET,
|
||||
.name = "AmdInitReset",
|
||||
.entry_id = TS_AGESA_INIT_RESET_START,
|
||||
.exit_id = TS_AGESA_INIT_RESET_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_EARLY,
|
||||
.name = "AmdInitEarly",
|
||||
.entry_id = TS_AGESA_INIT_EARLY_START,
|
||||
.exit_id = TS_AGESA_INIT_EARLY_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_POST,
|
||||
.name = "AmdInitPost",
|
||||
.entry_id = TS_AGESA_INIT_POST_START,
|
||||
.exit_id = TS_AGESA_INIT_POST_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_RESUME,
|
||||
.name = "AmdInitResume",
|
||||
.entry_id = TS_AGESA_INIT_RESUME_START,
|
||||
.exit_id = TS_AGESA_INIT_RESUME_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_ENV,
|
||||
.name = "AmdInitEnv",
|
||||
.entry_id = TS_AGESA_INIT_ENV_START,
|
||||
.exit_id = TS_AGESA_INIT_ENV_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_MID,
|
||||
.name = "AmdInitMid",
|
||||
.entry_id = TS_AGESA_INIT_MID_START,
|
||||
.exit_id = TS_AGESA_INIT_MID_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_LATE,
|
||||
.name = "AmdInitLate",
|
||||
.entry_id = TS_AGESA_INIT_LATE_START,
|
||||
.exit_id = TS_AGESA_INIT_LATE_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_S3LATE_RESTORE,
|
||||
.name = "AmdS3LateRestore",
|
||||
.entry_id = TS_AGESA_S3_LATE_START,
|
||||
.exit_id = TS_AGESA_S3_LATE_DONE,
|
||||
},
|
||||
#if !defined(AMD_S3_SAVE_REMOVED)
|
||||
{
|
||||
.func = AMD_S3_SAVE,
|
||||
.name = "AmdS3Save",
|
||||
.entry_id = TS_AGESA_INIT_RTB_START,
|
||||
.exit_id = TS_AGESA_INIT_RTB_DONE,
|
||||
},
|
||||
#endif
|
||||
return AgesaFunctionNameStr[index];
|
||||
{
|
||||
.func = AMD_S3FINAL_RESTORE,
|
||||
.name = "AmdS3FinalRestore",
|
||||
.entry_id = TS_AGESA_S3_FINAL_START,
|
||||
.exit_id = TS_AGESA_S3_FINAL_DONE,
|
||||
},
|
||||
{
|
||||
.func = AMD_INIT_RTB,
|
||||
.name = "AmdInitRtb",
|
||||
.entry_id = TS_AGESA_INIT_RTB_START,
|
||||
.exit_id = TS_AGESA_INIT_RTB_DONE,
|
||||
},
|
||||
};
|
||||
|
||||
void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func)
|
||||
{
|
||||
int i;
|
||||
|
||||
task->apic_id = (u8) (cpuid_ebx(1) >> 24);
|
||||
task->func = func;
|
||||
task->function_name = undefined;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(entrypoint); i++) {
|
||||
if (task->func == entrypoint[i].func) {
|
||||
task->function_name = entrypoint[i].name;
|
||||
task->ts_entry_id = entrypoint[i].entry_id;
|
||||
task->ts_exit_id = entrypoint[i].exit_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "\nAPIC %02d: ** Enter %s [%08x]\n",
|
||||
task->apic_id, task->function_name, task->func);
|
||||
}
|
||||
|
||||
const char *heap_status_name(int status)
|
||||
void agesa_state_on_exit(struct agesa_state *task,
|
||||
AMD_CONFIG_PARAMS *StdHeader)
|
||||
{
|
||||
if ((status < HEAP_DO_NOT_EXIST_YET) || (status > HEAP_S3_RESUME))
|
||||
return undefined;
|
||||
printk(BIOS_DEBUG, "APIC %02d: Heap in %s (%d) at 0x%08x\n",
|
||||
task->apic_id, heap_status_name(StdHeader->HeapStatus),
|
||||
StdHeader->HeapStatus, (u32)StdHeader->HeapBasePtr);
|
||||
|
||||
int index = status - HEAP_DO_NOT_EXIST_YET;
|
||||
return HeapStatusStr[index];
|
||||
printk(BIOS_DEBUG, "APIC %02d: ** Exit %s [%08x]\n",
|
||||
task->apic_id, task->function_name, task->func);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -90,8 +90,6 @@ void *asmlinkage romstage_main(unsigned long bist)
|
||||
else
|
||||
agesa_execute_state(cb, AMD_INIT_RESUME);
|
||||
|
||||
/* FIXME: Detect if TSC frequency changed during raminit? */
|
||||
timestamp_rescale_table(1, 4);
|
||||
timestamp_add_now(TS_AFTER_INITRAM);
|
||||
|
||||
/* Work around AGESA setting all memory as WB on normal
|
||||
|
@@ -20,11 +20,14 @@
|
||||
#include <arch/cpu.h>
|
||||
#include <bootstate.h>
|
||||
#include <cbfs.h>
|
||||
#include <console/console.h>
|
||||
#include <cbmem.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
#include <northbridge/amd/agesa/state_machine.h>
|
||||
#include <northbridge/amd/agesa/agesa_helper.h>
|
||||
#include <northbridge/amd/agesa/BiosCallOuts.h>
|
||||
#include <amdlib.h>
|
||||
|
||||
#include <AMD.h>
|
||||
|
||||
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE)
|
||||
@@ -146,6 +149,11 @@ static AGESA_STATUS romstage_dispatch(struct sysinfo *cb,
|
||||
platform_BeforeInitPost(cb, param);
|
||||
board_BeforeInitPost(cb, param);
|
||||
status = module_dispatch(func, StdHeader);
|
||||
|
||||
/* FIXME: Detect if TSC frequency really
|
||||
* changed during raminit? */
|
||||
timestamp_rescale_table(1, 4);
|
||||
|
||||
platform_AfterInitPost(cb, param);
|
||||
break;
|
||||
}
|
||||
@@ -155,6 +163,11 @@ static AGESA_STATUS romstage_dispatch(struct sysinfo *cb,
|
||||
AMD_RESUME_PARAMS *param = (void *)StdHeader;
|
||||
platform_BeforeInitResume(cb, param);
|
||||
status = module_dispatch(func, StdHeader);
|
||||
|
||||
/* FIXME: Detect if TSC frequency really
|
||||
* changed during raminit? */
|
||||
timestamp_rescale_table(1, 4);
|
||||
|
||||
platform_AfterInitResume(cb, param);
|
||||
break;
|
||||
}
|
||||
@@ -229,38 +242,6 @@ static AGESA_STATUS ramstage_dispatch(struct sysinfo *cb,
|
||||
return status;
|
||||
}
|
||||
|
||||
/* DEBUG trace helper */
|
||||
|
||||
struct agesa_state
|
||||
{
|
||||
u8 apic_id;
|
||||
|
||||
AGESA_STRUCT_NAME func;
|
||||
const char *function_name;
|
||||
};
|
||||
|
||||
static void state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func,
|
||||
const char *struct_name)
|
||||
{
|
||||
task->apic_id = (u8) (cpuid_ebx(1) >> 24);
|
||||
task->func = func;
|
||||
task->function_name = struct_name;
|
||||
|
||||
printk(BIOS_DEBUG, "\nAPIC %02d: ** Enter %s [%08x]\n",
|
||||
task->apic_id, task->function_name, task->func);
|
||||
}
|
||||
|
||||
static void state_on_exit(struct agesa_state *task,
|
||||
AMD_CONFIG_PARAMS *StdHeader)
|
||||
{
|
||||
printk(BIOS_DEBUG, "APIC %02d: Heap in %s (%d) at 0x%08x\n",
|
||||
task->apic_id, heap_status_name(StdHeader->HeapStatus),
|
||||
StdHeader->HeapStatus, (u32)StdHeader->HeapBasePtr);
|
||||
|
||||
printk(BIOS_DEBUG, "APIC %02d: ** Exit %s [%08x]\n",
|
||||
task->apic_id, task->function_name, task->func);
|
||||
}
|
||||
|
||||
int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
|
||||
{
|
||||
AMD_INTERFACE_PARAMS aip;
|
||||
@@ -270,13 +251,12 @@ int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
|
||||
} agesa_params;
|
||||
void *buf = NULL;
|
||||
size_t len = 0;
|
||||
const char *state_name = agesa_struct_name(func);
|
||||
|
||||
AGESA_STATUS status, final;
|
||||
|
||||
struct agesa_state task;
|
||||
memset(&task, 0, sizeof(task));
|
||||
state_on_entry(&task, func, state_name);
|
||||
agesa_state_on_entry(&task, func);
|
||||
|
||||
aip.StdHeader = cb->StdHeader;
|
||||
|
||||
@@ -294,19 +274,25 @@ int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
|
||||
AMD_CONFIG_PARAMS *StdHeader = aip.NewStructPtr;
|
||||
ASSERT(StdHeader->Func == func);
|
||||
|
||||
if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_entry_id)
|
||||
timestamp_add_now(task.ts_entry_id);
|
||||
|
||||
if (ENV_ROMSTAGE)
|
||||
final = romstage_dispatch(cb, func, StdHeader);
|
||||
|
||||
if (ENV_RAMSTAGE)
|
||||
final = ramstage_dispatch(cb, func, StdHeader);
|
||||
|
||||
agesawrapper_trace(final, StdHeader, state_name);
|
||||
if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_exit_id)
|
||||
timestamp_add_now(task.ts_exit_id);
|
||||
|
||||
agesawrapper_trace(final, StdHeader, task.function_name);
|
||||
ASSERT(final < AGESA_FATAL);
|
||||
|
||||
status = amd_release_struct(&aip);
|
||||
ASSERT(status == AGESA_SUCCESS);
|
||||
|
||||
state_on_exit(&task, &aip.StdHeader);
|
||||
agesa_state_on_exit(&task, &aip.StdHeader);
|
||||
|
||||
return (final < AGESA_FATAL) ? 0 : -1;
|
||||
}
|
||||
|
@@ -37,13 +37,12 @@ static void aspeed_ast2050_set_resources(struct device *dev)
|
||||
|
||||
static void aspeed_ast2050_init(struct device *dev)
|
||||
{
|
||||
u8 ret;
|
||||
struct drm_device drm_dev;
|
||||
|
||||
drm_dev.pdev = dev;
|
||||
|
||||
printk(BIOS_INFO, "ASpeed AST2050: initializing video device\n");
|
||||
ret = ast_driver_load(&drm_dev, 0);
|
||||
ast_driver_load(&drm_dev, 0);
|
||||
|
||||
/* Unlock extended configuration registers */
|
||||
outb(0x80, 0x3d4); outb(0xa8, 0x3d5);
|
||||
|
@@ -797,7 +797,7 @@ static bool elog_do_add_boot_count(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ramstage_elog_add_boot_count(void)
|
||||
static void elog_add_boot_count(void)
|
||||
{
|
||||
if (elog_do_add_boot_count()) {
|
||||
elog_add_event_dword(ELOG_TYPE_BOOT, boot_count_read());
|
||||
@@ -860,7 +860,7 @@ int elog_init(void)
|
||||
es->full_threshold, es->shrink_size);
|
||||
|
||||
if (ENV_RAMSTAGE)
|
||||
ramstage_elog_add_boot_count();
|
||||
elog_add_boot_count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -17,14 +17,13 @@
|
||||
#include <console/console.h>
|
||||
#include <console/qemu_debugcon.h>
|
||||
#include <arch/io.h>
|
||||
#include <arch/early_variables.h>
|
||||
|
||||
static int qemu_debugcon_detected CAR_GLOBAL;
|
||||
static int qemu_debugcon_detected;
|
||||
|
||||
void qemu_debugcon_init(void)
|
||||
{
|
||||
int detected = (inb(CONFIG_CONSOLE_QEMU_DEBUGCON_PORT) == 0xe9);
|
||||
car_set_var(qemu_debugcon_detected, detected);
|
||||
qemu_debugcon_detected = detected;
|
||||
printk(BIOS_INFO, "QEMU debugcon %s [port 0x%x]\n",
|
||||
detected ? "detected" : "not found",
|
||||
CONFIG_CONSOLE_QEMU_DEBUGCON_PORT);
|
||||
@@ -32,6 +31,6 @@ void qemu_debugcon_init(void)
|
||||
|
||||
void qemu_debugcon_tx_byte(unsigned char data)
|
||||
{
|
||||
if (car_get_var(qemu_debugcon_detected) != 0)
|
||||
if (qemu_debugcon_detected != 0)
|
||||
outb(data, CONFIG_CONSOLE_QEMU_DEBUGCON_PORT);
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
enum {
|
||||
BH720_PROTECT = 0xd0,
|
||||
BH720_PROTECT_LOCK_OFF = 0,
|
||||
|
@@ -36,9 +36,14 @@ static void max98357a_fill_ssdt(struct device *dev)
|
||||
if (!dev->enabled || !config)
|
||||
return;
|
||||
|
||||
const char *scope = acpi_device_scope(dev);
|
||||
const char *name = acpi_device_name(dev);
|
||||
if (!scope || !name)
|
||||
return;
|
||||
|
||||
/* Device */
|
||||
acpigen_write_scope(acpi_device_scope(dev));
|
||||
acpigen_write_device(acpi_device_name(dev));
|
||||
acpigen_write_scope(scope);
|
||||
acpigen_write_device(name);
|
||||
acpigen_write_name_string("_HID", MAX98357A_ACPI_HID);
|
||||
acpigen_write_name_integer("_UID", 0);
|
||||
acpigen_write_name_string("_DDN", dev->chip_ops->name);
|
||||
|