coreboot-gerrit
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
March 2013
- 1 participants
- 443 discussions
Patch set updated for coreboot: cc31999 haswell: Add microcode for ULT C0 stepping 0x40651
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2858
-gerrit
commit cc31999fe5d0522e85b7c7d78e6196353d3e8b26
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Fri Mar 15 09:42:00 2013 -0700
haswell: Add microcode for ULT C0 stepping 0x40651
Change-Id: I53982d88f94255abdbb38ca18f9d891d4bc161b0
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
.../intel/haswell/microcode-M7240651_00000006.h | 960 +++++++++++++++++++++
src/cpu/intel/haswell/microcode_blob.h | 3 +-
2 files changed, 962 insertions(+), 1 deletion(-)
diff --git a/src/cpu/intel/haswell/microcode-M7240651_00000006.h b/src/cpu/intel/haswell/microcode-M7240651_00000006.h
new file mode 100644
index 0000000..7df48a9
--- /dev/null
+++ b/src/cpu/intel/haswell/microcode-M7240651_00000006.h
@@ -0,0 +1,960 @@
+0x00000001, 0x00000006, 0x02222013, 0x00040651,
+0xc9c88122, 0x00000001, 0x00000072, 0x00003bd0,
+0x00003c00, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x000000a1, 0x00020001, 0x00000006,
+0x00000000, 0x00000e41, 0x20130221, 0x00000e41,
+0x00000001, 0x00040651, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x28f5c8c7, 0x9e112164, 0xf02f86e8, 0xf6b6111d,
+0x3c4e5d43, 0xd650ad15, 0x38aa12f0, 0xa22e6707,
+0xa19308a3, 0x5b19c4b7, 0x4a1b425b, 0x7d6a74f6,
+0x81624193, 0x3a559605, 0x5475280b, 0xe7319d58,
+0x48624ca7, 0x507af030, 0x3b32d96a, 0x30164068,
+0x5284d2f5, 0x725b2915, 0xf63c9280, 0x44b7c142,
+0xe67ca7b3, 0xd6f163e7, 0xcdf51f3c, 0x41d180a1,
+0xcc3931b1, 0xf7a544a9, 0x7f6bf77d, 0xfc45a45f,
+0xf0985836, 0x652d7e2e, 0x0324b1f3, 0x24b9548c,
+0x7bcae7a5, 0xdcdebf79, 0x27015922, 0x0c83c606,
+0x3d2ceeb7, 0x61c5eec8, 0x6b6899c6, 0x3e500531,
+0xf08bfa44, 0xb304a8f4, 0xcee8f713, 0x2912c786,
+0xfae6c34c, 0xa5292960, 0x7d63e389, 0xaa257a01,
+0x1fb25054, 0x963fc676, 0x5bcb9fd3, 0x58f369a4,
+0xf6e3beb2, 0xa58b5eb0, 0x33c7eba4, 0x37fe8b66,
+0x00714403, 0xf0fd0c4e, 0xaa122996, 0x9a55b184,
+0x00201507, 0xc9fb6e3a, 0x11ab60c8, 0x80ff6e84,
+0xc37aabdd, 0x0fc23175, 0xb0b18c34, 0xf1ec806c,
+0x00000011, 0xb446b9bb, 0x11a39f7e, 0x83a4e800,
+0xf403aa18, 0x12d1dc1e, 0x438bea79, 0xd7808b62,
+0x51b1b426, 0x7b7d0b59, 0x7ca0d77c, 0x5104e85b,
+0xcf72fbb2, 0xde64ad8b, 0x18555138, 0xd1b30f33,
+0x51f7abc6, 0xb9f5f98a, 0x63433b31, 0x020fb6ec,
+0xc83d63c4, 0x5235d1c1, 0x75f744ca, 0x1a2a203a,
+0xd2acee38, 0x0257ee06, 0x743dc8fd, 0x7092432f,
+0xd669ef00, 0x406bd83f, 0xbf41491b, 0x97f73536,
+0xfd3d1815, 0x197dedcd, 0x619286eb, 0xf463e603,
+0xc4a6391f, 0x70b5c1aa, 0xe97b562f, 0xbee42bdc,
+0xc5f9161b, 0x19c16776, 0x54677a02, 0x577e4564,
+0x3f7f0a9e, 0xf2b94d7d, 0x8a2bee71, 0xe5523125,
+0xc48ffd22, 0x7ade387b, 0x5b59c395, 0x3195e214,
+0x987839ae, 0xef23b028, 0xe9574b34, 0x084f9aed,
+0xb8d14461, 0x92ee473a, 0x5b5fc73d, 0x00460894,
+0x0b5967ed, 0x987685ef, 0x50a2550b, 0xd87522c8,
+0xbe2ff4a9, 0xe299bc1b, 0x452096bd, 0x5baaecf9,
+0xf8f1956e, 0x2d02606f, 0x87fd45e8, 0x5bf097b3,
+0x07236f9d, 0xcd6a058d, 0xbf9fa005, 0x8c7cc99a,
+0xb89e30ef, 0xad128bcb, 0x4a7e1219, 0xc2481852,
+0x19129474, 0x227d9802, 0xdb6047f0, 0x44fb7f7e,
+0xa553b7de, 0xd36cf600, 0x50b29f3b, 0xba3798d0,
+0xde788331, 0x344dac23, 0x63716887, 0x835d6c94,
+0xc1c178e4, 0x68fae96d, 0x5a50782e, 0xb6054e32,
+0x3a501249, 0xe2fe62da, 0x778a6b05, 0x7de9f5fa,
+0xc0a1a476, 0xf765e134, 0xf9906b29, 0x4c847ede,
+0xd721564e, 0x37c16584, 0xfcfa7c80, 0x8b7c405d,
+0xe0929d68, 0xc21e8810, 0x96e75c1a, 0xd07a402f,
+0x1c42a7c1, 0x97f0146b, 0x8fc5d3f3, 0x3dace643,
+0xeba6869d, 0xf67391bd, 0x5f5cb5b5, 0x74fb3b28,
+0x7a9e587b, 0x33ca7543, 0x2e0775aa, 0x9e1097be,
+0xb019ad1c, 0x79642e86, 0x6ab5e4ba, 0x470d2670,
+0x6fd90246, 0x65c3c566, 0x39a298f5, 0x7b779f08,
+0x1f4a965f, 0xead217d9, 0x7e538c63, 0xdf71122c,
+0x2d8e5893, 0x650a8b5b, 0x07848c67, 0x5a5a9714,
+0x8d4884c2, 0xae30cbeb, 0x2a75f5b2, 0x5ad9ef89,
+0xe6f968d6, 0x4976db33, 0x2aae8868, 0x54a0f425,
+0x938be96c, 0xe4779ace, 0x15f6d58d, 0xd9773d3a,
+0x7986c83d, 0x58a8f3b2, 0x3d927e9c, 0xb981d8d6,
+0xfc5b69b4, 0x816c556d, 0xb79d4dac, 0x56c72592,
+0x30793478, 0x52792616, 0xdd3368bf, 0x8615f67c,
+0x9e9ad64e, 0x21986208, 0x52cbf75b, 0x99158bf6,
+0x90a4bb94, 0xd101ccdd, 0x7f9893bf, 0x95d654ad,
+0x75747d0c, 0x2a0aed08, 0xd51abee7, 0x0b1a1664,
+0x44dba341, 0x76435331, 0x1ed332d7, 0x86af2c20,
+0x5a14dcf0, 0x720af164, 0xdb03b43d, 0xf0434592,
+0xcd374221, 0xbe6cb668, 0xc7fe200d, 0x9024aa11,
+0x98973a68, 0x45854fe5, 0x42fbfba1, 0x7ecda23c,
+0xd3810753, 0x94a2dfd9, 0xa6d9c615, 0xb01f739c,
+0x072672eb, 0x5f71c0d3, 0xbcb5e5b5, 0x4bd6829f,
+0x9357c942, 0x7d2dc61c, 0xdc737d79, 0x0e8069b9,
+0xa6a8948b, 0x824cb986, 0x8712ca46, 0x88a6e076,
+0xf6e4bdd4, 0x125194ba, 0xa6c566b0, 0x21b6ae11,
+0xb0e55a44, 0x1c71d4d9, 0xdcb7b53f, 0x8d9aa903,
+0x3b2f3e5e, 0xba0a80d2, 0xd81b15c3, 0xf8b69b19,
+0xfc4f4ee6, 0x371aff7c, 0xf977d01d, 0x6753eb49,
+0xf8c6aba3, 0x52a32da8, 0xf8bc09a9, 0xafaae176,
+0xbd1a2509, 0x9c4ba2f7, 0xf2c5117b, 0x408fd867,
+0xb417fd42, 0xf7c63c92, 0xd7817632, 0x45820959,
+0xe3180104, 0x95f3cf3e, 0xa758b59c, 0x887a8fe2,
+0x3dd7a338, 0x5a73b3ca, 0xad7db285, 0x1ccbb377,
+0xf7dec7f9, 0x9bbf2b6b, 0xe05ab128, 0x3d92924b,
+0x61c63664, 0xd544d18f, 0xba6ddcb4, 0xec691bc4,
+0xd5ffea1d, 0x4a06c0a8, 0x6fbc8ca8, 0x75676b0d,
+0x0f557867, 0x9fa53efd, 0xc7e736fe, 0x0580f0c1,
+0xbceac219, 0x8f8e0bbf, 0x0cc23b6f, 0xb81dc329,
+0x7e0b8083, 0x3a80b402, 0x4dd57a81, 0x1026ba1b,
+0x63f8d61a, 0x33aa33a8, 0xfbb2388a, 0x2db9444f,
+0x1b2337bf, 0x68a9e70b, 0xb0278540, 0x04ca1d3f,
+0xdda4cbba, 0x07285957, 0x2bb2ad49, 0xbc3c632e,
+0xdb30073a, 0x3485ea61, 0x728c610a, 0x26d911fc,
+0xd9079ed1, 0xdb5ed68e, 0xe8015226, 0xc674c819,
+0x8245885c, 0x1e78f037, 0xec3f2319, 0x2218c785,
+0x5233ddb2, 0x22ad3fe8, 0x627f3680, 0x34be829c,
+0x68db8e7e, 0x648fa39b, 0x50be8c93, 0x76e8032a,
+0x9d6bc072, 0xe4cb2873, 0xdd4659e3, 0x4ca89b06,
+0x68cee095, 0x331b6344, 0x8b42e6bd, 0x189f545f,
+0x810656bb, 0xdef5199b, 0xe95eb90a, 0xaa8fa334,
+0x9f74279b, 0x7a0cfa6f, 0xaebc1cb6, 0x453573ed,
+0x39873714, 0x84ea8dd6, 0xeaa7d8ac, 0x753f045e,
+0xed5a38fc, 0xd15b3135, 0x9bcb2a47, 0x3bec4c99,
+0xffdce6e3, 0xc172bfc1, 0x5086aee0, 0xf3df0a2e,
+0x90efa3b3, 0x29d3bcfd, 0x2feea67c, 0xad1ad1fb,
+0xb8a68400, 0xbd7e92e6, 0x0181a4ed, 0x72a0d21c,
+0x6ec9cd1e, 0x4470dbcc, 0xcb62bb94, 0x2e9f2616,
+0x71f85a2c, 0x4e645795, 0x4c0b3aaa, 0xefc2fd2e,
+0x12126c51, 0x5fe0b2bd, 0xa2ea0296, 0x241aab09,
+0x3ff9e277, 0xfec1e535, 0xa1862c20, 0x1d388628,
+0x15bac0e6, 0x5107fc7f, 0x017c73c4, 0xb45e3354,
+0x1e20663b, 0xc155ab92, 0x702600e0, 0xd42bc23e,
+0x235caab1, 0xca8e02b0, 0xdfc5efba, 0xb99d7766,
+0x709eee81, 0xc0f9742d, 0x3cfbf530, 0xafc0cb77,
+0xa1d97cce, 0x1c7e8e9f, 0x99405b33, 0xe17f2274,
+0x3270f9b9, 0x2f702761, 0x50c87113, 0xe9fbc2c5,
+0x598d7a49, 0x1ebf50e8, 0x69e46dba, 0x45a0e13a,
+0x531dea3a, 0x4f167a0f, 0x50301d05, 0x011ec979,
+0x046416ac, 0xf8f24e19, 0x52abb228, 0x586163f8,
+0x83a4f211, 0xdf42625b, 0x59549ea4, 0x2f1e65e6,
+0x9fe42b62, 0xc0d869d1, 0x6615ef68, 0xa2687bce,
+0x49a46a7c, 0xe9dd362b, 0x0bb5d2e4, 0x0b19630e,
+0xe121854d, 0x0aa9ab28, 0x715231f7, 0xda126b34,
+0x4935896d, 0x92d0d59b, 0x2865b221, 0x2d7659a5,
+0xcfdaaa5f, 0x4b3df303, 0xdb6ee69a, 0xfd8acc6d,
+0xe9f0f278, 0xbe73c6ea, 0x79a6cc3a, 0xd0ec7aa4,
+0x6f4f3211, 0xe5ceb325, 0xedcb8bec, 0x3c06567b,
+0xfc4020db, 0xe4514d36, 0xa6efdf9a, 0xd1027491,
+0x22ac2657, 0x9573ce20, 0xb975b125, 0xc2a43590,
+0xf2bd1d69, 0xa65d09fb, 0x791ad65c, 0xb22629c4,
+0x00d8f643, 0x10c31e80, 0x59366171, 0x1c5eae00,
+0x66fc579e, 0xa9cd3b65, 0x52b251a6, 0x80601bcf,
+0x96310f9a, 0x9750dd48, 0x8b893602, 0x38a25b68,
+0xdc6a3b4d, 0x627b969c, 0x31a0702b, 0x73c624ca,
+0x7fc4eef2, 0x80c81884, 0x117f023f, 0x3e981c1e,
+0x873d99ca, 0x9bfc9459, 0x0be5af0b, 0x3c257880,
+0xb8cf77b8, 0x11949c50, 0x47114468, 0x80f91bbe,
+0x442cd2ab, 0xee976c2e, 0xcefe1a32, 0xef5ebaeb,
+0xd573c27e, 0x2978d764, 0x653eddfc, 0x85a6910a,
+0x644a1dce, 0xd194a1eb, 0x3103ca3a, 0xddf7c31e,
+0x502d1c7b, 0x9ea11aca, 0x8415e1be, 0xc8b5e6b7,
+0x737ec3d1, 0x0025a1e8, 0x2d10e23e, 0xe1cf25c9,
+0xd93f9834, 0x5f176c76, 0xed90f0eb, 0x5bfd86a7,
+0x0572ccd4, 0xd70c8a08, 0x850da421, 0x0daab877,
+0x619e62e6, 0x18c6cda2, 0xc6893dfd, 0xa89177db,
+0x7f1797fa, 0x949da24a, 0x3243a802, 0xc98709ed,
+0x99134653, 0x671a8b96, 0x5fed050f, 0x78425038,
+0xf4d43815, 0x114618a8, 0x75a50583, 0xb8ef5853,
+0xbcdff144, 0x10b07fca, 0x99ed97bd, 0xe815d87b,
+0x948c0a51, 0x8573a114, 0xf28e0f59, 0xc12cb20e,
+0x8aa754d1, 0x199dc118, 0x5fdf32ba, 0x57146859,
+0xa4941b44, 0xdcc65dad, 0x6bec0038, 0xeadee691,
+0x635fc01b, 0x70e7ea43, 0x6f3e679d, 0xb04deb01,
+0x96aba9ef, 0x0409473f, 0x6c69818a, 0xd41e74bf,
+0x822f563b, 0x6b224567, 0xc9583923, 0x64460243,
+0x6fab20e5, 0x20b85a7d, 0x7ff6c610, 0x84ce4172,
+0xc2242380, 0xd512c67d, 0x2f1c7df7, 0x55289339,
+0x8cfe618e, 0x14ebf8cb, 0x7b562bbc, 0x37b512cd,
+0x5c07cce5, 0xb8020aee, 0x9a91c3a0, 0x3be3adf3,
+0x50ffc652, 0x76d2ae8c, 0xafc3153d, 0x6ec9e9ca,
+0xfc7908f7, 0xdb95584b, 0xe9195fa7, 0xa68ccbfa,
+0xfb5c972f, 0x9f8c7d1c, 0x0bf06c92, 0xe1581091,
+0x1fe6f263, 0xff2ef660, 0xd3207637, 0x63c75e6c,
+0x6e058902, 0xd2b7fc96, 0xe624c80f, 0xd9567175,
+0x07a2f14d, 0xea931882, 0xd82b83e6, 0xef0333d2,
+0xc9aefaa5, 0x9cc369a9, 0x2f8d3dde, 0xd357d196,
+0xbf34448b, 0x568a4927, 0xa011c011, 0x842b8e78,
+0x5f713235, 0xfc9635da, 0xe32b8035, 0x993efdc7,
+0x662b2e4c, 0x203c2fda, 0x1a637a9d, 0x4ffb9037,
+0x8750b84a, 0xc0678521, 0xa409c34e, 0x87beeb49,
+0x2b9c74ed, 0xaaaab901, 0xfc00020d, 0x31450438,
+0x0115b209, 0x9c6000e3, 0x34fbc4e7, 0xe4904905,
+0xb18ba3fd, 0xf59461e7, 0x0cfe1630, 0xc9fdf2a3,
+0xe778d88d, 0xac018200, 0xb71fea46, 0xe303e55f,
+0xce7e8ed7, 0xb84a943e, 0x6e2cdd1d, 0x6cdba37d,
+0x488d4d64, 0xc7956242, 0x1a8056a8, 0xef28092f,
+0x205bcdd9, 0xdb000225, 0x60592274, 0xe2b5e6a3,
+0x61f0299e, 0x826c08b4, 0x5840da4b, 0x7b38f75a,
+0x02435a81, 0x0411fc4e, 0x27d53980, 0xb68be32f,
+0x66c7132b, 0xe5095758, 0xb5369c1d, 0xcd36f9e0,
+0x4b3cd470, 0x815c94b9, 0x188df989, 0x2ce8d855,
+0xaa643e10, 0x79800fbc, 0x3e5b5471, 0x0d894001,
+0xbdbb3801, 0x9ff9f719, 0x1cd71921, 0x17ef534b,
+0x0c779b3d, 0xcfe872ac, 0x4f810fdd, 0x83017c60,
+0xbfec9761, 0xebace400, 0xe2dfb6ee, 0x18d62ca4,
+0xae3b101d, 0xacd56190, 0x6fb19c2f, 0xc01a2110,
+0x677fefcb, 0x792a248a, 0x83c8d7ff, 0xfd1365ef,
+0x64e955b3, 0x61a37834, 0xc4141d09, 0xd85ace5d,
+0x67b146dd, 0xdfcb7a9b, 0xcd76894a, 0x0465e1a0,
+0x2abd5dd7, 0x832d6077, 0xcff6633e, 0xcf03bd51,
+0x524b04d8, 0x98bf7f34, 0xcf495873, 0xeaa6d8b8,
+0xaa928eda, 0xd1d364c7, 0x3c93d762, 0x7a64ffc6,
+0x0a8037f6, 0x92000ece, 0xf4e3195d, 0x01c4ee4b,
+0x9612d484, 0x941bc1eb, 0xac0a1f83, 0x4c8be21d,
+0x7800d3b8, 0x61c76ba7, 0x1c2145e0, 0x91a403b5,
+0x71315117, 0xacbf80ec, 0x5e42a85d, 0xf215e0f4,
+0xc493e5b2, 0x2360435b, 0xf094ce88, 0x324b3e06,
+0x659eb9d9, 0xdebb6dd3, 0x248d35e2, 0x7684d9ba,
+0xcbd387b1, 0xa6467cb1, 0xb562ee9d, 0x468e53b9,
+0x8bd38964, 0x470b2b7a, 0xde131b58, 0xc4c2ba37,
+0xb87d47b4, 0x68c86e09, 0xb48567ca, 0xecd6ceb6,
+0xf6d4091d, 0x04c6fab5, 0xedd1f977, 0xb4a25d69,
+0x37499fdf, 0xb0c02112, 0xd4a927b1, 0x62041ee0,
+0x7fc53271, 0x8b66957a, 0x0e21ca06, 0x12154793,
+0xf3463d4b, 0x1afe8d79, 0x934b1044, 0x6aca9c9e,
+0xbfc1f26e, 0x62352d63, 0x67d8aa9e, 0x9c075ef8,
+0x0dfd401b, 0x1928628d, 0x90d1c980, 0x986d1689,
+0x4dfecca5, 0x02aa70bf, 0x2fd5010e, 0x6b595451,
+0x63767819, 0x82d63750, 0x73dfa2f1, 0x460ce4c5,
+0x52113035, 0xe600faea, 0xbb91197e, 0xa9c6a682,
+0xd0d3a7f7, 0xce342b0e, 0x1e87f0bf, 0xe800dfea,
+0x29b14f0e, 0xbc430364, 0x1e5524f8, 0xc7366dcb,
+0x769ea9a3, 0x2a7f71e0, 0xd764e720, 0x9deed5cd,
+0xcfe424b0, 0x35816bc3, 0xe05f58ca, 0x4b5e7322,
+0x9ff4259e, 0x535f805e, 0xdc6a4590, 0xb4e4f87a,
+0x2f414aee, 0x44106f70, 0x462a6abc, 0x8f8424cc,
+0x6cd666bb, 0x1bbd9ad3, 0xc8b5895b, 0x1f1a3d04,
+0x45f7f5a4, 0x677e959b, 0xf96fbd87, 0x4eda1f8c,
+0x9ce7f266, 0x9f89a83e, 0x625b11f6, 0xf8a14ae9,
+0xa1b74809, 0x5c0a2767, 0x57041d2e, 0xfc677b51,
+0x7f9cadaf, 0x5b973281, 0xff4037d1, 0x731b118b,
+0xfb7a03ce, 0x68caba11, 0x0fb4721e, 0x5c35cf30,
+0x7c4baf0f, 0xc86dab09, 0x75e4e9af, 0xd8d32796,
+0x10b23123, 0xde91d224, 0x4976a748, 0x9c05cfff,
+0xa4988e9e, 0x08501676, 0xe67878fb, 0x50a0070e,
+0x981049c2, 0x6d7913a8, 0xe2fabd7d, 0xfd182706,
+0xe6f94d8e, 0xd6a8bcb1, 0xc6b15c51, 0xf33c8e80,
+0x6ecd2ecc, 0xd5a68dcb, 0x9dfc5334, 0xfb5ea241,
+0x3a2f72e5, 0xca46e813, 0x431b8b8e, 0x6febccda,
+0x49839ce1, 0xf3bb3160, 0xd73a25d8, 0xaf9f28b2,
+0x38fc3477, 0xdb4a6323, 0x4033330c, 0xfccce782,
+0x89e1de9c, 0xeb1525ba, 0x83f8d0f6, 0x46605021,
+0x8935829f, 0x7062d709, 0xfb00a81f, 0x2169c690,
+0x281ed324, 0x5cf5e518, 0x035f49de, 0xdaddf93e,
+0xbace8d92, 0x44f104f0, 0x1494026c, 0xeca404f3,
+0xfc7e17c0, 0x9550ba9c, 0x4b12d482, 0x2879812c,
+0x85e9599f, 0x911bdd00, 0xa9eda77e, 0x360e081d,
+0x78ca0e8d, 0xb8da0b26, 0x4e9caab5, 0x20fbbd28,
+0x45b00578, 0x9be52a42, 0x3b3adfb7, 0x8e63140e,
+0xdc12c7d9, 0x8a47baa8, 0x333aa390, 0xe0d660fb,
+0x486371b3, 0x285fa010, 0x886d827c, 0x051b9d65,
+0xbba94b67, 0x17d84a96, 0xf0a66f79, 0xccf282d5,
+0x23ce6a92, 0xae2e0000, 0x48089dd8, 0xe8861ab2,
+0xb4bfb958, 0x2bcf25b5, 0x503f269f, 0x1b70d243,
+0x5bfe2415, 0xfbd32a52, 0x2f26b1ad, 0x06bbc224,
+0xf0f26f1a, 0x2de81fef, 0x50fe8ca4, 0x96ef22b4,
+0x47091853, 0x761ee27a, 0x63daadd4, 0xa789f906,
+0xcd9c27b2, 0xbf435f5c, 0x566d6231, 0xd42b0e75,
+0xfcff2ef1, 0x7a794a7a, 0x5b75e982, 0xefcf56bd,
+0x039d19c6, 0xebf156b3, 0xb7e4321b, 0xe21ce160,
+0x0c10f33a, 0xeefae4cf, 0x75d84717, 0xef3d258e,
+0x726d7b3b, 0xd4b7c671, 0xbaa0d837, 0x85dc8b73,
+0x427d805a, 0x98af49ec, 0x5590eaf6, 0x21d347cb,
+0x070c912f, 0x3c47624a, 0xa39ce494, 0xc29b7745,
+0xed27a280, 0x6a3074cc, 0x22302c0e, 0xb3a597bb,
+0x9e2feaa1, 0x165a69db, 0x1c525060, 0x70524264,
+0x1b869d99, 0xed1ec4e1, 0x6a2bf925, 0xf1babe28,
+0x1fbe4e7e, 0x020cfeeb, 0x95fdf645, 0xd0a74567,
+0x2b70274d, 0xcbfdc79c, 0xf057f195, 0xbcc9adfd,
+0x52e3bc04, 0x0754f675, 0xce7a72db, 0xd0cd06bd,
+0xe40d3511, 0x30bf2517, 0x505df290, 0x2238136f,
+0xf45e1246, 0x500eb35d, 0x78668ef3, 0x30da8b8f,
+0x6a9181d8, 0x9dd1320a, 0xdf416ea6, 0xb3283c78,
+0x61d83cb1, 0x5eb143af, 0xb3125e66, 0xfe1f6b8c,
+0xb003cf08, 0x7a6a9f8c, 0x20a514d2, 0x76063b90,
+0xd2633f18, 0xd556ae32, 0xc9621dd3, 0x92f56c58,
+0x0c148404, 0xde8c6cfa, 0x7aeb8e7c, 0xde8df7b2,
+0x44466456, 0x3b680854, 0xc82639c5, 0x7b9721df,
+0xcd18a5e5, 0xcccc452d, 0xc5e52e62, 0x93fee698,
+0x8283de78, 0xa30a633b, 0x141f50fc, 0xaff73f5a,
+0xcc10bbe1, 0xf902c092, 0xa588e45c, 0x670e6d01,
+0x81b983a8, 0x0f050d23, 0x5bd740d7, 0x4999abc0,
+0x0c57106e, 0x2b52cc23, 0xf45806b3, 0x634bf883,
+0x4d2a61ca, 0x824d80f3, 0x4628188e, 0xb4f546a1,
+0x6d4e3827, 0x8003f015, 0xbc1b9bce, 0xb39e014b,
+0x0c3f3816, 0xb176ba07, 0xaddbf865, 0x7ee1f1b8,
+0xe4265881, 0xba7ac132, 0xf1297d80, 0x03657fd0,
+0x2fff7cee, 0x5730fb0b, 0xbd82aa45, 0x3b73392d,
+0xac7ff8ba, 0x24eb3509, 0xdebf48f7, 0x3f677574,
+0xfaebe27c, 0x0fd6057a, 0x2b174c7d, 0x19cc475b,
+0x86a24948, 0xf93b486a, 0xec4b3229, 0x5ff55583,
+0x15c66f53, 0x4943cf48, 0x78f21980, 0x049dafd4,
+0x741e70de, 0x5ddeee61, 0xb447d639, 0x2abea882,
+0x27bcb7bd, 0x0d97a7db, 0x24a45573, 0xd3ff84e1,
+0xb29edea8, 0xff9d4169, 0x34847315, 0x6f7306a7,
+0x82506253, 0x00171a65, 0x35e28463, 0x9508b7a8,
+0x75fa250b, 0x065d477b, 0x34249304, 0x9cf82e8d,
+0xc49c9c3d, 0x796150ea, 0x02ee27e5, 0xdbe0e114,
+0x0ceb7c06, 0x8658b12e, 0xf934a16a, 0x08b6c3d5,
+0x789d90f9, 0x3494c445, 0xdde09cc8, 0xf7470770,
+0x4f97ded0, 0x3591ff55, 0x49cd8020, 0x5ed34825,
+0x1b156b21, 0x8ced7603, 0x4f481da2, 0x5092d16d,
+0x2ee6ebe1, 0x17afb1a5, 0xc7b8382e, 0xb1ea3a85,
+0xa2ce0013, 0x49a2764b, 0x521d82f4, 0xb4d3281e,
+0x5346b8fa, 0xea0d859b, 0x491e5556, 0xa244aa3f,
+0x01612757, 0x391098eb, 0xf15611e1, 0xb548c503,
+0x93130d80, 0xb822cd1b, 0xaeb8413e, 0x3677716a,
+0x5aa1e8e3, 0xd9df3a26, 0xa45d23e1, 0x138cf8d1,
+0xd5bb81c5, 0xd5b3a6b6, 0x6450c940, 0xf9dcb5ab,
+0x89f42817, 0x6bfa9846, 0xfb599b34, 0x58286624,
+0x880b2850, 0xba0bd7d8, 0x23f9b1f5, 0xe634893d,
+0xb55626b0, 0xea88afe5, 0xf3317948, 0x45b3c314,
+0x12ef60cd, 0x861f0298, 0x9df9b7d9, 0x750bc728,
+0x0107a026, 0x92d075e9, 0xa4cb738a, 0x4d80a3bd,
+0x2ecbfc2f, 0x2ab8405e, 0x00806d49, 0x54cfd69d,
+0x5f627f6e, 0x52adade3, 0x0d43439a, 0x26bd04c1,
+0xdec4adaa, 0xd09365b3, 0xb07e6b69, 0xaec00374,
+0x872fc813, 0x12d513da, 0x49fc1378, 0xb62fa8b3,
+0xecf5b71a, 0xe1b7cb2a, 0xfcfc3cf5, 0x007b80dc,
+0x272398c3, 0x2eb19c04, 0xbf3427e2, 0x99bca982,
+0xe124481d, 0x08d93963, 0x0533e624, 0xa662297c,
+0x0b4787a6, 0xb647b150, 0xec81da7b, 0xa71fa2d8,
+0x6a6cdbda, 0x81ac8f38, 0xfb2a6a22, 0xee381b76,
+0xdf04c6d4, 0xa7cf9808, 0x922f74c5, 0xcadb536f,
+0xe2eb0414, 0x5ef67bc4, 0x4cd7055a, 0x5efb33af,
+0x15a6f90a, 0xf374b7d3, 0xdc8e1c81, 0x7d7a1380,
+0xe45a11d7, 0x47d86b2f, 0x687fee01, 0x91dcc48f,
+0x13a3fb21, 0x0d962225, 0x81d6b2c5, 0xc6f9472c,
+0x5e3cd85c, 0xefea9ff4, 0xaf23cdbb, 0x855b6c85,
+0xbebe0361, 0x93749508, 0x9d73271d, 0x2ed98ea7,
+0x982bad4f, 0x0b7d849a, 0xeb296a70, 0x1ede4d5c,
+0xfd456e8b, 0x6e68d5cb, 0xcb05eca8, 0x783d4205,
+0xf44a90e1, 0xdf369d1b, 0x6d770e65, 0xf2b3d175,
+0x3750a53d, 0xcb41d546, 0xfc090b92, 0x1e793bfb,
+0xf95e220c, 0xc9489628, 0x19330ddf, 0xbb3ed7ae,
+0x5fcff880, 0xb73467b0, 0x2ffb94e1, 0x3cf4f68e,
+0x364132c2, 0x162f0fc3, 0xb6e61410, 0x7d923452,
+0x7437d978, 0x3d4e5f87, 0xbccae82b, 0x3f766f7f,
+0x01b20414, 0xf938c74b, 0x5b40b872, 0x82265389,
+0xeec17bf5, 0x05debd79, 0x233c02a6, 0xda9c6156,
+0x5f721f56, 0x411a0b1f, 0xf7ac4162, 0x737685db,
+0x59f2d52a, 0x05e789d3, 0xe5f3cb54, 0xf21edfca,
+0x1bab963c, 0xf2e1264e, 0xf64b54c4, 0xf2c954ad,
+0x500415b6, 0xaf0b4e2b, 0x7efa90b0, 0xd599c9a8,
+0x1db78fda, 0xe46f9a0c, 0xfea4711e, 0xb6cf82ee,
+0x1bccb9c8, 0x8f1c0d24, 0x4030215f, 0x4650a709,
+0x40faa996, 0xe931dbde, 0x69325d9f, 0x3b9eb821,
+0x1fe4513a, 0x56cabe26, 0x3a4e0a87, 0x736b4a20,
+0xb7518f04, 0x39d42642, 0x9fd7fb23, 0x10c9e73a,
+0x636f73f1, 0xc527f2fe, 0xa26a30eb, 0xdf37179d,
+0x514c4aa2, 0x35e9c3b7, 0x44a5d905, 0x4beaf2f8,
+0xf19f5f94, 0xc2fce14d, 0x84d6d019, 0x5d727a52,
+0x89c23872, 0xba4b24d7, 0x56fe9fd0, 0x0a094a06,
+0x49032487, 0x20a05f63, 0xc5c41fa5, 0xc2bb20ba,
+0x50aded39, 0x87c1acf4, 0xd673ab01, 0xbb675253,
+0x4c4a51cc, 0xb81efc6f, 0x761c7a06, 0x70f409c5,
+0xb35f2bf7, 0x94b1842e, 0x221c684e, 0x275f3df6,
+0x85f13440, 0x5e975c05, 0xcd68aef9, 0x1905171c,
+0x83a63d24, 0xda77c1e9, 0xd904745d, 0x7e145218,
+0xb6dc967a, 0x160d4c41, 0xa657f9d6, 0x298d1599,
+0xeb9e1714, 0x9094b1c2, 0x2b328c96, 0x8ec92de9,
+0x65df7282, 0x697e7cc7, 0x5eaf7cfb, 0xf85f2b2c,
+0x3a8dfcc7, 0x104d27e4, 0xfdd36c08, 0x0e710d9f,
+0xbfa2a9ff, 0x3084621c, 0xa783b3f4, 0xc0a92b67,
+0xe0f41153, 0x422ab6e1, 0xcc09e15a, 0x12624d90,
+0xe04e68c4, 0x8e7e5fe9, 0x73fc577c, 0xf06d31cc,
+0xdc6933a9, 0x7b46ca45, 0x82a1ef8f, 0xfe3f2f93,
+0x09133db7, 0x8707ec96, 0x933b15dd, 0x83ee88fa,
+0x64329b72, 0xeb83294a, 0x6a1979fd, 0x76e135d0,
+0xfb82d0f7, 0x0eb5ab40, 0x3238ddc3, 0x17e1895a,
+0xab09fec3, 0x9b01aa2b, 0xe5dffb13, 0xd7b89a51,
+0xfd97e2d8, 0x31e8baf8, 0x0a844bd7, 0xe92c2a3f,
+0xf723fd28, 0x8d8dcfee, 0x45997de3, 0xf3f66fb8,
+0x9c6ed175, 0x9d09a91c, 0xcf687a76, 0xaa0a1bb2,
+0x9abc05ac, 0x54da0c6a, 0xb013d20b, 0xb3a60e8d,
+0xa4041564, 0x721c69f0, 0xadcbb137, 0xa78da1fd,
+0x61eb8f2b, 0x20b80206, 0xa7fef9e3, 0x43e69780,
+0x2e7d2105, 0x1fc2c0d4, 0x9e4a035c, 0x1d391a13,
+0x7dc62265, 0x1ead5933, 0x496ce97c, 0x3ab8ae44,
+0x36c32802, 0x5946844d, 0x0db8cfcd, 0xdf2dc77f,
+0xbc99385d, 0x7da63575, 0x60313d5b, 0xa63067bd,
+0xbd38b29d, 0xd8499661, 0x70cf216c, 0x27df62f7,
+0xc8375fd0, 0xe5860a15, 0x43eae7bc, 0x634b776d,
+0xda322f70, 0x4845c62b, 0xd203ddc6, 0x88772a73,
+0x4245859c, 0x86c9fe74, 0x6b1fcb93, 0x44d87f32,
+0x78b663a5, 0xafe103e7, 0xf37af1ba, 0xc7500cae,
+0x732cc784, 0x3ae33be5, 0xc8fc57bc, 0x9f5afb1e,
+0x5c08d7ff, 0xb153b9cd, 0x996b8fdd, 0xd9bb40ce,
+0x59108156, 0xf53aebb3, 0x08e848c5, 0x533d36e3,
+0x30415ad7, 0xe6c795b2, 0xf14f368b, 0xb1c47026,
+0xc19d5168, 0x2d1ee985, 0x21ef2cb0, 0x19e33330,
+0x2e585ebd, 0xc7c92471, 0xe52bc348, 0x5248d0b7,
+0x8f8047f8, 0x7860d087, 0x8d9daac7, 0xe348534d,
+0x5cf2542b, 0xf530b329, 0xec9d35cd, 0x22c3211e,
+0xd78fa2d9, 0x5ccd4afa, 0x36b43086, 0x41505ff0,
+0x6ef8b8b7, 0x8d21e267, 0x8019e2b5, 0x42fb5d92,
+0x91e20727, 0x6fe8c69a, 0x1892ee32, 0x67c63f18,
+0xbca72002, 0xd7d9ae20, 0x93c2c8a9, 0x187fb44f,
+0x4df76754, 0x4a112103, 0x68477de4, 0x00538e8a,
+0x84a6f4cb, 0xff74b213, 0xed0d9c8d, 0x307a372f,
+0xf23193d7, 0x9df266c0, 0xcd9131bf, 0x4d7884fb,
+0x44966696, 0x0323c77d, 0xadfeb668, 0x1fa2dfd9,
+0xb7578c63, 0x8a5d9856, 0xc81985f3, 0x023d8dc3,
+0x343a277f, 0xa053964a, 0xc8708064, 0x75c88148,
+0x1a1bc416, 0x9713a3c8, 0x01a0c6f0, 0x8200f404,
+0x8c3d5ac1, 0x0b531f90, 0xdc7e8197, 0x9cde055b,
+0x03d0f726, 0x5f8cb39d, 0x40079754, 0xb86cf3ec,
+0x95d281e6, 0xcdf73d3a, 0xfd1ca798, 0x47b51ff3,
+0x26bd82d2, 0x4f7f628a, 0x42121ddf, 0x0263d3fc,
+0x4afbaf1a, 0x0c4dea1e, 0x01b741ae, 0x7a438bd0,
+0x8b820fc9, 0x4b9314a1, 0x09ed960d, 0x867ae17f,
+0xa7da11e1, 0x4eeaabb0, 0x92b6b767, 0xc46ae3de,
+0x1fa58ac6, 0xbc14be04, 0x2c3bcb62, 0x7b8ca13f,
+0x55b67258, 0xdb2414ed, 0xf4780715, 0x2da33f59,
+0xd70c2321, 0xace0a988, 0x3a74466f, 0xc873c6d0,
+0x08837ba9, 0xed33318b, 0x8d97ccce, 0x2dc948c2,
+0xd7fab572, 0x6af225b4, 0x16791847, 0x49979d55,
+0xc7aa0238, 0x2696b7e4, 0xaf90c8d6, 0x7fbd7b43,
+0xd5cb34bb, 0xff46949b, 0x73f931f8, 0x31d8b57b,
+0x41fa3917, 0x44e97506, 0x52a469b3, 0xbdd21daa,
+0x30488f02, 0x6ee3eb1f, 0x4808aad2, 0x78ff0ca8,
+0x826cead2, 0x1e71fc21, 0x1fd81641, 0x714c9f08,
+0x71ac1f39, 0x11253412, 0x92a6d60a, 0xb496409e,
+0x3e241151, 0x67a8818c, 0xfd00854a, 0x7a70361c,
+0x5dda0c1d, 0xdb7887a3, 0x26dcdb04, 0x6a7d588c,
+0x81e0c55a, 0x54d2a698, 0x62048e52, 0x7c2ba376,
+0xbe2b2b01, 0xa5dd0bac, 0x1b7d4ee5, 0x23e040b8,
+0x76c285ef, 0x4c2b01ee, 0x34eabd03, 0x264b6261,
+0x99643856, 0x115b4e72, 0x86b5ac49, 0xeb040d41,
+0xe343e96b, 0x98e31e88, 0x44de4837, 0x1bb1ef9c,
+0xb83c86c5, 0x1a52eeb0, 0x1f90f598, 0xbe7e172c,
+0x67cd8bc5, 0xdc130e0f, 0xe2a1c399, 0x690a1f1b,
+0xe75f6b88, 0xd4c62760, 0x9db2e144, 0x44a6a42f,
+0x01eb64fa, 0x27e5c6a2, 0xd08a423e, 0xf5c24ac1,
+0x56a616d4, 0x5d3c11e8, 0x9f452f4f, 0x106efdf6,
+0x782a9dd2, 0xe3de8e3e, 0x0d0a1c9c, 0x6f2b937d,
+0xf40074f5, 0x49b99d8e, 0x80a94818, 0x7d859cec,
+0x62f9deb9, 0xf4b2d5aa, 0x29c9558c, 0x03db82b0,
+0x3e151f8d, 0x80f48bdc, 0x13dce759, 0x1e44419a,
+0x9fc16b8f, 0xcd11ed93, 0x3b83734b, 0x197d0630,
+0x1f0e8c94, 0x3c23d1e6, 0x6cd6588f, 0x61328b1f,
+0xda81cee7, 0x0abfb164, 0x6855b84c, 0xa6ce1d24,
+0x2b8a9ff5, 0x4358f5b3, 0x3715d36c, 0xf0392717,
+0x460873ef, 0xe632b3ac, 0x429a73fc, 0xe6c0d570,
+0x778dbce1, 0x45cf770e, 0x932fb6e3, 0x813b228e,
+0x89c4c5eb, 0xbfef781c, 0xd92a513b, 0x85fc3596,
+0x763ecced, 0x614f36a3, 0x256a64de, 0x273cf78d,
+0x835607ee, 0xe12fc92c, 0xcd39cadb, 0x8a57dc40,
+0xe9ad11e9, 0x0a838cb7, 0xdfb5bc90, 0x03db53b4,
+0x2c8440fd, 0x1883a3d8, 0x52b9faa4, 0x85865cba,
+0xe262cfb7, 0x1d4f330c, 0x5cb42da3, 0xa17dbdfe,
+0xf70726cb, 0xc85425c6, 0x95b2fd6d, 0x097eb5e4,
+0xbadbd483, 0x62f7f615, 0xa31b1f8a, 0x6bdbde11,
+0x7cb6d971, 0x683dbe82, 0xcce63573, 0x0684b015,
+0x84693d3a, 0xe07cf230, 0xe92029a5, 0xd8b51931,
+0x4e25b0c0, 0xee5270c3, 0x1976877f, 0xe86da511,
+0x14325478, 0xde8e0ccb, 0x169d0b23, 0x6af61903,
+0x66ab7559, 0x4315c203, 0x2cb683ee, 0xe535c8d0,
+0x62b24e37, 0x166a8d42, 0x318ab2a1, 0xb2f46067,
+0xcc8b522d, 0x99452df0, 0x09748975, 0xfe0ea905,
+0x387a852c, 0xbb79dd87, 0x372f06b7, 0x760994eb,
+0x72e12cbc, 0x9197fcb7, 0xb55298a6, 0x683aef24,
+0x363ca2f8, 0xc9c78276, 0x34b3c182, 0x560ebad2,
+0xb470e19f, 0x4c97a0b2, 0xcc9ac3ea, 0x8ce71a62,
+0xe51eb203, 0x6ef6bc8e, 0xf3f6ce30, 0x3b897cb5,
+0x3ea47192, 0x3568792a, 0x74fd4cf2, 0xf228e7c5,
+0xd58b34e9, 0x6a248d54, 0x92cb751b, 0x40c56ee1,
+0x2aaa732c, 0xc76e8739, 0x2f5469fe, 0x38b399e2,
+0x1f1c773e, 0xff742d40, 0xe0b9893e, 0x49686555,
+0xd934f027, 0xace42921, 0x88c3d897, 0x0616afcb,
+0x1e93841a, 0xf6e1ea90, 0x7ce80ef4, 0x22ee431a,
+0xed0f3142, 0x6e49847d, 0x2f524e8b, 0x75b795ab,
+0x95049d5b, 0xf1c5849d, 0xa51dede6, 0xbcc8dc18,
+0x1163a676, 0x3b1438e2, 0x76a639d4, 0xee1edd3f,
+0x96de87c3, 0x45d63c50, 0xb1114d03, 0xff58e8a4,
+0x60b4e173, 0x4364016f, 0x56b76f7d, 0xff1313a9,
+0xd53ec4dd, 0xdcb4f982, 0x13592177, 0xd522e87a,
+0x0fdbe476, 0x9187b67a, 0xf3d06269, 0x4a9da90b,
+0xd9d341a5, 0x73998813, 0xbef2bb9d, 0xa05801b8,
+0xf4980344, 0x1bb22261, 0x5d8912d5, 0x5b061137,
+0x09cb8a14, 0x8ed7d22c, 0xdd4ce1d4, 0x62b574d5,
+0x053c5f6e, 0x855a668b, 0xe8d65e27, 0x35c93fc8,
+0xa40dfd35, 0x421230a6, 0x080542c8, 0xe7e5345a,
+0xfd4f46c9, 0x7b08e24c, 0x40929d56, 0x3ca573c0,
+0x5f4f0b22, 0x42e62596, 0x6c4be7ad, 0xa0d2df6f,
+0xddae803a, 0x6c9d8ed5, 0x7ab7ad30, 0x4b21c7ec,
+0x3c7f4f91, 0xd8a47ef7, 0x5b9022c9, 0x4d8b5968,
+0xc4eb3055, 0x63308a8f, 0x454aceac, 0xca13fdfe,
+0xd895c8ef, 0xb07b20c4, 0x2c33e72b, 0xa68baf63,
+0x1224f1f8, 0xf575c61f, 0x4fc4fb09, 0xe5df35a8,
+0x28a6d14d, 0x7c5c2df0, 0x0c1bf4c6, 0xf915588b,
+0x9a153aee, 0x1c729730, 0xb37f5603, 0x2a56f79b,
+0x31115753, 0x9320e4ae, 0xfe8a140f, 0x1fcb0de7,
+0x99a89003, 0x5d17cb0b, 0x7526b3e4, 0xb1ffcdb3,
+0xa244483a, 0xc6cae04b, 0x271a6cb5, 0x3a1a78e7,
+0x9123d147, 0x1623164f, 0x50131c22, 0xc71c44ea,
+0x9d45c809, 0x319a2d9f, 0x139a396d, 0xf5be1640,
+0xec0129d2, 0x6d38ad24, 0xa90d58e4, 0xda465e01,
+0xf7f30996, 0x633f98ad, 0x4408de5f, 0x2ecd5e18,
+0x26a27917, 0xd392a671, 0xab12a391, 0xe273f8b6,
+0xa9dad013, 0x8de4f531, 0xc349364e, 0x49b51ece,
+0x6f1930b1, 0x9d042382, 0x9f400049, 0x7a2b169d,
+0x00f3219a, 0xd4a4a932, 0x5a71a860, 0x2f119e2e,
+0xf77637c0, 0xd56d138e, 0x67c00efa, 0xcab97fbf,
+0x56fd87d1, 0x940d3bf7, 0x163ba5b9, 0xdac0c245,
+0x21d9f9a7, 0x4b3d80bd, 0xb32c710a, 0x15ed4155,
+0x3a399a5b, 0xb9cd0f77, 0x950a06e1, 0xcae6a37c,
+0xd574a6bf, 0x5eb9924d, 0x5d9b285d, 0x51211b3a,
+0x564da988, 0x2077db05, 0xa73b1fb0, 0xd2613ab7,
+0x0b2c73d1, 0x65b52cfb, 0x1cb9ca42, 0x9633b440,
+0x14dfe779, 0x5bd8153c, 0xfeacba2d, 0xc0f7be5a,
+0x910411a6, 0x4a7bad83, 0xb80584f7, 0x0dfb949e,
+0x30d44c70, 0x95dc2448, 0x451ddc9e, 0xec9b9d61,
+0xca115af5, 0xaed655e5, 0xe3f6275b, 0xfb7e970c,
+0x48acbc47, 0x0528dcd8, 0x792dda40, 0x2acc0c83,
+0x5a6c52ce, 0x8987ea8e, 0xd51e0fff, 0x5fd74d93,
+0xa2ebcf81, 0xb33982f6, 0xb02d8517, 0x7106b421,
+0x8705902b, 0x5554a09c, 0x6cdc274a, 0x518b78d4,
+0xc45272d2, 0xf1d20094, 0xbc83023b, 0x7b92e11a,
+0x2127e95e, 0xea1c4f94, 0x87685745, 0xf02f8723,
+0x0d657815, 0x65281001, 0x0a802809, 0x6c1de0f2,
+0x7dfe2907, 0x8314380c, 0x825ef43a, 0x64928f88,
+0x29ac56d6, 0x65e7896f, 0x3fe3e098, 0xb891785e,
+0xb905a618, 0xfa0b7a5a, 0xb7760ed8, 0x2a09b52c,
+0x2f1df687, 0x299a3810, 0x22384521, 0xacbfb85f,
+0x769ef0b5, 0xbaf10659, 0xb8867a12, 0x070fc670,
+0xbdaee197, 0x3e1d3788, 0x88f6a0f6, 0xe8ced6ce,
+0xcd6b2889, 0x2f575b28, 0xde815700, 0xba108211,
+0x81bb9106, 0xcb9f3470, 0xc7706cb6, 0x9b97c18f,
+0xd965ccb8, 0x8abc2d40, 0x97ba3f98, 0x76e5ad94,
+0xa1aa8a91, 0xbc38eb72, 0xdc19830d, 0x1ea6d2d2,
+0xf2d44340, 0x14e2981f, 0x14c3da58, 0x56941785,
+0xb89bbca2, 0xcdb3a50d, 0x649860cb, 0x73f27c05,
+0xf17a7647, 0xd0ec6994, 0x7c1cbbf4, 0xa69d51b3,
+0x2e62f6d4, 0xb47c815a, 0x9f38abc8, 0x04d73af6,
+0xf295e077, 0x95227fe1, 0x54f76a6d, 0xe29cd090,
+0xe8d8c7df, 0x5710353e, 0x003ef58b, 0xb36845ca,
+0x49dc02bb, 0xf3ab0691, 0x1fcffc36, 0xb06ab2ae,
+0xe447c7df, 0xdb64ac06, 0x6c3cc550, 0x45be8fd6,
+0x57d936cd, 0x04a19414, 0xbd7826f4, 0xcd535a8e,
+0x83a4f39b, 0xb767c0ff, 0x289274bb, 0x251bb729,
+0x770e6068, 0x37499a21, 0x69173b98, 0xc7eb88d6,
+0xf7e8e372, 0xe188c165, 0x628fcfce, 0xbe7dfe45,
+0x6ddc9969, 0xa1cf2884, 0x0df7ffa8, 0x2f840376,
+0x59ac62e2, 0x061a4781, 0x36b65146, 0xa4f96e5c,
+0x1d6ac540, 0x42417b41, 0x0d6d203c, 0x27d1ae6d,
+0x7c646013, 0x3a7e353d, 0x728d24ca, 0x99c73e22,
+0x55aa311d, 0x4c950d8c, 0x981af0c2, 0x31e597b1,
+0x1e0c483b, 0x8986725e, 0x193bb7ae, 0xaa4b61e7,
+0xb0af3602, 0x24d7633a, 0x5932b068, 0xf5ec2a15,
+0x46e00a83, 0xff944061, 0xb8ddc4a1, 0xc1e0ef58,
+0xcf6ab52d, 0xb6217e21, 0x77a1c56f, 0xdc64b8f7,
+0xecbad078, 0xda412cf2, 0x847e62f1, 0xddca350f,
+0x68b4495c, 0x0f490863, 0x2dcf584d, 0x829e7660,
+0x0303d884, 0x60465078, 0x29e5e1cc, 0x11f41ab2,
+0x968f7872, 0x4660fbc7, 0xc8ea385a, 0xe474dbb8,
+0x3b943657, 0xdf2ede56, 0x75667c66, 0xb8a1c4ad,
+0x526410a1, 0xb4fd5d70, 0x87eb4dcb, 0x6a18ade1,
+0x250cc94c, 0x39922dff, 0x39bdb8a8, 0xe264ed5b,
+0x0ecd0891, 0x9d7fa275, 0xd75cace1, 0xfe009cab,
+0x94440126, 0x0d2639e2, 0x87bf340a, 0xa1861ace,
+0x8bec69d1, 0x964e70b9, 0xbe073561, 0xc3605902,
+0xa22bc32f, 0xac6ece3d, 0x60b4e3b0, 0x7add4964,
+0x58f5a300, 0x08679784, 0x026a134f, 0x412dd9e7,
+0x22d33251, 0x461d6f6c, 0x59140bac, 0x68053736,
+0x754dd267, 0x23796fe4, 0x40bd3f71, 0xf762979a,
+0xf3960525, 0x913b5690, 0x34137ec4, 0xa08fd1bb,
+0x19b9d1d3, 0x64799f17, 0x773451a3, 0xedbee62b,
+0xe2aaeae7, 0xa262bca5, 0x67d1c5e3, 0xac9ec514,
+0xc55ee660, 0xa21712b4, 0x1bbcc683, 0xce4dc09d,
+0x6b277c75, 0x39dcd39c, 0x561eae71, 0xe5fc29b7,
+0x53e081ff, 0xe3915c88, 0xe50d6831, 0xe0fa2cb3,
+0xa679fefb, 0x1bf47255, 0xf3fca929, 0x53d6ef55,
+0x9fdc0bdc, 0xc5019cf8, 0xe93622e4, 0xd4ccae19,
+0xec135e5b, 0x3882c02d, 0x7b989295, 0x23866190,
+0x1d65d694, 0xc44fd24d, 0x32ac5842, 0x0b7f6ca2,
+0xe8567872, 0x5372e0c6, 0x42ad7230, 0x79708c5a,
+0x7210aa7e, 0x43b33795, 0x5ebeb3de, 0xa10cc4f3,
+0x1db8247e, 0xfd69e44c, 0x90265f7c, 0x64da4062,
+0x64600ed8, 0x2be3baf7, 0xc9e5eab8, 0xc71082e1,
+0xf916a1b4, 0x037218b2, 0x21f2c5f5, 0xb06f7fc9,
+0xac7e85f4, 0x5ffe4990, 0x5fa03cc4, 0x1bda88a6,
+0x06c6ecde, 0x6bbdf5b7, 0x3f661b1b, 0x1a752611,
+0x0795cd8e, 0xc4912438, 0xcd7dc1c4, 0x20140d24,
+0x28b7906d, 0x5c88487b, 0xdb4cb66a, 0x7480e66d,
+0x6c3cdafd, 0xf89939fb, 0xda8084bd, 0xb1d004c2,
+0x7dce565c, 0x03bca5c1, 0xe4698b06, 0xa4a6a898,
+0xce307b03, 0x6ee1d1c7, 0xfadc6fd6, 0x31bc9ba7,
+0x068077d4, 0x288c3a53, 0xbbb7bb8c, 0x31bb51cc,
+0x6c3ebfc5, 0x528cd18a, 0x42a10ca4, 0xd8536a73,
+0xcea79f78, 0xc1e60a2f, 0x1b34cc0d, 0x3b67ba68,
+0xa1a5a7f7, 0xcccac432, 0xcce44415, 0xe9f72329,
+0xed2b7418, 0x2e132fa3, 0x93c79de7, 0xae5be0c8,
+0xe5d8ac4c, 0xe44494ac, 0x37fe2022, 0xb4b6a708,
+0x8a64bcbb, 0xb2edad76, 0xdb183255, 0x00b76b3e,
+0x08ed65a4, 0xf6cbe4e0, 0x68ad583a, 0xf52301a2,
+0xaf2b12bf, 0x733b2cd8, 0x2b96df15, 0xd73694f8,
+0x9828ad99, 0x3a0ce96e, 0x758b0926, 0x1a6224a8,
+0x82751745, 0x50fb01ed, 0x2263404e, 0x24a8a8e8,
+0xcfd357af, 0x841a5214, 0x473a05fe, 0x081b24e0,
+0x27450a67, 0x3f544f1e, 0xb0c5d641, 0x96925629,
+0xb3f52948, 0x94d1cca1, 0x8452f267, 0x78804a70,
+0xd98dd79a, 0x1d618913, 0x514696a1, 0xc1f4673b,
+0xbbcfa0d5, 0x47dd2bc2, 0xbb435b52, 0x3f5b7a76,
+0x2ef3ebdf, 0x8a4abb6b, 0xf0f2e87c, 0xc10d0512,
+0xec9148a3, 0x8c240267, 0x519b3600, 0xe46dfb40,
+0xb2fc67dc, 0x47701417, 0x710ba38c, 0x05b578fe,
+0x0e3f77f2, 0x43ede712, 0x6575f254, 0xb85e1540,
+0xb875d437, 0x43f9e107, 0xfeeb6aa9, 0xf604d027,
+0x926d6190, 0xff22770a, 0xbde679c4, 0x13c5f920,
+0xc3a8524f, 0x6ada5b52, 0x2dabf693, 0x188338bf,
+0x73322d1c, 0xd68babc7, 0xaf61e4d9, 0x2d8f9b52,
+0x7180d7c6, 0x17fd14b3, 0x380408e9, 0x5508f09c,
+0x50d3dddf, 0x9fbd289f, 0x0ab08840, 0x8696d39a,
+0x3940f678, 0xfc6d18a7, 0xe798fc3f, 0xd424718a,
+0x8a4fd5d8, 0x5b486672, 0x2ce2f129, 0x0f6a6b82,
+0xbc3ba7ad, 0xd6170b7f, 0x41f53ef3, 0xc55130ed,
+0x757410b4, 0xca3b3b2e, 0x9c7e7481, 0xd08f1082,
+0x167589e7, 0x851a83ee, 0x83f804a8, 0x9a69644c,
+0x982ae89f, 0xd423db54, 0xbaad1ff5, 0x4b40b588,
+0x53ad20c9, 0x0a970cb2, 0x22bdf3f0, 0x64b4a53e,
+0xa09f4dad, 0x612c3f43, 0xb88b2191, 0xf406c182,
+0x090da946, 0xea6a775f, 0x0d65ff36, 0xef3ce316,
+0x5d755d46, 0x7de78c4d, 0x8f5174d9, 0xafbf7d02,
+0x4a4c86cc, 0x88560d24, 0xbe20b642, 0xaabaa5e2,
+0xbfb7e1d7, 0x2ec8eae9, 0x2b186dc5, 0x6d309620,
+0x3af05061, 0x766df20b, 0x7916052e, 0xfc2dded9,
+0xb3d20301, 0xad33df5b, 0x4cee069a, 0xc1a7a81e,
+0x5e0d2e35, 0x2805a1a3, 0x5f2cea35, 0x130cf8bb,
+0xe79edeb2, 0xaedd8cbe, 0x80efe93c, 0x0d483938,
+0x452afcb1, 0xa2b3758f, 0xce4f3a7f, 0x56122d3b,
+0x9e168187, 0x8397f609, 0x146ff536, 0x7a7dc4c8,
+0x50703042, 0x595cd1ec, 0xba543372, 0xe1b151b5,
+0xc46d2c8c, 0x19e12bd1, 0x9282164a, 0x2ed012e9,
+0xd9035dcb, 0x7d736af6, 0x2ca9d8ff, 0xfc99f12f,
+0xc8ec3a6f, 0x62a4e97c, 0x4e31b465, 0x11e25a96,
+0x3160f44f, 0xd9a1d58e, 0x20808031, 0xec00b0fa,
+0x3c87eb83, 0x30f94451, 0xe2c3952d, 0xaf0801f7,
+0xcac70533, 0x487d6603, 0x0af5250a, 0x63080e46,
+0x6cedae0f, 0x701f0981, 0xa3b66541, 0x6b733727,
+0x482f441c, 0xd498c452, 0xba40059d, 0x6f85bb3a,
+0xbd51e78c, 0x2859c03e, 0xe70d9d99, 0x0fc6c26c,
+0x5c078e15, 0x3f7157b2, 0x4d2cde72, 0x8be833f9,
+0xabe0af3c, 0xf09058e5, 0x436204b5, 0x1e532c1e,
+0x727cff49, 0xc11dd498, 0x7b88b1f1, 0x850b8bed,
+0xbd0cc30a, 0x650bb89f, 0x610cdd43, 0xbed699b5,
+0x18152f49, 0x8c0a6496, 0x87b0a913, 0x7af59111,
+0xe9ce27bf, 0xe6fb006d, 0x6b357612, 0xe0572e24,
+0x3045f40f, 0xafd7b93d, 0x6769860b, 0x8c21c3cd,
+0xe303ea80, 0xcb18f550, 0x98389f36, 0xd2dcdc4f,
+0x7b26eb79, 0xec64f080, 0xe21a0d89, 0x18ae1918,
+0x7176e366, 0xe8c4d728, 0xc5cd386e, 0xb616f441,
+0xb979bb54, 0x4a61011b, 0x9178034c, 0x4fce8d95,
+0x97686376, 0x48f05b11, 0xcf14eda7, 0xe6ff3da4,
+0x3162b2af, 0xfe2fd68f, 0x478783fd, 0xe1084210,
+0x6f9facd9, 0xc6ccc402, 0x868466f1, 0xa6f47627,
+0x39b7af6c, 0x9f91fb32, 0x02b65635, 0xd703f967,
+0x6af2e5a8, 0x52c32e81, 0x31dac449, 0xa006713f,
+0xdb92d3e0, 0x4506bbb5, 0x25f59244, 0x276d6b08,
+0x9ab553cc, 0x37612200, 0xbb5fd352, 0x1e369f70,
+0x6f3bec85, 0xa0d99e71, 0x93642918, 0x54c3b57f,
+0x39745b49, 0x107f30f6, 0x7225202b, 0x0d32ee6a,
+0xc9f8df68, 0x479b96fc, 0x5157d18d, 0x59fae351,
+0x96185c52, 0x49dd2e14, 0x6bb9d326, 0x8dc40d3f,
+0x8f9fdac9, 0x8d9d47ae, 0x5f32bf3b, 0x3def03fe,
+0x6f93cad1, 0xf73d0b0d, 0xdfe00b8e, 0x97e41f69,
+0xc9b2c8ef, 0x1de99304, 0x4cebc433, 0xd9e1d3b7,
+0xb2b77b24, 0xad5d3803, 0x015cfb06, 0xe73dd973,
+0xb0ac2332, 0x59ce79cf, 0x55945d61, 0x6df6434d,
+0xc593a4ae, 0xaa34537e, 0x8ed711bc, 0x1c4521b8,
+0x578db5f1, 0xc319851d, 0x155e2a08, 0xa5800acd,
+0x70a1c445, 0x47aa82bd, 0xf70b6f05, 0x7a635ae6,
+0xf8770ac4, 0x1a5ed921, 0x2dedcb10, 0xf636289d,
+0x5c7544e3, 0x64db30a0, 0xae13089d, 0x33b2686e,
+0x185f96a7, 0x97068958, 0xd7d1389a, 0xe5b44a6b,
+0x36112243, 0xefa493cb, 0x9083a640, 0xe68c5c0f,
+0x5c0adca0, 0x8d1b147c, 0xbf7f384d, 0xdd8afb98,
+0xff4c2a95, 0x25366bcc, 0x3969376b, 0x9ae8c87d,
+0x55335aeb, 0xaaed8693, 0xea5b1441, 0xfeb2e4b5,
+0xdce1ef6e, 0x5404d8b3, 0xf2571c76, 0x300a8cb6,
+0xbac6c865, 0x9af56dca, 0x5e5b7f74, 0xcbf77e48,
+0x625a0618, 0xe9082583, 0xb36626c8, 0x8827ee3f,
+0x063905ab, 0x516d8fbd, 0xa2841336, 0x400d8539,
+0x80b1ce20, 0xc2250673, 0x674b3b7d, 0x5aca5117,
+0x72376888, 0xc94395cf, 0xdf49d93e, 0xfa614c96,
+0x6ae76787, 0xc2414688, 0xa3d907aa, 0x3f4d6e64,
+0x55a0266a, 0xee5c5ee5, 0xf93bd2d4, 0x5d42fb98,
+0x3801880e, 0xdb5d8c5e, 0x8199a6b0, 0x7439e4df,
+0x3b913581, 0xf60f67ef, 0xffc3209f, 0x98e40217,
+0x030aa73a, 0x2f36c2ba, 0x29abd0db, 0xc731f0c1,
+0x7eb9df5a, 0x30cb5f3b, 0x3789b186, 0x6d86b5cb,
+0x34285488, 0x20da7f81, 0xacbdf893, 0x2c2a002d,
+0x9b83203a, 0xf0386c1a, 0x9d3483dc, 0x236c1e17,
+0x36932dcc, 0x575da852, 0x026dbcbd, 0x55dc9721,
+0x1cfbbb40, 0x6f41ae1f, 0x19291f9b, 0x1e0a9767,
+0x122e0463, 0x5d1ffb16, 0xabd5bcba, 0xe995341b,
+0xab265d98, 0x572681c4, 0xb2aec7e5, 0x4029fb6d,
+0x41020e98, 0x26dc21a7, 0xd9f7c588, 0xeb5cfe4b,
+0x58b43f0c, 0x99f4cfca, 0x199b0ab7, 0x0aa040c0,
+0x764a034c, 0xc209cd28, 0x21bc4580, 0x6cdcfac3,
+0x87a2c27d, 0x9e844f4c, 0xc0a13c4a, 0xfa616765,
+0x7322b9c6, 0x61e4963f, 0x04776967, 0x45fff36f,
+0xfd8157b7, 0x82e3a974, 0xdb5f3807, 0xb89df834,
+0x707b88b2, 0x633991a6, 0x0f2be137, 0xaffa7d22,
+0x4f3a5fc1, 0xe02d7929, 0xa0cfc36d, 0x1d2fa776,
+0x9dd8cc06, 0xa9af0f7d, 0xa904959e, 0xde9f41c5,
+0x67c2f167, 0x5c7bcf08, 0x457bb7e4, 0x59dcb4e0,
+0x4a433c8e, 0x570f7e57, 0x6165d55c, 0x67c20286,
+0x9eeeff21, 0x93a2573a, 0xad6ca028, 0xa3b6825a,
+0xcd56806e, 0x732e6de6, 0x0593c268, 0x5033849c,
+0xf63cda8b, 0xe04fe7c7, 0xb7aebd59, 0xedaa70a1,
+0xcd6cbab1, 0x36486a78, 0x9fc80222, 0x9515ab73,
+0xa5c9c606, 0x8cf5b39a, 0x4134c919, 0x1194230a,
+0x36a59cc6, 0xdbfc20b1, 0x57734e76, 0x9748480b,
+0xf4cc43ab, 0xa447c5a4, 0xfef930a1, 0xaaee7cf6,
+0x9baf4bc9, 0x7ed4b11d, 0xa6d96c25, 0xa23ca74c,
+0xaa544043, 0x16818dda, 0x0c1aba69, 0xff3ac26f,
+0xfdc7a0d4, 0xc7b308d0, 0xc9abe69b, 0x2f9c52b6,
+0x18b82863, 0x79535750, 0xea74f7b1, 0x4f8664fa,
+0x9466d84d, 0xb266932b, 0x83926175, 0x9beaf1b1,
+0x5a430d93, 0x5409277c, 0xc6657acc, 0x3b94532d,
+0x70f91530, 0xd7f1106c, 0x93c01e83, 0xea491ef4,
+0xc19a3766, 0x4f44f96d, 0x3505453f, 0xbe4bd0ef,
+0x7fa37537, 0x2767aa84, 0x53545e49, 0xea73763c,
+0x31165a86, 0x9d782d3c, 0xf5c4bd5a, 0x9bf85499,
+0xad998612, 0x0a66ad87, 0xc34240b3, 0x886fb112,
+0x25f6cd2a, 0x279d7eb8, 0x649a8506, 0x095702a5,
+0xd257e1ba, 0xd2f16855, 0x927fc73d, 0x38b9c1c9,
+0x4ff21a76, 0xa49835ba, 0xa5e78f6f, 0xd6a7eff8,
+0x4b10ad12, 0xd2d47632, 0x4d69db46, 0xcb6b34ad,
+0x9d510095, 0x2b3eaad4, 0x1a284335, 0x446175b2,
+0xc7e72fbf, 0x88891af4, 0x0a4bcd9c, 0xf392ee57,
+0x4e3b29aa, 0x5c1d5f9c, 0x70ead218, 0x8396bc4d,
+0xd70c0ce2, 0x3ef572ea, 0x8884acc0, 0x994df85c,
+0x99764347, 0x3e37263c, 0x90935e62, 0x1b3d8ec7,
+0x59d3adb1, 0x855449ed, 0x5856989b, 0xbda0552a,
+0xe5e2b642, 0x5dd26583, 0xa244fbd6, 0x1b4773f7,
+0xa1ed86df, 0xff6e9503, 0x534ef6af, 0x82adbe2b,
+0xc019cce0, 0x90b5466d, 0x05c2ff5b, 0x9366755e,
+0x95f05f17, 0x9e66b9fa, 0x8df0d260, 0xcca134c6,
+0x87ba85b7, 0x20897696, 0x217e2d47, 0x72275294,
+0x91129332, 0x61ee3907, 0xdc16a89a, 0x87eeae2a,
+0xb909819a, 0x58f2b5be, 0x481784c3, 0x12ed5ee2,
+0xe2400550, 0x4f0644d8, 0xb51d41e2, 0x77c83780,
+0x1f25d06a, 0x59a06d2c, 0x6d8bd115, 0xda1c2ac1,
+0x868e8b5e, 0x071186d0, 0x43c0c312, 0xffe85804,
+0xd9496f80, 0x84ce51d8, 0x7956483a, 0xd1405abc,
+0x09561de9, 0xea291de7, 0x0dcfd003, 0x38178a17,
+0xddf6e3b0, 0xa712cfcd, 0x5df8cd3d, 0xba55da91,
+0x7b7269d0, 0xef16cc88, 0xb5878dd8, 0x9ba275f3,
+0x0ef6b904, 0x95c36c7f, 0xedb2bb38, 0x5d49294b,
+0xe2283613, 0xb8e5b63b, 0x714258e9, 0x0ffc610d,
+0x4d3603d6, 0x2d2e428a, 0xb3bf9096, 0x5a72f460,
+0x39b6db1d, 0xfc7152ca, 0xe743356e, 0x95b49b6c,
+0xe68394d8, 0x09c6766c, 0xa121ea0c, 0x6d2ba336,
+0xb2cbd5eb, 0xfd08c8c4, 0xedbcef77, 0x3108cbb0,
+0x074d343a, 0x0b82d06f, 0xec4793a7, 0x395c0b37,
+0x1dfe63e0, 0xa5f573df, 0xbda29e5a, 0xbe6b91f5,
+0xa30334fc, 0x0bd7e798, 0x7c7d22b1, 0xac3f048b,
+0xcabfc343, 0xac8e0d8c, 0x54186878, 0x9b09527b,
+0x14567ce1, 0x9705ed18, 0x61023a15, 0xd8b762bd,
+0x63b4f16c, 0x4c87ea52, 0x704b2865, 0xa5e2685b,
+0xaf8d5db2, 0xc6bc0f2a, 0x33afc127, 0xc2561d76,
+0x26a2bbbd, 0xcb63aead, 0x9bc5b6df, 0x9e31b4d1,
+0x4fb75377, 0x5ec1ecf0, 0x63c5bf52, 0x0a017dd3,
+0x1f2a20ca, 0x14cc6ffe, 0x0b3fcc86, 0x8c50a026,
+0x3d672373, 0x8b956914, 0x30c8c153, 0xfd534b64,
+0x28b0b854, 0x0b5d8e45, 0x567bc73e, 0x20b455de,
+0x1829334a, 0xd434bf15, 0xc9619f5c, 0x5da74cce,
+0x916401ea, 0xa3bd4486, 0x6823c60d, 0x9c91560c,
+0x2117cad4, 0x6c66bcdb, 0x9550340f, 0x550e8d97,
+0x5209cd44, 0x0dcb51b2, 0xe6492fc3, 0x0de46cfc,
+0x163e5b7b, 0x40146883, 0x80e4a485, 0xb990134e,
+0x7851d0f6, 0x5739c514, 0x8f242d6e, 0x36ca258a,
+0x16a4cdd6, 0x315b52c2, 0x40eef0ff, 0x9f3a89b5,
+0xd28c53c4, 0x3b0bfda1, 0x1c64048d, 0x33c36d3a,
+0x99fbc613, 0xae676d5b, 0xdf81d183, 0xa485f8d0,
+0x68cf4562, 0x518de339, 0x3eb4f6e0, 0xb4d76bb7,
+0x16434ca8, 0xbd70620f, 0x9a5992eb, 0x5c9fa4a9,
+0xc11b2c0f, 0x0451774e, 0xb6c3ec7a, 0xfe194a24,
+0xa3174684, 0xcc56c062, 0xc574e8f0, 0x90abdcec,
+0x31c7c52b, 0xec5de583, 0xfcd5d7a2, 0x426f41d4,
+0x2cf1c508, 0xc72a0b51, 0x4fb1f431, 0x6624ef2b,
+0x79aa8bfe, 0xbfad4b0c, 0xd77cf3f2, 0x205191b8,
+0x4407be23, 0x8b2e5041, 0xd3f962b5, 0xb8d5b6ab,
+0x9ab1e89b, 0x87acd401, 0x2f242e5c, 0x0a90d574,
+0x61dc7ec2, 0xbdc51df7, 0x5b5ae6c3, 0xd502d4ad,
+0x9186b015, 0x1fea30cc, 0xfb3f17ed, 0x4368b8d0,
+0x5d16f257, 0x102b9206, 0x3f0f7d44, 0xf885111e,
+0x5e2b6df1, 0x577ad1cc, 0xefb8ad88, 0xefd80ed0,
+0x51b32eb8, 0xfa776389, 0x69a9f7ee, 0x662fc857,
+0xc1ae7765, 0x2d964bd7, 0x675be16d, 0x44ed135d,
+0x38c96605, 0xf3650d4f, 0x837ee4cf, 0x1f084ec9,
+0x1195b940, 0xe6e0efe3, 0x1bb1ff64, 0x7711bbbc,
+0x193c1521, 0x4071d579, 0x7f9cb73f, 0x5ec50212,
+0x5fc22225, 0x958271d4, 0xce269d1e, 0x86cee227,
+0x57667154, 0x6ee813a8, 0x75c7bbf7, 0x07dcfeab,
+0xc0809ae0, 0x27b06249, 0xbae823de, 0xb6a1591a,
+0x9d1dfe30, 0x983a41e4, 0x2ed09436, 0x2a635078,
+0xd73ff054, 0xac7434ca, 0x6f133aa7, 0x2e2909b6,
+0xae5a8d45, 0x30ac8903, 0xf8d64d7c, 0x3dfdefd5,
+0xebb0e023, 0xfed8c69e, 0x891ae90d, 0x8e7e5320,
+0x2cfb5b3d, 0x5ec75f82, 0x71e29320, 0x5a8cbf26,
+0xeff320f4, 0x5812b25f, 0xf0c52517, 0xe622b0dd,
+0x0acea14c, 0xbf136a87, 0xf9df1cbe, 0xb31b2ea9,
+0x3da9d39f, 0x678326c2, 0x871cd9c1, 0xa9c1acc5,
+0x71a6060b, 0xa3493e34, 0x16133a09, 0xfe5d0d43,
+0x60e16195, 0xfac4b6dc, 0xb344292d, 0x5456c6d6,
+0x7381dfe1, 0x35ba0a55, 0x16081681, 0xe5d6e16f,
+0x216d2b46, 0xc9490c1b, 0xbf0a2520, 0xc0d10973,
+0xa1d81317, 0x95813b7a, 0x46f0f8cd, 0x7221a626,
+0xec8bfc36, 0xdeb10e26, 0xec798ae3, 0xc8ffbe45,
+0xfcfa11e9, 0xebdc55a3, 0x736a379e, 0x676e7af0,
+0xa2945215, 0xf068e484, 0x89231a34, 0xcedbf2df,
+0x7a6311d6, 0x1d678905, 0x1c74cd90, 0x87129c62,
+0x40806f69, 0x253b9301, 0x4f008223, 0xd3ff8432,
+0x95012970, 0x88656d86, 0x0c0ee02c, 0x787f3587,
+0xc42277e3, 0x79e6ef87, 0x5196006c, 0xf2d0cbc2,
+0xab71f09a, 0xfb7962ba, 0x9a5ed845, 0x5f475d29,
+0xe9e9f194, 0x6caafba5, 0x3f8a6913, 0xbcafaf43,
+0xb426d1ba, 0x7ddf1b80, 0x87710a60, 0xd3f65d40,
+0x217c5029, 0x6b6c6b5e, 0xdd30c968, 0xe2a8ad5b,
+0x2ce40081, 0x0b0326fd, 0x1775f4b9, 0x9984d53b,
+0x19c84319, 0x465a38ac, 0x1bd7e712, 0x99a9f93c,
+0x67ced20b, 0xd909a91c, 0xcbbbae58, 0x1a56bcae,
+0xc9c1c973, 0x2e090318, 0x353dc224, 0xb72fc0ee,
+0x0001dc88, 0x52c0aec6, 0xb4a89127, 0xb8740fe8,
+0x0141c569, 0x4ec1bf2c, 0x1c9f7cb2, 0xf7d58573,
+0xafba44a6, 0x20fcaace, 0xed059923, 0x60d377e0,
+0x9cd58a6d, 0xceb64564, 0x39d50927, 0x4f829bf4,
+0xd782dd10, 0x7bfeeb5b, 0x2805389a, 0x06ee4e50,
+0x45e3e1bf, 0x8b0782d1, 0x55510724, 0xde4340dc,
+0x0468d730, 0x20af74ed, 0xdb7ff10b, 0x7977bf6b,
+0x2bd02094, 0x1d0a216f, 0x03cfabbc, 0x164b1fcf,
+0x534a4437, 0x1915263a, 0x150e93ea, 0xf9d63f34,
+0x857af279, 0xf9b826bd, 0x4f9c1631, 0x761b288f,
+0xefd930dc, 0x7e21b509, 0xc275ee25, 0x97dccf92,
+0x2eb45005, 0xcb303a17, 0x84fcdc5c, 0xa21d3fe8,
+0x724124a5, 0x54524483, 0x389170e3, 0x4e1ff7d5,
+0x72110258, 0xc0cf6e82, 0x6e1fe12e, 0x65c90371,
+0xa99c9462, 0x5b78aa98, 0xbc9436a1, 0xede73575,
+0xde169877, 0x720934e4, 0xde3155b7, 0x7ebb2f0e,
+0xb2d0e40d, 0x15b597d0, 0xdf082d5e, 0x22ebbbba,
+0x68cb42cb, 0x58e6e661, 0xbaefc91f, 0x4e3217cb,
+0x52cc18eb, 0x7bc2f199, 0x8e7fdc90, 0x4907f862,
+0xd0815fa4, 0x1b7eaad8, 0x90b39c74, 0x2f02f979,
+0xd7985fad, 0x82c4d349, 0xb878c5e6, 0xd6d7365f,
+0xb360fdc2, 0xaf8ffc5d, 0xb0098ef0, 0x0b41dfc8,
+0x24e4e4ea, 0xe17f8877, 0xbcde039d, 0x9b586e03,
+0x192b18ce, 0x2a9a1d86, 0xa864f8c8, 0xce6563fd,
+0xd9ee2351, 0xdef41347, 0xd21994e2, 0x387c9359,
+0xe2d3abc0, 0x4982c680, 0xe3e43f84, 0x67d8fe93,
+0xc8cfe469, 0x2095c98a, 0xda2db810, 0x9e5766c7,
+0x3c2f4b20, 0x92e67606, 0xe1bac93a, 0xa805c705,
+0x4aed9ea0, 0xd1f0c546, 0x807248fd, 0x43b26233,
+0x3486434b, 0x4e2d025a, 0x755f498f, 0xb58c5be4,
+0xebb5fcfe, 0xb6bc61f2, 0xa7693118, 0xd9df5f82,
+0x23c0c360, 0x436d2b4e, 0x717ca75e, 0x6f0fea5e,
+0xfe11bed5, 0x1031f3bb, 0x3a8c3570, 0x3c784752,
+0x90a3f899, 0x38929e1c, 0x00c554a7, 0xfe083bb7,
+0x489b1d2b, 0x81b619ed, 0xe8a7207a, 0xebfcc03f,
+0x58265a1c, 0xdb698877, 0xc8da280f, 0xdb60cfd3,
+0x0f8ac573, 0x41935f4a, 0x03f574c1, 0xe7084e1a,
+0x4f481b4f, 0xccecdfe4, 0x17974d9a, 0x50ef62bc,
+0xb28317d6, 0x1118de1e, 0x9f95e190, 0x116d18f5,
+0x4d83f4f2, 0xfd2069d3, 0xff4df0c6, 0x1fb97350,
+0x738c1695, 0x81218575, 0x049869e2, 0xafd6d853,
+0x2eef0331, 0xabe2333d, 0x5f5da74e, 0x2aad7e80,
+0x30ef17d8, 0xda18d115, 0x14cf5948, 0x83a8fd0f,
+0xe0418383, 0x1051450a, 0xeda7fd61, 0xc1e5636f,
+0xba6853ca, 0xd442829f, 0xba5046b0, 0x49ed0cdc,
+0x47b45c36, 0x947b6622, 0xb937b3ab, 0xcc56bf60,
+0x114b3314, 0x689ee17b, 0xd06cf12e, 0x27d6ede6,
+0x6f558857, 0xe04c4418, 0x7b8d2ee6, 0xac511481,
+0xa7ffeb98, 0xfcdc240b, 0x2df5364c, 0x76c0a100,
+0xadb9fe5d, 0x1c947fba, 0xde6aa412, 0x4a27d690,
+0x1b0b912f, 0xfb9e0ef1, 0xccb65c2b, 0xfc951766,
+0x6e2517a2, 0x6915a740, 0x5d25a614, 0x6cd7b974,
+0xa7ce4d32, 0x3224f657, 0x4282b7a1, 0xec366255,
+0x0e47b33e, 0xdcfcc85d, 0xa1664173, 0xf59ba283,
+0xee9e56ff, 0x19394206, 0x10c79974, 0xae5dc824,
+0x6c0ee811, 0x71e73438, 0x3dbd7096, 0x3067b002,
+0xd4dbf4a1, 0xeeadf929, 0xf9fbf969, 0x313828ac,
+0xf3098c09, 0x9f4471b4, 0x603db9bc, 0x183e48cb,
+0x4fde31ea, 0x1d742894, 0x15925c74, 0x05c76d00,
+0x0c4014bc, 0x8740492f, 0x55d13385, 0x26da473b,
+0x46073574, 0xe838bddf, 0x05eebc9f, 0x102db9d7,
+0x29e40133, 0x25358cec, 0xfc5a1101, 0x3d47e19e,
+0xd5d41f36, 0xf0ed93fb, 0xfed93b52, 0xa8eb8c88,
+0x8c46e49a, 0x53e1c785, 0x6b16ceb0, 0x7b371456,
+0xa002bb76, 0x124fb3fa, 0xcce07630, 0xf7a2b85b,
+0xbfc9d8f6, 0xcabd8927, 0xa17a6f95, 0x376f6b76,
+0x736e63e6, 0x1817b743, 0xb1065d6a, 0x465c9f0b,
+0xa0f2834b, 0xf2a4e312, 0x440c9337, 0xf90a881c,
+0x5394b548, 0x39d7270b, 0x34df5a19, 0xef293328,
+0x9208a78d, 0xb10047a0, 0x4cdb36e0, 0x956341d2,
+0x1172f6a7, 0x0d4dbcd9, 0x150257e5, 0x6fcd2819,
+0x58d0fbb0, 0xd0c02e0a, 0xdaa14a11, 0x9916a9cb,
+0x1b57cc6a, 0xfcb7d15f, 0x1f53a411, 0x5879f5b8,
+0x16b0a08b, 0x682bc794, 0xc7a3b009, 0xe03786c4,
+0x0b5a7c63, 0xc8dc0446, 0x193e9316, 0x47d5c30d,
+0xa60a3c80, 0xf4a12762, 0xf8793c61, 0x2409a00b,
+0x6c6d50f1, 0x7ea3a994, 0x30451730, 0x826e1d45,
+0x3976f84e, 0xd23342a7, 0xd4f833df, 0x15fb07a5,
+0x44a51f2f, 0xa791f9c7, 0x2ab655ac, 0x330f04ed,
+0x7993420d, 0x6c30b008, 0x5605f4a6, 0x0b8f8ab9,
+0x6cf1deee, 0x6b60da51, 0xbc1422b1, 0x74e8f1f0,
+0x0c2c01f4, 0x88eee820, 0x9f6f60ca, 0xbd4e5376,
+0xa2e01d54, 0xbbac9a7e, 0x95ffc15c, 0xf17cbfe7,
+0x2f7be37e, 0x65db6739, 0xe75ad573, 0xa9b14b3a,
+0x3999e77d, 0x402c7ee2, 0xef122e31, 0x2b82eacc,
+0x29085b92, 0xe4ffbf36, 0xf8ed47db, 0xead6e5cf,
+0x5de54805, 0x7a1d9515, 0xcb865781, 0x4e60f4ed,
+0x98d61f94, 0x3cef4824, 0x6ce64200, 0x7a8e1493,
+0xefab6481, 0xf9e0de21, 0x00d68953, 0x8328e844,
+0xc5ffa497, 0xcdd2f8e5, 0xe70ed12d, 0x8c8d24f0,
+0x95abdfaf, 0xed54a7a8, 0x443150f3, 0xbfd46120,
+0xbf5a7bf6, 0x99a5b47f, 0x0c9d7760, 0xd70a3ea5,
+0xe4183d93, 0x5af80980, 0xba263b1d, 0xeedf5a94,
+0x8f935597, 0x7e84bb8d, 0x24a54001, 0x230a3c64,
+0x5ee409a0, 0xbc4a02e8, 0x73487e4b, 0xb8a14b12,
+0x4d2c9105, 0x1fdcdc1c, 0x10eb2962, 0xb0217fba,
+0xbe8793f2, 0x3c44cfcf, 0x67a95305, 0xdef9c77f,
+0xd60b9d0d, 0xa8a1fbc7, 0xc3b7fef7, 0x1a76c5ac,
+0xf55092a9, 0xe3a3752a, 0x08a88130, 0x9909eb5a,
+0x0e4c37c4, 0x13b66089, 0x7a49ac95, 0xe60b4832,
+0xc300cf0c, 0xe1582543, 0x3b3d2c8a, 0xfe882522,
+0xa24b794c, 0x81a3b399, 0x48f3fb1e, 0xd2b325a8,
+0xf8015b2c, 0x0c35913d, 0x639e9bbf, 0x80c8ec76,
+0x81c0705b, 0xa4fe643b, 0xa06100d6, 0x9f8d4894,
+0x5d17d490, 0xd7a9007c, 0x5adcc8b3, 0xd7c1c03e,
+0xaefa34f6, 0xbf959047, 0xdaafcc99, 0xdd14e71c,
+0xd7ac0efc, 0x3c9c4c89, 0x48bbd2ed, 0x907b4da3,
+0x817d5b8b, 0x822c5db5, 0x7f3293bc, 0xb712ffb3,
+0x7c154824, 0xc354ea89, 0xd6b1252b, 0x39bf78c0,
+0x2127a973, 0x9bd70e29, 0x51fd538a, 0x535fac18,
+0xf2c5e53f, 0x1b736b26, 0x71255f0f, 0x6c254021,
+0x3eb72bda, 0x05da558d, 0x84131772, 0xa276638f,
+0xd577fb79, 0xef0d1a08, 0x8bdc53fd, 0x2a71b3fd,
+0x4ed41204, 0x592abca3, 0x995154c7, 0xbede8562,
+0xe9492455, 0xddc9a5ce, 0x1e9db016, 0x57477a40,
+0xcc86ebfa, 0xba7c18a3, 0xd9060d3a, 0x3866c4a7,
+0x5ad05ee6, 0xcd1df98e, 0xcf031455, 0x3d31984a,
+0x481e2ea1, 0x29e760dc, 0x5e49a8e0, 0xe8354e48,
+0x611ffef7, 0xfa9bb0d3, 0x7c8bbad7, 0x65fb7b7b,
+0x47971e27, 0x431f6b52, 0x1cf9b8f0, 0x2ab3c24e,
+0xecbaeb0e, 0x7d57cf23, 0x23d1f43f, 0x3e607986,
+0x3d697fe1, 0xbb3c596e, 0x707a141c, 0x9c3c5974,
+0x4789aa5c, 0x2354a40b, 0x4e050f47, 0x430f417f,
+0x1ad0b489, 0x291fbd9f, 0x0919fd8c, 0xb5b1cffa,
+0xcab90385, 0xd81804ac, 0x818b7b6b, 0xb3fff6b4,
+0x42881bda, 0xe562c316, 0x4d374783, 0xe5d9eebd,
+0x0f8d2d59, 0x014043c9, 0x68dd37c2, 0x0b1cee46,
+0xe0fde299, 0x0ee2e06d, 0x8314a2a2, 0x0492cb97,
+0x402bd26a, 0x7e3b9161, 0xa492def0, 0xb3474888,
+0xeeeb9bfe, 0x00dbde69, 0x585d8ad8, 0x3cdc19f9,
+0x6d5b6885, 0x3809aac8, 0x7da7e149, 0xbca5df24,
+0x6379477f, 0xc7953baf, 0x9c6782e7, 0xcab924d8,
+0x0e319d11, 0x6e190440, 0xecf1be0c, 0x8b4940fc,
+0x5ac3a404, 0x60aa3685, 0x421d8f9f, 0x29d74acf,
+0x0ebbd757, 0x2d32d521, 0xacc74cc8, 0xbd2cb4db,
+0x35d8f179, 0xd3e00599, 0xfea923b0, 0x921c158e,
+0x129411a1, 0x9d7caf7b, 0x49e567e6, 0xc4807bdf,
+0xf93181c9, 0x718e08c3, 0x19c6ed21, 0xdef94589,
+0xd0768a4c, 0x148e8c3e, 0x68788954, 0xf34fccad,
diff --git a/src/cpu/intel/haswell/microcode_blob.h b/src/cpu/intel/haswell/microcode_blob.h
index b37ff21..ef79cac 100644
--- a/src/cpu/intel/haswell/microcode_blob.h
+++ b/src/cpu/intel/haswell/microcode_blob.h
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2011 Google Inc.
+ * Copyright 2013 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
@@ -21,6 +21,7 @@
#include "microcode-M32306c2_ffff0003.h"
#include "microcode-M3240660_ffff000b.h"
#include "microcode-M7240650_ffff000a.h"
+#include "microcode-M7240651_00000006.h"
/* Dummy terminator */
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
1
0
Patch set updated for coreboot: 5b33ad3 coreboot: add vboot_handoff to coreboot tables
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2857
-gerrit
commit 5b33ad31a128220f7cec666bd553e9fbf4d6bbea
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Mar 7 23:15:06 2013 -0600
coreboot: add vboot_handoff to coreboot tables
The vboot_handoff structure contians the VbInitParams as well as the
shared vboot data. In order for the boot loader to find it, the
structure address and size needs to be obtained from the coreboot
tables.
Change-Id: I6573d479009ccbf373a7325f861bebe8dc9f5cf8
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/arch/x86/boot/coreboot_table.c | 26 +++++++++++++++++++++++++-
src/include/boot/coreboot_tables.h | 9 +++++++++
src/vendorcode/google/chromeos/chromeos.c | 14 ++++++++++++++
src/vendorcode/google/chromeos/chromeos.h | 2 ++
4 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c
index 530849f..a456484 100644
--- a/src/arch/x86/boot/coreboot_table.c
+++ b/src/arch/x86/boot/coreboot_table.c
@@ -36,6 +36,7 @@
#endif
#if CONFIG_CHROMEOS
#include <arch/acpi.h>
+#include <vendorcode/google/chromeos/chromeos.h>
#include <vendorcode/google/chromeos/gnvs.h>
#endif
@@ -219,7 +220,27 @@ static void lb_vbnv(struct lb_header *header)
vbnv->vbnv_start = CONFIG_VBNV_OFFSET + 14;
vbnv->vbnv_size = CONFIG_VBNV_SIZE;
}
-#endif
+
+#if CONFIG_VBOOT_VERIFY_FIRMWARE
+static void lb_vboot_handoff(struct lb_header *header)
+{
+ void *addr;
+ uint32_t size;
+ struct lb_vboot_handoff* vbho;
+
+ if (vboot_get_handoff_info(&addr, &size))
+ return;
+
+ vbho = (struct lb_vboot_handoff *)lb_new_record(header);
+ vbho->tag = LB_TAB_VBOOT_HANDOFF;
+ vbho->size = sizeof(*vbho);
+ vbho->vboot_handoff_addr = addr;
+ vbho->vboot_handoff_size = size;
+}
+#else
+static inline void lb_vboot_handoff(struct lb_header *header) {}
+#endif /* CONFIG_VBOOT_VERIFY_FIRMWARE */
+#endif /* CONFIG_CHROMEOS */
static void add_cbmem_pointers(struct lb_header *header)
{
@@ -697,6 +718,9 @@ unsigned long write_coreboot_table(
/* pass along VBNV offsets in CMOS */
lb_vbnv(head);
+
+ /* pass along the vboot_handoff address. */
+ lb_vboot_handoff(head);
#endif
add_cbmem_pointers(head);
diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h
index 9cf90d3..71ad3f0 100644
--- a/src/include/boot/coreboot_tables.h
+++ b/src/include/boot/coreboot_tables.h
@@ -241,6 +241,15 @@ struct lb_vbnv {
uint32_t vbnv_size;
};
+#define LB_TAB_VBOOT_HANDOFF 0x0020
+struct lb_vboot_handoff {
+ uint32_t tag;
+ uint32_t size;
+
+ void *vboot_handoff_addr;
+ uint32_t vboot_handoff_size;
+};
+
/* The following structures are for the cmos definitions table */
#define LB_TAG_CMOS_OPTION_TABLE 200
/* cmos header record */
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index 559f1f0..abe7104 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -66,4 +66,18 @@ void *vboot_get_payload(int *len)
return (void *)fwc->address;
}
+
+int vboot_get_handoff_info(void **addr, uint32_t *size)
+{
+ struct vboot_handoff *vboot_handoff;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return -1;
+
+ *addr = vboot_handoff;
+ *size = sizeof(*vboot_handoff);
+ return 0;
+}
#endif
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index 8410707..d241085 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -49,6 +49,8 @@ void init_chromeos(int bootmode);
struct romstage_handoff;
void vboot_verify_firmware(struct romstage_handoff *handoff);
void *vboot_get_payload(int *len);
+/* Returns 0 on success < 0 on error. */
+int vboot_get_handoff_info(void **addr, uint32_t *size);
#endif
#endif
1
0
Patch set updated for coreboot: 10bdf5c haswell: vboot path support in romstage
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2856
-gerrit
commit 10bdf5cfbe5bb8424d42ccd775d9ae2645349ac7
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Mar 1 17:40:49 2013 -0600
haswell: vboot path support in romstage
Take the vboot path in romstage. This will complete the haswell
support for vboot firmware selection.
Built and booted. Noted firmware select worked on an image with
RW firmware support. Also checked that recovery mode worked as
well by choosing the RO path.
Change-Id: Ie2b0a34e6c5c45e6f0d25f77a5fdbaef0324cb09
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/intel/haswell/romstage.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c
index 1d58191..54f4a97 100644
--- a/src/cpu/intel/haswell/romstage.c
+++ b/src/cpu/intel/haswell/romstage.c
@@ -298,13 +298,11 @@ void romstage_common(const struct romstage_params *params)
#endif
}
-static inline void prepare_for_resume(void)
+static inline void prepare_for_resume(struct romstage_handoff *handoff)
{
/* Only need to save memory when ramstage isn't relocatable. */
#if !CONFIG_RELOCATABLE_RAMSTAGE
#if CONFIG_HAVE_ACPI_RESUME
- struct romstage_handoff *handoff = romstage_handoff_find_or_add();
-
/* Back up the OS-controlled memory where ramstage will be loaded. */
if (handoff != NULL && handoff->s3_resume) {
void *src = (void *)CONFIG_RAMBASE;
@@ -318,7 +316,16 @@ static inline void prepare_for_resume(void)
void romstage_after_car(void)
{
- prepare_for_resume();
+ struct romstage_handoff *handoff;
+
+ handoff = romstage_handoff_find_or_add();
+
+ prepare_for_resume(handoff);
+
+#if CONFIG_VBOOT_VERIFY_FIRMWARE
+ vboot_verify_firmware(handoff);
+#endif
+
/* Load the ramstage. */
copy_and_run(0);
}
1
0
Patch set updated for coreboot: 438fac9 WIP: Unify coreboot table generation
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2863
-gerrit
commit 438fac9abc1251394618d06367064ba77f534c8e
Author: Stefan Reinauer <reinauer(a)chromium.org>
Date: Wed Mar 20 14:08:04 2013 -0700
WIP: Unify coreboot table generation
*** DO NOT SUBMIT *** DO NOT SUBMIT *** DO NOT SUBMIT ***
coreboot tables are, unlike general system tables, a platform
independent concept. Hence, use the same code for coreboot table
generation on all platforms. lib/coreboot_tables.c is based
on the x86 version of the file, because some important fixes
were missed on the ARMv7 version lately.
This needs to refactored in a number of ways:
- Use macro for aligning table ends
- fix lb_serial for ARMv7
- lots of other things?
Change-Id: Icc38baf609f10536a320d21ac64408bef44bb77d
Signed-off-by: Stefan Reinauer <reinauer(a)coreboot.org>
---
src/arch/armv7/boot/Makefile.inc | 1 -
src/arch/armv7/boot/coreboot_table.c | 675 -----------------------
src/arch/armv7/boot/tables.c | 2 +-
src/arch/armv7/include/arch/coreboot_tables.h | 10 +-
src/arch/x86/boot/Makefile.inc | 1 -
src/arch/x86/boot/coreboot_table.c | 730 -------------------------
src/lib/Makefile.inc | 1 +
src/lib/coreboot_table.c | 735 ++++++++++++++++++++++++++
src/vendorcode/google/chromeos/Kconfig | 2 +
9 files changed, 741 insertions(+), 1416 deletions(-)
diff --git a/src/arch/armv7/boot/Makefile.inc b/src/arch/armv7/boot/Makefile.inc
index a0752d6..8d24fae 100644
--- a/src/arch/armv7/boot/Makefile.inc
+++ b/src/arch/armv7/boot/Makefile.inc
@@ -1,5 +1,4 @@
ramstage-y += boot.c
-ramstage-y += coreboot_table.c
#ramstage-$(CONFIG_MULTIBOOT) += multiboot.c
ramstage-y += tables.c
#ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
diff --git a/src/arch/armv7/boot/coreboot_table.c b/src/arch/armv7/boot/coreboot_table.c
deleted file mode 100644
index e5aa6ed..0000000
--- a/src/arch/armv7/boot/coreboot_table.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003-2004 Eric Biederman
- * Copyright (C) 2005-2010 coresystems GmbH
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#include <console/console.h>
-#include <ip_checksum.h>
-#include <boot/tables.h>
-#include <arch/coreboot_tables.h>
-#include <string.h>
-#include <version.h>
-#include <device/device.h>
-#include <stdlib.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#if CONFIG_USE_OPTION_TABLE
-#include <option_table.h>
-#endif
-#if CONFIG_CHROMEOS
-//#include <arch/acpi.h>
-#include <vendorcode/google/chromeos/gnvs.h>
-#endif
-
-static struct lb_header *lb_table_init(unsigned long addr)
-{
- struct lb_header *header;
-
- /* 16 byte align the address */
- addr += 15;
- addr &= ~15;
-
- header = (void *)addr;
- header->signature[0] = 'L';
- header->signature[1] = 'B';
- header->signature[2] = 'I';
- header->signature[3] = 'O';
- header->header_bytes = sizeof(*header);
- header->header_checksum = 0;
- header->table_bytes = 0;
- header->table_checksum = 0;
- header->table_entries = 0;
- return header;
-}
-
-static struct lb_record *lb_first_record(struct lb_header *header)
-{
- struct lb_record *rec;
- rec = (void *)(((char *)header) + sizeof(*header));
- return rec;
-}
-
-static struct lb_record *lb_last_record(struct lb_header *header)
-{
- struct lb_record *rec;
- rec = (void *)(((char *)header) + sizeof(*header) + header->table_bytes);
- return rec;
-}
-
-#if 0
-static struct lb_record *lb_next_record(struct lb_record *rec)
-{
- rec = (void *)(((char *)rec) + rec->size);
- return rec;
-}
-#endif
-
-static struct lb_record *lb_new_record(struct lb_header *header)
-{
- struct lb_record *rec;
- rec = lb_last_record(header);
- if (header->table_entries) {
- header->table_bytes += rec->size;
- }
- rec = lb_last_record(header);
- header->table_entries++;
- rec->tag = LB_TAG_UNUSED;
- rec->size = sizeof(*rec);
- return rec;
-}
-
-
-static struct lb_memory *lb_memory(struct lb_header *header)
-{
- struct lb_record *rec;
- struct lb_memory *mem;
- rec = lb_new_record(header);
- mem = (struct lb_memory *)rec;
- mem->tag = LB_TAG_MEMORY;
- mem->size = sizeof(*mem);
- return mem;
-}
-
-static struct lb_serial *lb_serial(struct lb_header *header)
-{
-#if CONFIG_CONSOLE_SERIAL
- if (uartmem_getbaseaddr()) {
- struct lb_record *rec;
- struct lb_serial *serial;
- rec = lb_new_record(header);
- serial = (struct lb_serial *)rec;
- serial->tag = LB_TAG_SERIAL;
- serial->size = sizeof(*serial);
- serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
- serial->baseaddr = uartmem_getbaseaddr();
- serial->baud = CONFIG_TTYS0_BAUD;
- return serial;
- } else {
- return NULL;
- }
-#else
- return NULL;
-#endif
-}
-
-#if CONFIG_CONSOLE_SERIAL8250 || CONFIG_CONSOLE_SERIAL8250MEM || \
- CONFIG_CONSOLE_LOGBUF || CONFIG_USBDEBUG
-static void add_console(struct lb_header *header, u16 consoletype)
-{
- struct lb_console *console;
-
- console = (struct lb_console *)lb_new_record(header);
- console->tag = LB_TAG_CONSOLE;
- console->size = sizeof(*console);
- console->type = consoletype;
-}
-#endif
-
-static void lb_console(struct lb_header *header)
-{
-#if CONFIG_CONSOLE_SERIAL8250
- add_console(header, LB_TAG_CONSOLE_SERIAL8250);
-#endif
-#if CONFIG_CONSOLE_SERIAL8250MEM
- add_console(header, LB_TAG_CONSOLE_SERIAL8250MEM);
-#endif
-#if CONFIG_CONSOLE_LOGBUF
- add_console(header, LB_TAG_CONSOLE_LOGBUF);
-#endif
-#if CONFIG_USBDEBUG
- add_console(header, LB_TAG_CONSOLE_EHCI);
-#endif
-}
-
-static void lb_framebuffer(struct lb_header *header)
-{
-#if CONFIG_FRAMEBUFFER_KEEP_VESA_MODE
- void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
- int vbe_mode_info_valid(void);
-
- // If there isn't any mode info to put in the table, don't ask for it
- // to be filled with junk.
- if (!vbe_mode_info_valid())
- return;
- struct lb_framebuffer *framebuffer;
- framebuffer = (struct lb_framebuffer *)lb_new_record(header);
- framebuffer->tag = LB_TAG_FRAMEBUFFER;
- framebuffer->size = sizeof(*framebuffer);
- fill_lb_framebuffer(framebuffer);
-#endif
-}
-
-#if CONFIG_CHROMEOS
-static void lb_gpios(struct lb_header *header)
-{
- struct lb_gpios *gpios;
- gpios = (struct lb_gpios *)lb_new_record(header);
- gpios->tag = LB_TAG_GPIO;
- fill_lb_gpios(gpios);
-}
-
-#if 0
-static void lb_vdat(struct lb_header *header)
-{
- struct lb_vdat* vdat;
-
- vdat = (struct lb_vdat *)lb_new_record(header);
- vdat->tag = LB_TAG_VDAT;
- vdat->size = sizeof(*vdat);
- acpi_get_vdat_info(&vdat->vdat_addr, &vdat->vdat_size);
-}
-
-static void lb_vbnv(struct lb_header *header)
-{
- struct lb_vbnv* vbnv;
-
- vbnv = (struct lb_vbnv *)lb_new_record(header);
- vbnv->tag = LB_TAG_VBNV;
- vbnv->size = sizeof(*vbnv);
- vbnv->vbnv_start = CONFIG_VBNV_OFFSET + 14;
- vbnv->vbnv_size = CONFIG_VBNV_SIZE;
-}
-#endif
-#endif
-
-static void add_cbmem_pointers(struct lb_header *header)
-{
- /*
- * These CBMEM sections' addresses are included in the coreboot table
- * with the appropriate tags.
- */
- const struct section_id {
- int cbmem_id;
- int table_tag;
- } section_ids[] = {
- {CBMEM_ID_TIMESTAMP, LB_TAG_TIMESTAMPS},
- {CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE}
- };
- int i;
-
- for (i = 0; i < ARRAY_SIZE(section_ids); i++) {
- const struct section_id *sid = section_ids + i;
- struct lb_cbmem_ref *cbmem_ref;
- void *cbmem_addr = cbmem_find(sid->cbmem_id);
-
- if (!cbmem_addr)
- continue; /* This section is not present */
-
- cbmem_ref = (struct lb_cbmem_ref *)lb_new_record(header);
- if (!cbmem_ref) {
- printk(BIOS_ERR, "No more room in coreboot table!\n");
- break;
- }
- cbmem_ref->tag = sid->table_tag;
- cbmem_ref->size = sizeof(*cbmem_ref);
- cbmem_ref->cbmem_addr = (unsigned long)cbmem_addr;
- }
-}
-
-static struct lb_mainboard *lb_mainboard(struct lb_header *header)
-{
- struct lb_record *rec;
- struct lb_mainboard *mainboard;
- rec = lb_new_record(header);
- mainboard = (struct lb_mainboard *)rec;
- mainboard->tag = LB_TAG_MAINBOARD;
-
- mainboard->size = (sizeof(*mainboard) +
- strlen(mainboard_vendor) + 1 +
- strlen(mainboard_part_number) + 1 +
- 3) & ~3;
-
- mainboard->vendor_idx = 0;
- mainboard->part_number_idx = strlen(mainboard_vendor) + 1;
-
- memcpy(mainboard->strings + mainboard->vendor_idx,
- mainboard_vendor, strlen(mainboard_vendor) + 1);
- memcpy(mainboard->strings + mainboard->part_number_idx,
- mainboard_part_number, strlen(mainboard_part_number) + 1);
-
- return mainboard;
-}
-
-#if CONFIG_USE_OPTION_TABLE
-static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header)
-{
- struct lb_record *rec;
- struct cmos_checksum *cmos_checksum;
- rec = lb_new_record(header);
- cmos_checksum = (struct cmos_checksum *)rec;
- cmos_checksum->tag = LB_TAG_OPTION_CHECKSUM;
-
- cmos_checksum->size = (sizeof(*cmos_checksum));
-
- cmos_checksum->range_start = LB_CKS_RANGE_START * 8;
- cmos_checksum->range_end = ( LB_CKS_RANGE_END * 8 ) + 7;
- cmos_checksum->location = LB_CKS_LOC * 8;
- cmos_checksum->type = CHECKSUM_PCBIOS;
-
- return cmos_checksum;
-}
-#endif
-
-static void lb_strings(struct lb_header *header)
-{
- static const struct {
- uint32_t tag;
- const char *string;
- } strings[] = {
- { LB_TAG_VERSION, coreboot_version, },
- { LB_TAG_EXTRA_VERSION, coreboot_extra_version, },
- { LB_TAG_BUILD, coreboot_build, },
- { LB_TAG_COMPILE_TIME, coreboot_compile_time, },
- { LB_TAG_COMPILE_BY, coreboot_compile_by, },
- { LB_TAG_COMPILE_HOST, coreboot_compile_host, },
- { LB_TAG_COMPILE_DOMAIN, coreboot_compile_domain, },
- { LB_TAG_COMPILER, coreboot_compiler, },
- { LB_TAG_LINKER, coreboot_linker, },
- { LB_TAG_ASSEMBLER, coreboot_assembler, },
- };
- unsigned int i;
- for(i = 0; i < ARRAY_SIZE(strings); i++) {
- struct lb_string *rec;
- size_t len;
- rec = (struct lb_string *)lb_new_record(header);
- len = strlen(strings[i].string);
- rec->tag = strings[i].tag;
- rec->size = (sizeof(*rec) + len + 1 + 3) & ~3;
- memcpy(rec->string, strings[i].string, len+1);
- }
-
-}
-
-/* FIXME(dhendrix): used to be static void lb_memory_range(), but compiler
- started complaining since it shares a name with a non-static struct. ugh. */
-static void new_lb_memory_range(struct lb_memory *mem,
- uint32_t type, uint64_t start, uint64_t size)
-{
- int entries;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
- mem->map[entries].start = pack_lb64(start);
- mem->map[entries].size = pack_lb64(size);
- mem->map[entries].type = type;
- mem->size += sizeof(mem->map[0]);
-}
-
-static void lb_reserve_table_memory(struct lb_header *head)
-{
- struct lb_record *last_rec;
- struct lb_memory *mem;
- uint64_t start;
- uint64_t end;
- int i, entries;
-
- last_rec = lb_last_record(head);
- mem = get_lb_mem();
- start = (unsigned long)head;
- end = (unsigned long)last_rec;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
- /* Resize the right two memory areas so this table is in
- * a reserved area of memory. Everything has been carefully
- * setup so that is all we need to do.
- */
- for(i = 0; i < entries; i++ ) {
- uint64_t map_start = unpack_lb64(mem->map[i].start);
- uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
- /* Does this area need to be expanded? */
- if (map_end == start) {
- mem->map[i].size = pack_lb64(end - map_start);
- }
- /* Does this area need to be contracted? */
- else if (map_start == start) {
- mem->map[i].start = pack_lb64(end);
- mem->map[i].size = pack_lb64(map_end - end);
- }
- }
-}
-
-static unsigned long lb_table_fini(struct lb_header *head, int fixup)
-{
- struct lb_record *rec, *first_rec;
- rec = lb_last_record(head);
- if (head->table_entries) {
- head->table_bytes += rec->size;
- }
-
- if (fixup)
- lb_reserve_table_memory(head);
-
- first_rec = lb_first_record(head);
- head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes);
- head->header_checksum = 0;
- head->header_checksum = compute_ip_checksum(head, sizeof(*head));
- printk(BIOS_DEBUG,
- "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
- head, head->table_bytes, head->table_checksum);
- return (unsigned long)rec + rec->size;
-}
-
-static void lb_cleanup_memory_ranges(struct lb_memory *mem)
-{
- int entries;
- int i, j;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
-
- /* Sort the lb memory ranges */
- for(i = 0; i < entries; i++) {
- uint64_t entry_start = unpack_lb64(mem->map[i].start);
- for(j = i; j < entries; j++) {
- uint64_t temp_start = unpack_lb64(mem->map[j].start);
- if (temp_start < entry_start) {
- struct lb_memory_range tmp;
- tmp = mem->map[i];
- mem->map[i] = mem->map[j];
- mem->map[j] = tmp;
- }
- }
- }
-
- /* Merge adjacent entries */
- for(i = 0; (i + 1) < entries; i++) {
- uint64_t start, end, nstart, nend;
- if (mem->map[i].type != mem->map[i + 1].type) {
- continue;
- }
- start = unpack_lb64(mem->map[i].start);
- end = start + unpack_lb64(mem->map[i].size);
- nstart = unpack_lb64(mem->map[i + 1].start);
- nend = nstart + unpack_lb64(mem->map[i + 1].size);
- if ((start <= nstart) && (end > nstart)) {
- if (start > nstart) {
- start = nstart;
- }
- if (end < nend) {
- end = nend;
- }
- /* Record the new region size */
- mem->map[i].start = pack_lb64(start);
- mem->map[i].size = pack_lb64(end - start);
-
- /* Delete the entry I have merged with */
- memmove(&mem->map[i + 1], &mem->map[i + 2],
- ((entries - i - 2) * sizeof(mem->map[0])));
- mem->size -= sizeof(mem->map[0]);
- entries -= 1;
- /* See if I can merge with the next entry as well */
- i -= 1;
- }
- }
-}
-
-static void lb_remove_memory_range(struct lb_memory *mem,
- uint64_t start, uint64_t size)
-{
- uint64_t end;
- int entries;
- int i;
-
- end = start + size;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
-
- /* Remove a reserved area from the memory map */
- for(i = 0; i < entries; i++) {
- uint64_t map_start = unpack_lb64(mem->map[i].start);
- uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
- if ((start <= map_start) && (end >= map_end)) {
- /* Remove the completely covered range */
- memmove(&mem->map[i], &mem->map[i + 1],
- ((entries - i - 1) * sizeof(mem->map[0])));
- mem->size -= sizeof(mem->map[0]);
- entries -= 1;
- /* Since the index will disappear revisit what will appear here */
- i -= 1;
- }
- else if ((start > map_start) && (end < map_end)) {
- /* Split the memory range */
- memmove(&mem->map[i + 1], &mem->map[i],
- ((entries - i) * sizeof(mem->map[0])));
- mem->size += sizeof(mem->map[0]);
- entries += 1;
- /* Update the first map entry */
- mem->map[i].size = pack_lb64(start - map_start);
- /* Update the second map entry */
- mem->map[i + 1].start = pack_lb64(end);
- mem->map[i + 1].size = pack_lb64(map_end - end);
- /* Don't bother with this map entry again */
- i += 1;
- }
- else if ((start <= map_start) && (end > map_start)) {
- /* Shrink the start of the memory range */
- mem->map[i].start = pack_lb64(end);
- mem->map[i].size = pack_lb64(map_end - end);
- }
- else if ((start < map_end) && (start > map_start)) {
- /* Shrink the end of the memory range */
- mem->map[i].size = pack_lb64(start - map_start);
- }
- }
-}
-
-void lb_add_memory_range(struct lb_memory *mem,
- uint32_t type, uint64_t start, uint64_t size)
-{
- lb_remove_memory_range(mem, start, size);
- new_lb_memory_range(mem, type, start, size);
- lb_cleanup_memory_ranges(mem);
-}
-
-static void lb_dump_memory_ranges(struct lb_memory *mem)
-{
- int entries;
- int i;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
-
- printk(BIOS_DEBUG, "coreboot memory table:\n");
- for(i = 0; i < entries; i++) {
- uint64_t entry_start = unpack_lb64(mem->map[i].start);
- uint64_t entry_size = unpack_lb64(mem->map[i].size);
- const char *entry_type;
-
- switch (mem->map[i].type) {
- case LB_MEM_RAM: entry_type="RAM"; break;
- case LB_MEM_RESERVED: entry_type="RESERVED"; break;
- case LB_MEM_ACPI: entry_type="ACPI"; break;
- case LB_MEM_NVS: entry_type="NVS"; break;
- case LB_MEM_UNUSABLE: entry_type="UNUSABLE"; break;
- case LB_MEM_VENDOR_RSVD: entry_type="VENDOR RESERVED"; break;
- case LB_MEM_TABLE: entry_type="CONFIGURATION TABLES"; break;
- default: entry_type="UNKNOWN!"; break;
- }
-
- printk(BIOS_DEBUG, "%2d. %016llx-%016llx: %s\n",
- i, entry_start, entry_start+entry_size-1, entry_type);
-
- }
-}
-
-
-/* Routines to extract part so the coreboot table or
- * information from the coreboot table after we have written it.
- * Currently get_lb_mem relies on a global we can change the
- * implementaiton.
- */
-static struct lb_memory *mem_ranges = 0;
-struct lb_memory *get_lb_mem(void)
-{
- return mem_ranges;
-}
-
-static void build_lb_mem_range(void *gp, struct device *dev, struct resource *res)
-{
- struct lb_memory *mem = gp;
- new_lb_memory_range(mem, LB_MEM_RAM, res->base, res->size);
-}
-
-static struct lb_memory *build_lb_mem(struct lb_header *head)
-{
- struct lb_memory *mem;
-
- /* Record where the lb memory ranges will live */
- mem = lb_memory(head);
- mem_ranges = mem;
-
- /* FIXME: implement this */
- /* Build the raw table of memory */
- search_global_resources(
- IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
- build_lb_mem_range, mem);
- /* FIXME: things die in cleanup_memory_ranges(), skip for now */
-// lb_cleanup_memory_ranges(mem);
- return mem;
-}
-
-static void lb_add_rsvd_range(void *gp, struct device *dev, struct resource *res)
-{
- struct lb_memory *mem = gp;
- lb_add_memory_range(mem, LB_MEM_RESERVED, res->base, res->size);
-}
-
-static void add_lb_reserved(struct lb_memory *mem)
-{
- /* Add reserved ranges */
- search_global_resources(
- IORESOURCE_MEM | IORESOURCE_RESERVE, IORESOURCE_MEM | IORESOURCE_RESERVE,
- lb_add_rsvd_range, mem);
-}
-
-unsigned long write_coreboot_table(
- unsigned long table_start, unsigned long table_end)
-{
- struct lb_header *head;
- struct lb_memory *mem;
- unsigned long fini;
-
- printk(BIOS_DEBUG, "table_start: 0x%lx, table_end: 0x%lx\n",
- table_start, table_end);
- head = lb_table_init(table_start);
-
- table_end = (unsigned long) head + head->table_bytes;
-
- /* FIXME(dhendrix): do we need this? */
- printk(BIOS_DEBUG, "Adjust table_end from 0x%08lx to ", table_end);
- table_end += 0xfff; // 4K aligned
- table_end &= ~0xfff;
- printk(BIOS_DEBUG, "0x%08lx \n", table_end);
-
-#if CONFIG_USE_OPTION_TABLE
- {
- struct cmos_option_table *option_table = cbfs_get_file_content(
- CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
- CBFS_COMPONENT_CMOS_LAYOUT);
- if (option_table) {
- struct lb_record *rec_dest = lb_new_record(head);
- /* Copy the option config table, it's already a lb_record... */
- memcpy(rec_dest, option_table, option_table->size);
- /* Create cmos checksum entry in coreboot table */
- lb_cmos_checksum(head);
- } else {
- printk(BIOS_ERR, "cmos_layout.bin could not be found!\n");
- }
- }
-#endif
- /* Record where RAM is located */
- /* FIXME(dhendrix): add global resources */
- printk(BIOS_DEBUG, "%s: head: 0x%p\n", __func__, head);
- mem = build_lb_mem(head);
- /* FIXME: we seem to get a bogus return value */
- printk(BIOS_DEBUG, "%s: mem: 0x%p\n", __func__, mem);
- if ((unsigned long)mem < CONFIG_RAMBASE) {
- printk(BIOS_DEBUG, "%s: mem < CONFIG_RAMBASE\n" , __func__);
- while (1);
- }
-
- /* Record the mptable and the the lb_table (This will be adjusted later) */
- lb_add_memory_range(mem, LB_MEM_TABLE,
- table_start, table_end - table_start);
-
- /* Record the pirq table, acpi tables, and maybe the mptable */
- lb_add_memory_range(mem, LB_MEM_TABLE,
- table_start, table_end - table_start);
-
- printk(BIOS_DEBUG, "Adding high table area\n");
- // should this be LB_MEM_ACPI?
- lb_add_memory_range(mem, LB_MEM_TABLE,
- table_start, table_end - table_start);
-
- /* Add reserved regions */
- add_lb_reserved(mem);
-
- lb_dump_memory_ranges(mem);
-
- /* Note:
- * I assume that there is always memory at immediately after
- * the table_end. This means that after I setup the coreboot table.
- * I can trivially fixup the reserved memory ranges to hold the correct
- * size of the coreboot table.
- */
-
- /* FIXME(dhendrix): Most of these do nothing at the moment */
- /* Record our motherboard */
- lb_mainboard(head);
- /* Record the serial port, if present */
- lb_serial(head);
- /* Record our console setup */
- lb_console(head);
- /* Record our various random string information */
- lb_strings(head);
- /* Record our framebuffer */
- lb_framebuffer(head);
-#if CONFIG_CHROMEOS
- /* Record our GPIO settings (ChromeOS specific) */
- lb_gpios(head);
-
-#if 0
- /* pass along the VDAT buffer adress */
- lb_vdat(head);
-
- /* pass along VBNV offsets in CMOS */
- lb_vbnv(head);
-#endif
-#endif
- add_cbmem_pointers(head);
-
- /* Remember where my valid memory ranges are */
- fini = lb_table_fini(head, 1);
- printk(BIOS_DEBUG, "%s: DONE: fini is 0x%lx\n", __func__, fini);
- return fini;
-
-}
diff --git a/src/arch/armv7/boot/tables.c b/src/arch/armv7/boot/tables.c
index e9fb6ab..3578a64 100644
--- a/src/arch/armv7/boot/tables.c
+++ b/src/arch/armv7/boot/tables.c
@@ -57,7 +57,7 @@ struct lb_memory *write_tables(void)
MAX_COREBOOT_TABLE_SIZE);
if (table_pointer) {
unsigned long new_table_pointer;
- new_table_pointer = write_coreboot_table(table_pointer,
+ new_table_pointer = write_coreboot_table(0UL, 0UL, table_pointer,
high_tables_size);
if (table_pointer > (table_pointer + MAX_COREBOOT_TABLE_SIZE)) {
printk(BIOS_ERR, "%s: coreboot table didn't fit (%lx)\n",
diff --git a/src/arch/armv7/include/arch/coreboot_tables.h b/src/arch/armv7/include/arch/coreboot_tables.h
index c5eacf8..72449f0 100644
--- a/src/arch/armv7/include/arch/coreboot_tables.h
+++ b/src/arch/armv7/include/arch/coreboot_tables.h
@@ -7,10 +7,8 @@
/* This file holds function prototypes for building the coreboot table. */
unsigned long write_coreboot_table(
- unsigned long table_start, unsigned long table_end);
-
-void lb_memory_range(struct lb_memory *mem,
- uint32_t type, uint64_t start, uint64_t size);
+ unsigned long low_table_start, unsigned long low_table_end,
+ unsigned long rom_table_start, unsigned long rom_table_end);
void lb_add_memory_range(struct lb_memory *mem,
uint32_t type, uint64_t start, uint64_t size);
@@ -24,8 +22,4 @@ struct lb_memory *get_lb_mem(void);
extern struct cmos_option_table option_table;
-/* defined by mainboard.c if the mainboard requires extra resources */
-int add_mainboard_resources(struct lb_memory *mem);
-int add_northbridge_resources(struct lb_memory *mem);
-
#endif /* COREBOOT_TABLE_H */
diff --git a/src/arch/x86/boot/Makefile.inc b/src/arch/x86/boot/Makefile.inc
index 9c18043..7b67e49 100644
--- a/src/arch/x86/boot/Makefile.inc
+++ b/src/arch/x86/boot/Makefile.inc
@@ -1,5 +1,4 @@
ramstage-y += boot.c
-ramstage-y += coreboot_table.c
ramstage-$(CONFIG_MULTIBOOT) += multiboot.c
ramstage-y += gdt.c
ramstage-y += tables.c
diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c
deleted file mode 100644
index a456484..0000000
--- a/src/arch/x86/boot/coreboot_table.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003-2004 Eric Biederman
- * Copyright (C) 2005-2010 coresystems GmbH
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#include <console/console.h>
-#include <ip_checksum.h>
-#include <boot/tables.h>
-#include <boot/coreboot_tables.h>
-#include <arch/coreboot_tables.h>
-#include <string.h>
-#include <version.h>
-#include <device/device.h>
-#include <stdlib.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#if CONFIG_USE_OPTION_TABLE
-#include <option_table.h>
-#endif
-#if CONFIG_CHROMEOS
-#include <arch/acpi.h>
-#include <vendorcode/google/chromeos/chromeos.h>
-#include <vendorcode/google/chromeos/gnvs.h>
-#endif
-
-static struct lb_header *lb_table_init(unsigned long addr)
-{
- struct lb_header *header;
-
- /* 16 byte align the address */
- addr += 15;
- addr &= ~15;
-
- header = (void *)addr;
- header->signature[0] = 'L';
- header->signature[1] = 'B';
- header->signature[2] = 'I';
- header->signature[3] = 'O';
- header->header_bytes = sizeof(*header);
- header->header_checksum = 0;
- header->table_bytes = 0;
- header->table_checksum = 0;
- header->table_entries = 0;
- return header;
-}
-
-static struct lb_record *lb_first_record(struct lb_header *header)
-{
- struct lb_record *rec;
- rec = (void *)(((char *)header) + sizeof(*header));
- return rec;
-}
-
-static struct lb_record *lb_last_record(struct lb_header *header)
-{
- struct lb_record *rec;
- rec = (void *)(((char *)header) + sizeof(*header) + header->table_bytes);
- return rec;
-}
-
-#if 0
-static struct lb_record *lb_next_record(struct lb_record *rec)
-{
- rec = (void *)(((char *)rec) + rec->size);
- return rec;
-}
-#endif
-
-static struct lb_record *lb_new_record(struct lb_header *header)
-{
- struct lb_record *rec;
- rec = lb_last_record(header);
- if (header->table_entries) {
- header->table_bytes += rec->size;
- }
- rec = lb_last_record(header);
- header->table_entries++;
- rec->tag = LB_TAG_UNUSED;
- rec->size = sizeof(*rec);
- return rec;
-}
-
-
-static struct lb_memory *lb_memory(struct lb_header *header)
-{
- struct lb_record *rec;
- struct lb_memory *mem;
- rec = lb_new_record(header);
- mem = (struct lb_memory *)rec;
- mem->tag = LB_TAG_MEMORY;
- mem->size = sizeof(*mem);
- return mem;
-}
-
-static struct lb_serial *lb_serial(struct lb_header *header)
-{
-#if CONFIG_CONSOLE_SERIAL8250
- struct lb_record *rec;
- struct lb_serial *serial;
- rec = lb_new_record(header);
- serial = (struct lb_serial *)rec;
- serial->tag = LB_TAG_SERIAL;
- serial->size = sizeof(*serial);
- serial->type = LB_SERIAL_TYPE_IO_MAPPED;
- serial->baseaddr = CONFIG_TTYS0_BASE;
- serial->baud = CONFIG_TTYS0_BAUD;
- return serial;
-#elif CONFIG_CONSOLE_SERIAL8250MEM
- if (uartmem_getbaseaddr()) {
- struct lb_record *rec;
- struct lb_serial *serial;
- rec = lb_new_record(header);
- serial = (struct lb_serial *)rec;
- serial->tag = LB_TAG_SERIAL;
- serial->size = sizeof(*serial);
- serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
- serial->baseaddr = uartmem_getbaseaddr();
- serial->baud = CONFIG_TTYS0_BAUD;
- return serial;
- } else {
- return NULL;
- }
-#else
- return NULL;
-#endif
-}
-
-#if CONFIG_CONSOLE_SERIAL8250 || CONFIG_CONSOLE_SERIAL8250MEM || \
- CONFIG_CONSOLE_LOGBUF || CONFIG_USBDEBUG
-static void add_console(struct lb_header *header, u16 consoletype)
-{
- struct lb_console *console;
-
- console = (struct lb_console *)lb_new_record(header);
- console->tag = LB_TAG_CONSOLE;
- console->size = sizeof(*console);
- console->type = consoletype;
-}
-#endif
-
-static void lb_console(struct lb_header *header)
-{
-#if CONFIG_CONSOLE_SERIAL8250
- add_console(header, LB_TAG_CONSOLE_SERIAL8250);
-#endif
-#if CONFIG_CONSOLE_SERIAL8250MEM
- add_console(header, LB_TAG_CONSOLE_SERIAL8250MEM);
-#endif
-#if CONFIG_CONSOLE_LOGBUF
- add_console(header, LB_TAG_CONSOLE_LOGBUF);
-#endif
-#if CONFIG_USBDEBUG
- add_console(header, LB_TAG_CONSOLE_EHCI);
-#endif
-}
-
-static void lb_framebuffer(struct lb_header *header)
-{
-#if CONFIG_FRAMEBUFFER_KEEP_VESA_MODE || CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
- void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
- int vbe_mode_info_valid(void);
-
- // If there isn't any mode info to put in the table, don't ask for it
- // to be filled with junk.
- if (!vbe_mode_info_valid())
- return;
- struct lb_framebuffer *framebuffer;
- framebuffer = (struct lb_framebuffer *)lb_new_record(header);
- framebuffer->tag = LB_TAG_FRAMEBUFFER;
- framebuffer->size = sizeof(*framebuffer);
- fill_lb_framebuffer(framebuffer);
-#endif
-}
-
-#if CONFIG_CHROMEOS
-static void lb_gpios(struct lb_header *header)
-{
- struct lb_gpios *gpios;
- gpios = (struct lb_gpios *)lb_new_record(header);
- gpios->tag = LB_TAG_GPIO;
- gpios->size = sizeof(*gpios);
- gpios->count = 0;
- fill_lb_gpios(gpios);
-}
-
-static void lb_vdat(struct lb_header *header)
-{
- struct lb_vdat* vdat;
-
- vdat = (struct lb_vdat *)lb_new_record(header);
- vdat->tag = LB_TAG_VDAT;
- vdat->size = sizeof(*vdat);
- acpi_get_vdat_info(&vdat->vdat_addr, &vdat->vdat_size);
-}
-
-static void lb_vbnv(struct lb_header *header)
-{
- struct lb_vbnv* vbnv;
-
- vbnv = (struct lb_vbnv *)lb_new_record(header);
- vbnv->tag = LB_TAG_VBNV;
- vbnv->size = sizeof(*vbnv);
- vbnv->vbnv_start = CONFIG_VBNV_OFFSET + 14;
- vbnv->vbnv_size = CONFIG_VBNV_SIZE;
-}
-
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
-static void lb_vboot_handoff(struct lb_header *header)
-{
- void *addr;
- uint32_t size;
- struct lb_vboot_handoff* vbho;
-
- if (vboot_get_handoff_info(&addr, &size))
- return;
-
- vbho = (struct lb_vboot_handoff *)lb_new_record(header);
- vbho->tag = LB_TAB_VBOOT_HANDOFF;
- vbho->size = sizeof(*vbho);
- vbho->vboot_handoff_addr = addr;
- vbho->vboot_handoff_size = size;
-}
-#else
-static inline void lb_vboot_handoff(struct lb_header *header) {}
-#endif /* CONFIG_VBOOT_VERIFY_FIRMWARE */
-#endif /* CONFIG_CHROMEOS */
-
-static void add_cbmem_pointers(struct lb_header *header)
-{
- /*
- * These CBMEM sections' addresses are included in the coreboot table
- * with the appropriate tags.
- */
- const struct section_id {
- int cbmem_id;
- int table_tag;
- } section_ids[] = {
- {CBMEM_ID_TIMESTAMP, LB_TAG_TIMESTAMPS},
- {CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE}
- };
- int i;
-
- for (i = 0; i < ARRAY_SIZE(section_ids); i++) {
- const struct section_id *sid = section_ids + i;
- struct lb_cbmem_ref *cbmem_ref;
- void *cbmem_addr = cbmem_find(sid->cbmem_id);
-
- if (!cbmem_addr)
- continue; /* This section is not present */
-
- cbmem_ref = (struct lb_cbmem_ref *)lb_new_record(header);
- if (!cbmem_ref) {
- printk(BIOS_ERR, "No more room in coreboot table!\n");
- break;
- }
- cbmem_ref->tag = sid->table_tag;
- cbmem_ref->size = sizeof(*cbmem_ref);
- cbmem_ref->cbmem_addr = (unsigned long)cbmem_addr;
- }
-}
-
-static struct lb_mainboard *lb_mainboard(struct lb_header *header)
-{
- struct lb_record *rec;
- struct lb_mainboard *mainboard;
- rec = lb_new_record(header);
- mainboard = (struct lb_mainboard *)rec;
- mainboard->tag = LB_TAG_MAINBOARD;
-
- mainboard->size = (sizeof(*mainboard) +
- strlen(mainboard_vendor) + 1 +
- strlen(mainboard_part_number) + 1 +
- 3) & ~3;
-
- mainboard->vendor_idx = 0;
- mainboard->part_number_idx = strlen(mainboard_vendor) + 1;
-
- memcpy(mainboard->strings + mainboard->vendor_idx,
- mainboard_vendor, strlen(mainboard_vendor) + 1);
- memcpy(mainboard->strings + mainboard->part_number_idx,
- mainboard_part_number, strlen(mainboard_part_number) + 1);
-
- return mainboard;
-}
-
-#if CONFIG_USE_OPTION_TABLE
-static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header)
-{
- struct lb_record *rec;
- struct cmos_checksum *cmos_checksum;
- rec = lb_new_record(header);
- cmos_checksum = (struct cmos_checksum *)rec;
- cmos_checksum->tag = LB_TAG_OPTION_CHECKSUM;
-
- cmos_checksum->size = (sizeof(*cmos_checksum));
-
- cmos_checksum->range_start = LB_CKS_RANGE_START * 8;
- cmos_checksum->range_end = ( LB_CKS_RANGE_END * 8 ) + 7;
- cmos_checksum->location = LB_CKS_LOC * 8;
- cmos_checksum->type = CHECKSUM_PCBIOS;
-
- return cmos_checksum;
-}
-#endif
-
-static void lb_strings(struct lb_header *header)
-{
- static const struct {
- uint32_t tag;
- const char *string;
- } strings[] = {
- { LB_TAG_VERSION, coreboot_version, },
- { LB_TAG_EXTRA_VERSION, coreboot_extra_version, },
- { LB_TAG_BUILD, coreboot_build, },
- { LB_TAG_COMPILE_TIME, coreboot_compile_time, },
- { LB_TAG_COMPILE_BY, coreboot_compile_by, },
- { LB_TAG_COMPILE_HOST, coreboot_compile_host, },
- { LB_TAG_COMPILE_DOMAIN, coreboot_compile_domain, },
- { LB_TAG_COMPILER, coreboot_compiler, },
- { LB_TAG_LINKER, coreboot_linker, },
- { LB_TAG_ASSEMBLER, coreboot_assembler, },
- };
- unsigned int i;
- for(i = 0; i < ARRAY_SIZE(strings); i++) {
- struct lb_string *rec;
- size_t len;
- rec = (struct lb_string *)lb_new_record(header);
- len = strlen(strings[i].string);
- rec->tag = strings[i].tag;
- rec->size = (sizeof(*rec) + len + 1 + 3) & ~3;
- memcpy(rec->string, strings[i].string, len+1);
- }
-
-}
-
-static struct lb_forward *lb_forward(struct lb_header *header, struct lb_header *next_header)
-{
- struct lb_record *rec;
- struct lb_forward *forward;
- rec = lb_new_record(header);
- forward = (struct lb_forward *)rec;
- forward->tag = LB_TAG_FORWARD;
- forward->size = sizeof(*forward);
- forward->forward = (uint64_t)(unsigned long)next_header;
- return forward;
-}
-
-static void lb_memory_range(struct lb_memory *mem,
- uint32_t type, uint64_t start, uint64_t size)
-{
- int entries;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
- mem->map[entries].start = pack_lb64(start);
- mem->map[entries].size = pack_lb64(size);
- mem->map[entries].type = type;
- mem->size += sizeof(mem->map[0]);
-}
-
-static void lb_reserve_table_memory(struct lb_header *head)
-{
-/* Dynamic cbmem has already reserved the memory where the coreboot tables
- * reside. Therefore, there is nothing to fix up. */
-#if !CONFIG_DYNAMIC_CBMEM
- struct lb_record *last_rec;
- struct lb_memory *mem;
- uint64_t start;
- uint64_t end;
- int i, entries;
-
- last_rec = lb_last_record(head);
- mem = get_lb_mem();
- start = (unsigned long)head;
- end = (unsigned long)last_rec;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
- /* Resize the right two memory areas so this table is in
- * a reserved area of memory. Everything has been carefully
- * setup so that is all we need to do.
- */
- for(i = 0; i < entries; i++ ) {
- uint64_t map_start = unpack_lb64(mem->map[i].start);
- uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
- /* Does this area need to be expanded? */
- if (map_end == start) {
- mem->map[i].size = pack_lb64(end - map_start);
- }
- /* Does this area need to be contracted? */
- else if (map_start == start) {
- mem->map[i].start = pack_lb64(end);
- mem->map[i].size = pack_lb64(map_end - end);
- }
- }
-#endif
-}
-
-static unsigned long lb_table_fini(struct lb_header *head, int fixup)
-{
- struct lb_record *rec, *first_rec;
- rec = lb_last_record(head);
- if (head->table_entries) {
- head->table_bytes += rec->size;
- }
-
- if (fixup)
- lb_reserve_table_memory(head);
-
- first_rec = lb_first_record(head);
- head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes);
- head->header_checksum = 0;
- head->header_checksum = compute_ip_checksum(head, sizeof(*head));
- printk(BIOS_DEBUG,
- "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
- head, head->table_bytes, head->table_checksum);
- return (unsigned long)rec + rec->size;
-}
-
-static void lb_cleanup_memory_ranges(struct lb_memory *mem)
-{
- int entries;
- int i, j;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
-
- /* Sort the lb memory ranges */
- for(i = 0; i < entries; i++) {
- uint64_t entry_start = unpack_lb64(mem->map[i].start);
- for(j = i + 1; j < entries; j++) {
- uint64_t temp_start = unpack_lb64(mem->map[j].start);
- if (temp_start < entry_start) {
- struct lb_memory_range tmp;
- tmp = mem->map[i];
- mem->map[i] = mem->map[j];
- mem->map[j] = tmp;
- }
- }
- }
-
- /* Merge adjacent entries */
- for(i = 0; (i + 1) < entries; i++) {
- uint64_t start, end, nstart, nend;
- if (mem->map[i].type != mem->map[i + 1].type) {
- continue;
- }
- start = unpack_lb64(mem->map[i].start);
- end = start + unpack_lb64(mem->map[i].size);
- nstart = unpack_lb64(mem->map[i + 1].start);
- nend = nstart + unpack_lb64(mem->map[i + 1].size);
- if ((start <= nstart) && (end >= nstart)) {
- if (start > nstart) {
- start = nstart;
- }
- if (end < nend) {
- end = nend;
- }
- /* Record the new region size */
- mem->map[i].start = pack_lb64(start);
- mem->map[i].size = pack_lb64(end - start);
-
- /* Delete the entry I have merged with */
- memmove(&mem->map[i + 1], &mem->map[i + 2],
- ((entries - i - 2) * sizeof(mem->map[0])));
- mem->size -= sizeof(mem->map[0]);
- entries -= 1;
- /* See if I can merge with the next entry as well */
- i -= 1;
- }
- }
-}
-
-static void lb_remove_memory_range(struct lb_memory *mem,
- uint64_t start, uint64_t size)
-{
- uint64_t end;
- int entries;
- int i;
-
- end = start + size;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
-
- /* Remove a reserved area from the memory map */
- for(i = 0; i < entries; i++) {
- uint64_t map_start = unpack_lb64(mem->map[i].start);
- uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
- if ((start <= map_start) && (end >= map_end)) {
- /* Remove the completely covered range */
- memmove(&mem->map[i], &mem->map[i + 1],
- ((entries - i - 1) * sizeof(mem->map[0])));
- mem->size -= sizeof(mem->map[0]);
- entries -= 1;
- /* Since the index will disappear revisit what will appear here */
- i -= 1;
- }
- else if ((start > map_start) && (end < map_end)) {
- /* Split the memory range */
- memmove(&mem->map[i + 1], &mem->map[i],
- ((entries - i) * sizeof(mem->map[0])));
- mem->size += sizeof(mem->map[0]);
- entries += 1;
- /* Update the first map entry */
- mem->map[i].size = pack_lb64(start - map_start);
- /* Update the second map entry */
- mem->map[i + 1].start = pack_lb64(end);
- mem->map[i + 1].size = pack_lb64(map_end - end);
- /* Don't bother with this map entry again */
- i += 1;
- }
- else if ((start <= map_start) && (end > map_start)) {
- /* Shrink the start of the memory range */
- mem->map[i].start = pack_lb64(end);
- mem->map[i].size = pack_lb64(map_end - end);
- }
- else if ((start < map_end) && (start > map_start)) {
- /* Shrink the end of the memory range */
- mem->map[i].size = pack_lb64(start - map_start);
- }
- }
-}
-
-void lb_add_memory_range(struct lb_memory *mem,
- uint32_t type, uint64_t start, uint64_t size)
-{
- lb_remove_memory_range(mem, start, size);
- lb_memory_range(mem, type, start, size);
- lb_cleanup_memory_ranges(mem);
-}
-
-static void lb_dump_memory_ranges(struct lb_memory *mem)
-{
- int entries;
- int i;
- entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
-
- printk(BIOS_DEBUG, "coreboot memory table:\n");
- for(i = 0; i < entries; i++) {
- uint64_t entry_start = unpack_lb64(mem->map[i].start);
- uint64_t entry_size = unpack_lb64(mem->map[i].size);
- const char *entry_type;
-
- switch (mem->map[i].type) {
- case LB_MEM_RAM: entry_type="RAM"; break;
- case LB_MEM_RESERVED: entry_type="RESERVED"; break;
- case LB_MEM_ACPI: entry_type="ACPI"; break;
- case LB_MEM_NVS: entry_type="NVS"; break;
- case LB_MEM_UNUSABLE: entry_type="UNUSABLE"; break;
- case LB_MEM_VENDOR_RSVD: entry_type="VENDOR RESERVED"; break;
- case LB_MEM_TABLE: entry_type="CONFIGURATION TABLES"; break;
- default: entry_type="UNKNOWN!"; break;
- }
-
- printk(BIOS_DEBUG, "%2d. %016llx-%016llx: %s\n",
- i, entry_start, entry_start+entry_size-1, entry_type);
-
- }
-}
-
-
-/* Routines to extract part so the coreboot table or
- * information from the coreboot table after we have written it.
- * Currently get_lb_mem relies on a global we can change the
- * implementaiton.
- */
-static struct lb_memory *mem_ranges = 0;
-struct lb_memory *get_lb_mem(void)
-{
- return mem_ranges;
-}
-
-static void build_lb_mem_range(void *gp, struct device *dev, struct resource *res)
-{
- struct lb_memory *mem = gp;
- lb_memory_range(mem, LB_MEM_RAM, res->base, res->size);
-}
-
-static struct lb_memory *build_lb_mem(struct lb_header *head)
-{
- struct lb_memory *mem;
-
- /* Record where the lb memory ranges will live */
- mem = lb_memory(head);
- mem_ranges = mem;
-
- /* Build the raw table of memory */
- search_global_resources(
- IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
- build_lb_mem_range, mem);
- lb_cleanup_memory_ranges(mem);
- return mem;
-}
-
-static void lb_add_rsvd_range(void *gp, struct device *dev, struct resource *res)
-{
- struct lb_memory *mem = gp;
- lb_add_memory_range(mem, LB_MEM_RESERVED, res->base, res->size);
-}
-
-static void add_lb_reserved(struct lb_memory *mem)
-{
- /* Add reserved ranges */
- search_global_resources(
- IORESOURCE_MEM | IORESOURCE_RESERVE, IORESOURCE_MEM | IORESOURCE_RESERVE,
- lb_add_rsvd_range, mem);
-}
-
-unsigned long write_coreboot_table(
- unsigned long low_table_start, unsigned long low_table_end,
- unsigned long rom_table_start, unsigned long rom_table_end)
-{
- struct lb_header *head;
- struct lb_memory *mem;
-
- printk(BIOS_DEBUG, "Writing high table forward entry at 0x%08lx\n",
- low_table_end);
- head = lb_table_init(low_table_end);
- lb_forward(head, (struct lb_header*)rom_table_end);
-
- low_table_end = (unsigned long) lb_table_fini(head, 0);
- printk(BIOS_DEBUG, "New low_table_end: 0x%08lx\n", low_table_end);
- printk(BIOS_DEBUG, "Now going to write high coreboot table at 0x%08lx\n",
- rom_table_end);
-
- head = lb_table_init(rom_table_end);
- rom_table_end = (unsigned long)head;
- printk(BIOS_DEBUG, "rom_table_end = 0x%08lx\n", rom_table_end);
-
- printk(BIOS_DEBUG, "Adjust low_table_end from 0x%08lx to ", low_table_end);
- low_table_end += 0xfff; // 4K aligned
- low_table_end &= ~0xfff;
- printk(BIOS_DEBUG, "0x%08lx \n", low_table_end);
-
- /* The Linux kernel assumes this region is reserved */
- printk(BIOS_DEBUG, "Adjust rom_table_end from 0x%08lx to ", rom_table_end);
- rom_table_end += 0xffff; // 64K align
- rom_table_end &= ~0xffff;
- printk(BIOS_DEBUG, "0x%08lx \n", rom_table_end);
-
-#if CONFIG_USE_OPTION_TABLE
- {
- struct cmos_option_table *option_table = cbfs_get_file_content(
- CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
- CBFS_COMPONENT_CMOS_LAYOUT);
- if (option_table) {
- struct lb_record *rec_dest = lb_new_record(head);
- /* Copy the option config table, it's already a lb_record... */
- memcpy(rec_dest, option_table, option_table->size);
- /* Create cmos checksum entry in coreboot table */
- lb_cmos_checksum(head);
- } else {
- printk(BIOS_ERR, "cmos_layout.bin could not be found!\n");
- }
- }
-#endif
- /* Record where RAM is located */
- mem = build_lb_mem(head);
-
- /* Record the mptable and the the lb_table (This will be adjusted later) */
- lb_add_memory_range(mem, LB_MEM_TABLE,
- low_table_start, low_table_end - low_table_start);
-
- /* Record the pirq table, acpi tables, and maybe the mptable. However,
- * these only need to be added when the rom_table is sitting below
- * 1MiB. If it isn't that means high tables are being written.
- * The code below handles high tables correctly. */
- if (rom_table_end <= (1 << 20))
- lb_add_memory_range(mem, LB_MEM_TABLE,
- rom_table_start, rom_table_end-rom_table_start);
-
-#if CONFIG_DYNAMIC_CBMEM
- cbmem_add_lb_mem(mem);
-#else /* CONFIG_DYNAMIC_CBMEM */
- lb_add_memory_range(mem, LB_MEM_TABLE,
- high_tables_base, high_tables_size);
-#endif /* CONFIG_DYNAMIC_CBMEM */
-
- /* Add reserved regions */
- add_lb_reserved(mem);
-
- lb_dump_memory_ranges(mem);
-
- /* Note:
- * I assume that there is always memory at immediately after
- * the low_table_end. This means that after I setup the coreboot table.
- * I can trivially fixup the reserved memory ranges to hold the correct
- * size of the coreboot table.
- */
-
- /* Record our motherboard */
- lb_mainboard(head);
- /* Record the serial port, if present */
- lb_serial(head);
- /* Record our console setup */
- lb_console(head);
- /* Record our various random string information */
- lb_strings(head);
- /* Record our framebuffer */
- lb_framebuffer(head);
-
-#if CONFIG_CHROMEOS
- /* Record our GPIO settings (ChromeOS specific) */
- lb_gpios(head);
-
- /* pass along the VDAT buffer adress */
- lb_vdat(head);
-
- /* pass along VBNV offsets in CMOS */
- lb_vbnv(head);
-
- /* pass along the vboot_handoff address. */
- lb_vboot_handoff(head);
-#endif
- add_cbmem_pointers(head);
-
- /* Remember where my valid memory ranges are */
- return lb_table_fini(head, 1);
-
-}
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index c0372c5..8eff2a4 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -54,6 +54,7 @@ romstage-$(CONFIG_ARCH_X86) += gcc.c
ramstage-y += hardwaremain.c
ramstage-y += selfboot.c
+ramstage-y += coreboot_table.c
ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
ramstage-y += memset.c
endif
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
new file mode 100644
index 0000000..bd61b3a
--- /dev/null
+++ b/src/lib/coreboot_table.c
@@ -0,0 +1,735 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003-2004 Eric Biederman
+ * Copyright (C) 2005-2010 coresystems GmbH
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <ip_checksum.h>
+#include <boot/tables.h>
+#include <arch/coreboot_tables.h>
+#include <string.h>
+#include <version.h>
+#include <device/device.h>
+#include <stdlib.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#if CONFIG_USE_OPTION_TABLE
+#include <option_table.h>
+#endif
+#if CONFIG_CHROMEOS
+#if CONFIG_GENERATE_ACPI_TABLES
+#include <arch/acpi.h>
+#endif
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <vendorcode/google/chromeos/gnvs.h>
+#endif
+
+static struct lb_header *lb_table_init(unsigned long addr)
+{
+ struct lb_header *header;
+
+ /* 16 byte align the address */
+ addr += 15;
+ addr &= ~15;
+
+ header = (void *)addr;
+ header->signature[0] = 'L';
+ header->signature[1] = 'B';
+ header->signature[2] = 'I';
+ header->signature[3] = 'O';
+ header->header_bytes = sizeof(*header);
+ header->header_checksum = 0;
+ header->table_bytes = 0;
+ header->table_checksum = 0;
+ header->table_entries = 0;
+ return header;
+}
+
+static struct lb_record *lb_first_record(struct lb_header *header)
+{
+ struct lb_record *rec;
+ rec = (void *)(((char *)header) + sizeof(*header));
+ return rec;
+}
+
+static struct lb_record *lb_last_record(struct lb_header *header)
+{
+ struct lb_record *rec;
+ rec = (void *)(((char *)header) + sizeof(*header) + header->table_bytes);
+ return rec;
+}
+
+static struct lb_record *lb_new_record(struct lb_header *header)
+{
+ struct lb_record *rec;
+ rec = lb_last_record(header);
+ if (header->table_entries) {
+ header->table_bytes += rec->size;
+ }
+ rec = lb_last_record(header);
+ header->table_entries++;
+ rec->tag = LB_TAG_UNUSED;
+ rec->size = sizeof(*rec);
+ return rec;
+}
+
+static struct lb_memory *lb_memory(struct lb_header *header)
+{
+ struct lb_record *rec;
+ struct lb_memory *mem;
+ rec = lb_new_record(header);
+ mem = (struct lb_memory *)rec;
+ mem->tag = LB_TAG_MEMORY;
+ mem->size = sizeof(*mem);
+ return mem;
+}
+
+static struct lb_serial *lb_serial(struct lb_header *header)
+{
+#if CONFIG_CONSOLE_SERIAL8250
+ struct lb_record *rec;
+ struct lb_serial *serial;
+ rec = lb_new_record(header);
+ serial = (struct lb_serial *)rec;
+ serial->tag = LB_TAG_SERIAL;
+ serial->size = sizeof(*serial);
+ serial->type = LB_SERIAL_TYPE_IO_MAPPED;
+ serial->baseaddr = CONFIG_TTYS0_BASE;
+ serial->baud = CONFIG_TTYS0_BAUD;
+ return serial;
+#elif CONFIG_CONSOLE_SERIAL8250MEM
+ if (uartmem_getbaseaddr()) {
+ struct lb_record *rec;
+ struct lb_serial *serial;
+ rec = lb_new_record(header);
+ serial = (struct lb_serial *)rec;
+ serial->tag = LB_TAG_SERIAL;
+ serial->size = sizeof(*serial);
+ serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
+ serial->baseaddr = uartmem_getbaseaddr();
+ serial->baud = CONFIG_TTYS0_BAUD;
+ return serial;
+ } else {
+ return NULL;
+ }
+#else
+ return NULL;
+#endif
+}
+
+#if CONFIG_CONSOLE_SERIAL8250 || CONFIG_CONSOLE_SERIAL8250MEM || \
+ CONFIG_CONSOLE_LOGBUF || CONFIG_USBDEBUG
+static void add_console(struct lb_header *header, u16 consoletype)
+{
+ struct lb_console *console;
+
+ console = (struct lb_console *)lb_new_record(header);
+ console->tag = LB_TAG_CONSOLE;
+ console->size = sizeof(*console);
+ console->type = consoletype;
+}
+#endif
+
+static void lb_console(struct lb_header *header)
+{
+#if CONFIG_CONSOLE_SERIAL8250
+ add_console(header, LB_TAG_CONSOLE_SERIAL8250);
+#endif
+#if CONFIG_CONSOLE_SERIAL8250MEM
+ add_console(header, LB_TAG_CONSOLE_SERIAL8250MEM);
+#endif
+#if CONFIG_CONSOLE_LOGBUF
+ add_console(header, LB_TAG_CONSOLE_LOGBUF);
+#endif
+#if CONFIG_USBDEBUG
+ add_console(header, LB_TAG_CONSOLE_EHCI);
+#endif
+}
+
+static void lb_framebuffer(struct lb_header *header)
+{
+#if CONFIG_FRAMEBUFFER_KEEP_VESA_MODE || CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
+ void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
+ int vbe_mode_info_valid(void);
+
+ // If there isn't any mode info to put in the table, don't ask for it
+ // to be filled with junk.
+ if (!vbe_mode_info_valid())
+ return;
+ struct lb_framebuffer *framebuffer;
+ framebuffer = (struct lb_framebuffer *)lb_new_record(header);
+ framebuffer->tag = LB_TAG_FRAMEBUFFER;
+ framebuffer->size = sizeof(*framebuffer);
+ fill_lb_framebuffer(framebuffer);
+#endif
+}
+
+#if CONFIG_CHROMEOS
+static void lb_gpios(struct lb_header *header)
+{
+ struct lb_gpios *gpios;
+ gpios = (struct lb_gpios *)lb_new_record(header);
+ gpios->tag = LB_TAG_GPIO;
+ gpios->size = sizeof(*gpios);
+ gpios->count = 0;
+ fill_lb_gpios(gpios);
+}
+
+static void lb_vdat(struct lb_header *header)
+{
+#if CONFIG_GENERATE_ACPI_TABLES
+ struct lb_vdat* vdat;
+
+ vdat = (struct lb_vdat *)lb_new_record(header);
+ vdat->tag = LB_TAG_VDAT;
+ vdat->size = sizeof(*vdat);
+ acpi_get_vdat_info(&vdat->vdat_addr, &vdat->vdat_size);
+#endif
+}
+
+static void lb_vbnv(struct lb_header *header)
+{
+#if CONFIG_PC80_SYSTEM
+ struct lb_vbnv* vbnv;
+
+ vbnv = (struct lb_vbnv *)lb_new_record(header);
+ vbnv->tag = LB_TAG_VBNV;
+ vbnv->size = sizeof(*vbnv);
+ vbnv->vbnv_start = CONFIG_VBNV_OFFSET + 14;
+ vbnv->vbnv_size = CONFIG_VBNV_SIZE;
+#endif
+}
+
+#if CONFIG_VBOOT_VERIFY_FIRMWARE
+static void lb_vboot_handoff(struct lb_header *header)
+{
+ void *addr;
+ uint32_t size;
+ struct lb_vboot_handoff* vbho;
+
+ if (vboot_get_handoff_info(&addr, &size))
+ return;
+
+ vbho = (struct lb_vboot_handoff *)lb_new_record(header);
+ vbho->tag = LB_TAB_VBOOT_HANDOFF;
+ vbho->size = sizeof(*vbho);
+ vbho->vboot_handoff_addr = addr;
+ vbho->vboot_handoff_size = size;
+}
+#else
+static inline void lb_vboot_handoff(struct lb_header *header) {}
+#endif /* CONFIG_VBOOT_VERIFY_FIRMWARE */
+#endif /* CONFIG_CHROMEOS */
+
+static void add_cbmem_pointers(struct lb_header *header)
+{
+ /*
+ * These CBMEM sections' addresses are included in the coreboot table
+ * with the appropriate tags.
+ */
+ const struct section_id {
+ int cbmem_id;
+ int table_tag;
+ } section_ids[] = {
+ {CBMEM_ID_TIMESTAMP, LB_TAG_TIMESTAMPS},
+ {CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE}
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(section_ids); i++) {
+ const struct section_id *sid = section_ids + i;
+ struct lb_cbmem_ref *cbmem_ref;
+ void *cbmem_addr = cbmem_find(sid->cbmem_id);
+
+ if (!cbmem_addr)
+ continue; /* This section is not present */
+
+ cbmem_ref = (struct lb_cbmem_ref *)lb_new_record(header);
+ if (!cbmem_ref) {
+ printk(BIOS_ERR, "No more room in coreboot table!\n");
+ break;
+ }
+ cbmem_ref->tag = sid->table_tag;
+ cbmem_ref->size = sizeof(*cbmem_ref);
+ cbmem_ref->cbmem_addr = (unsigned long)cbmem_addr;
+ }
+}
+
+static struct lb_mainboard *lb_mainboard(struct lb_header *header)
+{
+ struct lb_record *rec;
+ struct lb_mainboard *mainboard;
+ rec = lb_new_record(header);
+ mainboard = (struct lb_mainboard *)rec;
+ mainboard->tag = LB_TAG_MAINBOARD;
+
+ mainboard->size = (sizeof(*mainboard) +
+ strlen(mainboard_vendor) + 1 +
+ strlen(mainboard_part_number) + 1 +
+ 3) & ~3;
+
+ mainboard->vendor_idx = 0;
+ mainboard->part_number_idx = strlen(mainboard_vendor) + 1;
+
+ memcpy(mainboard->strings + mainboard->vendor_idx,
+ mainboard_vendor, strlen(mainboard_vendor) + 1);
+ memcpy(mainboard->strings + mainboard->part_number_idx,
+ mainboard_part_number, strlen(mainboard_part_number) + 1);
+
+ return mainboard;
+}
+
+#if CONFIG_USE_OPTION_TABLE
+static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header)
+{
+ struct lb_record *rec;
+ struct cmos_checksum *cmos_checksum;
+ rec = lb_new_record(header);
+ cmos_checksum = (struct cmos_checksum *)rec;
+ cmos_checksum->tag = LB_TAG_OPTION_CHECKSUM;
+
+ cmos_checksum->size = (sizeof(*cmos_checksum));
+
+ cmos_checksum->range_start = LB_CKS_RANGE_START * 8;
+ cmos_checksum->range_end = ( LB_CKS_RANGE_END * 8 ) + 7;
+ cmos_checksum->location = LB_CKS_LOC * 8;
+ cmos_checksum->type = CHECKSUM_PCBIOS;
+
+ return cmos_checksum;
+}
+#endif
+
+static void lb_strings(struct lb_header *header)
+{
+ static const struct {
+ uint32_t tag;
+ const char *string;
+ } strings[] = {
+ { LB_TAG_VERSION, coreboot_version, },
+ { LB_TAG_EXTRA_VERSION, coreboot_extra_version, },
+ { LB_TAG_BUILD, coreboot_build, },
+ { LB_TAG_COMPILE_TIME, coreboot_compile_time, },
+ { LB_TAG_COMPILE_BY, coreboot_compile_by, },
+ { LB_TAG_COMPILE_HOST, coreboot_compile_host, },
+ { LB_TAG_COMPILE_DOMAIN, coreboot_compile_domain, },
+ { LB_TAG_COMPILER, coreboot_compiler, },
+ { LB_TAG_LINKER, coreboot_linker, },
+ { LB_TAG_ASSEMBLER, coreboot_assembler, },
+ };
+ unsigned int i;
+ for(i = 0; i < ARRAY_SIZE(strings); i++) {
+ struct lb_string *rec;
+ size_t len;
+ rec = (struct lb_string *)lb_new_record(header);
+ len = strlen(strings[i].string);
+ rec->tag = strings[i].tag;
+ rec->size = (sizeof(*rec) + len + 1 + 3) & ~3;
+ memcpy(rec->string, strings[i].string, len+1);
+ }
+
+}
+
+static struct lb_forward *lb_forward(struct lb_header *header, struct lb_header *next_header)
+{
+ struct lb_record *rec;
+ struct lb_forward *forward;
+ rec = lb_new_record(header);
+ forward = (struct lb_forward *)rec;
+ forward->tag = LB_TAG_FORWARD;
+ forward->size = sizeof(*forward);
+ forward->forward = (uint64_t)(unsigned long)next_header;
+ return forward;
+}
+
+static void lb_memory_range(struct lb_memory *mem,
+ uint32_t type, uint64_t start, uint64_t size)
+{
+ int entries;
+ entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+ mem->map[entries].start = pack_lb64(start);
+ mem->map[entries].size = pack_lb64(size);
+ mem->map[entries].type = type;
+ mem->size += sizeof(mem->map[0]);
+}
+
+static void lb_reserve_table_memory(struct lb_header *head)
+{
+/* Dynamic cbmem has already reserved the memory where the coreboot tables
+ * reside. Therefore, there is nothing to fix up. */
+#if !CONFIG_DYNAMIC_CBMEM
+ struct lb_record *last_rec;
+ struct lb_memory *mem;
+ uint64_t start;
+ uint64_t end;
+ int i, entries;
+
+ last_rec = lb_last_record(head);
+ mem = get_lb_mem();
+ start = (unsigned long)head;
+ end = (unsigned long)last_rec;
+ entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+ /* Resize the right two memory areas so this table is in
+ * a reserved area of memory. Everything has been carefully
+ * setup so that is all we need to do.
+ */
+ for(i = 0; i < entries; i++ ) {
+ uint64_t map_start = unpack_lb64(mem->map[i].start);
+ uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
+ /* Does this area need to be expanded? */
+ if (map_end == start) {
+ mem->map[i].size = pack_lb64(end - map_start);
+ }
+ /* Does this area need to be contracted? */
+ else if (map_start == start) {
+ mem->map[i].start = pack_lb64(end);
+ mem->map[i].size = pack_lb64(map_end - end);
+ }
+ }
+#endif
+}
+
+static unsigned long lb_table_fini(struct lb_header *head, int fixup)
+{
+ struct lb_record *rec, *first_rec;
+ rec = lb_last_record(head);
+ if (head->table_entries) {
+ head->table_bytes += rec->size;
+ }
+
+ if (fixup)
+ lb_reserve_table_memory(head);
+
+ first_rec = lb_first_record(head);
+ head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes);
+ head->header_checksum = 0;
+ head->header_checksum = compute_ip_checksum(head, sizeof(*head));
+ printk(BIOS_DEBUG,
+ "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
+ head, head->table_bytes, head->table_checksum);
+ return (unsigned long)rec + rec->size;
+}
+
+static void lb_cleanup_memory_ranges(struct lb_memory *mem)
+{
+ int entries;
+ int i, j;
+ entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+
+ /* Sort the lb memory ranges */
+ for(i = 0; i < entries; i++) {
+ uint64_t entry_start = unpack_lb64(mem->map[i].start);
+ for(j = i + 1; j < entries; j++) {
+ uint64_t temp_start = unpack_lb64(mem->map[j].start);
+ if (temp_start < entry_start) {
+ struct lb_memory_range tmp;
+ tmp = mem->map[i];
+ mem->map[i] = mem->map[j];
+ mem->map[j] = tmp;
+ }
+ }
+ }
+
+ /* Merge adjacent entries */
+ for(i = 0; (i + 1) < entries; i++) {
+ uint64_t start, end, nstart, nend;
+ if (mem->map[i].type != mem->map[i + 1].type) {
+ continue;
+ }
+ start = unpack_lb64(mem->map[i].start);
+ end = start + unpack_lb64(mem->map[i].size);
+ nstart = unpack_lb64(mem->map[i + 1].start);
+ nend = nstart + unpack_lb64(mem->map[i + 1].size);
+ if ((start <= nstart) && (end >= nstart)) {
+ if (start > nstart) {
+ start = nstart;
+ }
+ if (end < nend) {
+ end = nend;
+ }
+ /* Record the new region size */
+ mem->map[i].start = pack_lb64(start);
+ mem->map[i].size = pack_lb64(end - start);
+
+ /* Delete the entry I have merged with */
+ memmove(&mem->map[i + 1], &mem->map[i + 2],
+ ((entries - i - 2) * sizeof(mem->map[0])));
+ mem->size -= sizeof(mem->map[0]);
+ entries -= 1;
+ /* See if I can merge with the next entry as well */
+ i -= 1;
+ }
+ }
+}
+
+static void lb_remove_memory_range(struct lb_memory *mem,
+ uint64_t start, uint64_t size)
+{
+ uint64_t end;
+ int entries;
+ int i;
+
+ end = start + size;
+ entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+
+ /* Remove a reserved area from the memory map */
+ for(i = 0; i < entries; i++) {
+ uint64_t map_start = unpack_lb64(mem->map[i].start);
+ uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
+ if ((start <= map_start) && (end >= map_end)) {
+ /* Remove the completely covered range */
+ memmove(&mem->map[i], &mem->map[i + 1],
+ ((entries - i - 1) * sizeof(mem->map[0])));
+ mem->size -= sizeof(mem->map[0]);
+ entries -= 1;
+ /* Since the index will disappear revisit what will appear here */
+ i -= 1;
+ }
+ else if ((start > map_start) && (end < map_end)) {
+ /* Split the memory range */
+ memmove(&mem->map[i + 1], &mem->map[i],
+ ((entries - i) * sizeof(mem->map[0])));
+ mem->size += sizeof(mem->map[0]);
+ entries += 1;
+ /* Update the first map entry */
+ mem->map[i].size = pack_lb64(start - map_start);
+ /* Update the second map entry */
+ mem->map[i + 1].start = pack_lb64(end);
+ mem->map[i + 1].size = pack_lb64(map_end - end);
+ /* Don't bother with this map entry again */
+ i += 1;
+ }
+ else if ((start <= map_start) && (end > map_start)) {
+ /* Shrink the start of the memory range */
+ mem->map[i].start = pack_lb64(end);
+ mem->map[i].size = pack_lb64(map_end - end);
+ }
+ else if ((start < map_end) && (start > map_start)) {
+ /* Shrink the end of the memory range */
+ mem->map[i].size = pack_lb64(start - map_start);
+ }
+ }
+}
+
+void lb_add_memory_range(struct lb_memory *mem,
+ uint32_t type, uint64_t start, uint64_t size)
+{
+ lb_remove_memory_range(mem, start, size);
+ lb_memory_range(mem, type, start, size);
+ lb_cleanup_memory_ranges(mem);
+}
+
+static void lb_dump_memory_ranges(struct lb_memory *mem)
+{
+ int entries;
+ int i;
+ entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+
+ printk(BIOS_DEBUG, "coreboot memory table:\n");
+ for(i = 0; i < entries; i++) {
+ uint64_t entry_start = unpack_lb64(mem->map[i].start);
+ uint64_t entry_size = unpack_lb64(mem->map[i].size);
+ const char *entry_type;
+
+ switch (mem->map[i].type) {
+ case LB_MEM_RAM: entry_type="RAM"; break;
+ case LB_MEM_RESERVED: entry_type="RESERVED"; break;
+ case LB_MEM_ACPI: entry_type="ACPI"; break;
+ case LB_MEM_NVS: entry_type="NVS"; break;
+ case LB_MEM_UNUSABLE: entry_type="UNUSABLE"; break;
+ case LB_MEM_VENDOR_RSVD: entry_type="VENDOR RESERVED"; break;
+ case LB_MEM_TABLE: entry_type="CONFIGURATION TABLES"; break;
+ default: entry_type="UNKNOWN!"; break;
+ }
+
+ printk(BIOS_DEBUG, "%2d. %016llx-%016llx: %s\n",
+ i, entry_start, entry_start+entry_size-1, entry_type);
+
+ }
+}
+
+/* Routines to extract part so the coreboot table or
+ * information from the coreboot table after we have written it.
+ * Currently get_lb_mem relies on a global we can change the
+ * implementaiton.
+ */
+static struct lb_memory *mem_ranges = 0;
+struct lb_memory *get_lb_mem(void)
+{
+ return mem_ranges;
+}
+
+static void build_lb_mem_range(void *gp, struct device *dev, struct resource *res)
+{
+ struct lb_memory *mem = gp;
+ lb_memory_range(mem, LB_MEM_RAM, res->base, res->size);
+}
+
+static struct lb_memory *build_lb_mem(struct lb_header *head)
+{
+ struct lb_memory *mem;
+
+ /* Record where the lb memory ranges will live */
+ mem = lb_memory(head);
+ mem_ranges = mem;
+
+ /* Build the raw table of memory */
+ search_global_resources(
+ IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
+ build_lb_mem_range, mem);
+ lb_cleanup_memory_ranges(mem);
+ return mem;
+}
+
+static void lb_add_rsvd_range(void *gp, struct device *dev, struct resource *res)
+{
+ struct lb_memory *mem = gp;
+ lb_add_memory_range(mem, LB_MEM_RESERVED, res->base, res->size);
+}
+
+static void add_lb_reserved(struct lb_memory *mem)
+{
+ /* Add reserved ranges */
+ search_global_resources(
+ IORESOURCE_MEM | IORESOURCE_RESERVE, IORESOURCE_MEM | IORESOURCE_RESERVE,
+ lb_add_rsvd_range, mem);
+}
+
+unsigned long write_coreboot_table(
+ unsigned long low_table_start, unsigned long low_table_end,
+ unsigned long rom_table_start, unsigned long rom_table_end)
+{
+ struct lb_header *head;
+ struct lb_memory *mem;
+
+ if (low_table_start || low_table_end) {
+ printk(BIOS_DEBUG, "Writing table forward entry at 0x%08lx\n",
+ low_table_end);
+ head = lb_table_init(low_table_end);
+ lb_forward(head, (struct lb_header*)rom_table_end);
+
+ low_table_end = (unsigned long) lb_table_fini(head, 0);
+ printk(BIOS_DEBUG, "Table forward entry ends at 0x%08lx.\n",
+ low_table_end);
+ }
+
+ printk(BIOS_DEBUG, "Writing coreboot table at 0x%08lx\n",
+ rom_table_end);
+
+ head = lb_table_init(rom_table_end);
+ rom_table_end = (unsigned long)head;
+ printk(BIOS_DEBUG, "rom_table_end = 0x%08lx\n", rom_table_end);
+
+ if (low_table_start || low_table_end) {
+ printk(BIOS_DEBUG, "Adjust low_table_end from 0x%08lx to ",
+ low_table_end);
+ low_table_end += 0xfff; // 4K aligned
+ low_table_end &= ~0xfff;
+ printk(BIOS_DEBUG, "0x%08lx \n", low_table_end);
+ }
+
+ /* The Linux kernel assumes this region is reserved */
+ printk(BIOS_DEBUG, "Adjust rom_table_end from 0x%08lx to ", rom_table_end);
+ rom_table_end += 0xffff; // 64K align
+ rom_table_end &= ~0xffff;
+ printk(BIOS_DEBUG, "0x%08lx \n", rom_table_end);
+
+#if CONFIG_USE_OPTION_TABLE
+ {
+ struct cmos_option_table *option_table = cbfs_get_file_content(
+ CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT);
+ if (option_table) {
+ struct lb_record *rec_dest = lb_new_record(head);
+ /* Copy the option config table, it's already a lb_record... */
+ memcpy(rec_dest, option_table, option_table->size);
+ /* Create cmos checksum entry in coreboot table */
+ lb_cmos_checksum(head);
+ } else {
+ printk(BIOS_ERR, "cmos_layout.bin could not be found!\n");
+ }
+ }
+#endif
+ /* Record where RAM is located */
+ mem = build_lb_mem(head);
+
+ if (low_table_start || low_table_end) {
+ /* Record the mptable and the the lb_table.
+ * (This will be adjusted later) */
+ lb_add_memory_range(mem, LB_MEM_TABLE,
+ low_table_start, low_table_end - low_table_start);
+ }
+
+ /* Record the pirq table, acpi tables, and maybe the mptable. However,
+ * these only need to be added when the rom_table is sitting below
+ * 1MiB. If it isn't that means high tables are being written.
+ * The code below handles high tables correctly. */
+ if (rom_table_end <= (1 << 20))
+ lb_add_memory_range(mem, LB_MEM_TABLE,
+ rom_table_start, rom_table_end - rom_table_start);
+
+#if CONFIG_DYNAMIC_CBMEM
+ cbmem_add_lb_mem(mem);
+#else /* CONFIG_DYNAMIC_CBMEM */
+ lb_add_memory_range(mem, LB_MEM_TABLE,
+ high_tables_base, high_tables_size);
+#endif /* CONFIG_DYNAMIC_CBMEM */
+
+ /* Add reserved regions */
+ add_lb_reserved(mem);
+
+ lb_dump_memory_ranges(mem);
+
+ /* Note:
+ * I assume that there is always memory at immediately after
+ * the low_table_end. This means that after I setup the coreboot table.
+ * I can trivially fixup the reserved memory ranges to hold the correct
+ * size of the coreboot table.
+ */
+
+ /* Record our motherboard */
+ lb_mainboard(head);
+ /* Record the serial port, if present */
+ lb_serial(head);
+ /* Record our console setup */
+ lb_console(head);
+ /* Record our various random string information */
+ lb_strings(head);
+ /* Record our framebuffer */
+ lb_framebuffer(head);
+
+#if CONFIG_CHROMEOS
+ /* Record our GPIO settings (ChromeOS specific) */
+ lb_gpios(head);
+
+ /* pass along the VDAT buffer adress */
+ lb_vdat(head);
+
+ /* pass along VBNV offsets in CMOS */
+ lb_vbnv(head);
+
+ /* pass along the vboot_handoff address. */
+ lb_vboot_handoff(head);
+#endif
+ add_cbmem_pointers(head);
+
+ /* Remember where my valid memory ranges are */
+ return lb_table_fini(head, 1);
+
+}
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 06ed7d3..e99e2c8 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -32,6 +32,7 @@ menu "ChromeOS"
config VBNV_OFFSET
hex
default 0x26
+ depends on PC80_SYSTEM
help
CMOS offset for VbNv data. This value must match cmos.layout
in the mainboard directory, minus 14 bytes for the RTC.
@@ -39,6 +40,7 @@ config VBNV_OFFSET
config VBNV_SIZE
hex
default 0x10
+ depends on PC80_SYSTEM
help
CMOS storage size for VbNv data. This value must match cmos.layout
in the mainboard directory.
1
0
Patch set updated for coreboot: 721565e wtm2: build-time dev and recovery settings
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2861
-gerrit
commit 721565e38049dc1e03fe2ef0205287c7b52cadad
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 19 15:25:46 2013 -0500
wtm2: build-time dev and recovery settings
It's helpful to switch back and forth for developer and
recovery settings while testing boards. The wtm2 board
currently doesn't have gpios which dynamically seelect that.
Might as well make it easy to change the value for each
setting with one define. The original defaults are kept.
Change-Id: I7b928c592fd20a1b847e4733f4cdef09d6ddad4c
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/mainboard/intel/wtm2/chromeos.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/mainboard/intel/wtm2/chromeos.c b/src/mainboard/intel/wtm2/chromeos.c
index c2386a8..7ef7458 100644
--- a/src/mainboard/intel/wtm2/chromeos.c
+++ b/src/mainboard/intel/wtm2/chromeos.c
@@ -28,6 +28,10 @@
#endif
#include <southbridge/intel/lynxpoint/pch.h>
+/* Compile-time settings for developer and recovery mode. */
+#define DEV_MODE_SETTING 1
+#define REC_MODE_SETTING 0
+
#ifndef __PRE_RAM__
#include <boot/coreboot_tables.h>
#include <arch/coreboot_tables.h>
@@ -58,8 +62,8 @@ void fill_lb_gpios(struct lb_gpios *gpios)
gpio = gpios->gpios;
fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "write protect", 0);
- fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "recovery", 0); // force off
- fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "developer", 1); // force on
+ fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "recovery", REC_MODE_SETTING);
+ fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "developer", DEV_MODE_SETTING);
fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "lid", 1); // force open
fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "power", 0);
fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "oprom", oprom_is_loaded);
@@ -68,12 +72,12 @@ void fill_lb_gpios(struct lb_gpios *gpios)
int get_developer_mode_switch(void)
{
- return 1; // force on
+ return DEV_MODE_SETTING;
}
int get_recovery_mode_switch(void)
{
- return 0; // force off
+ return REC_MODE_SETTING;
}
int get_write_protect_state(void)
1
0
Patch set updated for coreboot: 846157b vboot: pass correct coreboot include paths
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2860
-gerrit
commit 846157bdc95fa0ccb44fd896430c5f3c57a73ce8
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 19 12:43:18 2013 -0500
vboot: pass correct coreboot include paths
The coreboot include were not being passed correctly when
building vboot_reference. The paths being included were of the
src/<dir> form. However, vboot_reference lives in
src/../vboot_reference. That coupled with the recursive make
call made vboot_reference not see coreboot's header files.
Fix this by appending ../ to coreboot's default include paths.
Change-Id: I73949c6f854ecfce77ac36bb995918d51f91445e
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/vendorcode/google/chromeos/Makefile.inc | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index 9bc4d64..abcd429 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -53,9 +53,11 @@ VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules.o
VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules.o
VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules.o
VBOOT_STUB_DEPS += $(VB_LIB)
-# Remove the '-include' option since that will break vboot's build.
-VBOOT_CFLAGS += $(filter-out -include $(src)/include/kconfig.h, $(CFLAGS))
+# Remove the '-include' option since that will break vboot's build and ensure
+# vboot_reference can get to coreboot's include files.
+VBOOT_CFLAGS += $(patsubst -I%,-I../%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS)))
VBOOT_CFLAGS += -DVBOOT_DEBUG
+$(warning $(VBOOT_CFLAGS))
$(VBOOT_STUB_DOTO): $(VBOOT_STUB_DEPS)
$(CC) $(LDFLAGS) -nostdlib -r -o $@ $^
1
0
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2851
-gerrit
commit 287702f74e61714e4caf25c7278f745adb9d1a4d
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Mar 13 12:48:33 2013 -0500
cbmem: add vboot cmbem id
The vboot firmware selection from romstage will need to
pass the resulting vboot data to other consumers. This will
be done using a cbmem entry.
Change-Id: I497caba53f9f3944513382f3929d21b04bf3ba9e
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/cbmem.h | 1 +
src/lib/cbmem_info.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index b3d9f86..5b19207 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -67,6 +67,7 @@
#define CBMEM_ID_RAMSTAGE 0x9a357a9e
#define CBMEM_ID_RAMSTAGE_CACHE 0x9a3ca54e
#define CBMEM_ID_ROOT 0xff4007ff
+#define CBMEM_ID_VBOOT_HANDOFF 0x780074f0
#define CBMEM_ID_NONE 0x00000000
#ifndef __ASSEMBLER__
diff --git a/src/lib/cbmem_info.c b/src/lib/cbmem_info.c
index aaf5840..5b02f2d 100644
--- a/src/lib/cbmem_info.c
+++ b/src/lib/cbmem_info.c
@@ -44,6 +44,7 @@ static struct cbmem_id_to_name {
{ CBMEM_ID_RAMSTAGE, "RAMSTAGE " },
{ CBMEM_ID_RAMSTAGE_CACHE, "RAMSTAGE $ " },
{ CBMEM_ID_ROOT, "CBMEM ROOT " },
+ { CBMEM_ID_VBOOT_HANDOFF, "VBOOT " },
};
void cbmem_print_entry(int n, u32 id, u64 base, u64 size)
1
0
Patch set updated for coreboot: 523fdef haswell: use dynamic cbmem
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2850
-gerrit
commit 523fdef6715d16c152cb5cecacce22813972757f
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Mar 13 13:51:20 2013 -0500
haswell: use dynamic cbmem
Convert the existing haswell code to support reloctable ramstage
to use dynamic cbmem. This patch always selects DYNAMIC_CBMEM as
this option is a hard requirement for relocatable ramstage.
Aside from converting a few new API calls, a cbmem_top()
implementation is added which is defined to be at the begining of the
TSEG region. Also, use the dynamic cbmem library for allocating a
stack in ram for romstage after CAR is torn down.
Utilizing dynamic cbmem does mean that the cmem field in the gnvs
chromeos acpi table is now 0. Also, the memconsole driver in the kernel
won't be able to find the memconsole because the cbmem structure
changed.
Change-Id: I7cf98d15b97ad82abacfb36ec37b004ce4605c38
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/intel/haswell/Kconfig | 1 +
src/cpu/intel/haswell/romstage.c | 49 ++++++++++++--------------
src/mainboard/intel/baskingridge/acpi_tables.c | 2 +-
src/mainboard/intel/wtm1/acpi_tables.c | 2 +-
src/mainboard/intel/wtm2/acpi_tables.c | 2 +-
src/northbridge/intel/haswell/northbridge.c | 10 ++++++
src/northbridge/intel/haswell/raminit.c | 5 +--
7 files changed, 39 insertions(+), 32 deletions(-)
diff --git a/src/cpu/intel/haswell/Kconfig b/src/cpu/intel/haswell/Kconfig
index d1f521d..5f27d4c 100644
--- a/src/cpu/intel/haswell/Kconfig
+++ b/src/cpu/intel/haswell/Kconfig
@@ -12,6 +12,7 @@ config CPU_SPECIFIC_OPTIONS
select SMM_TSEG
select SMM_MODULES
select RELOCATABLE_MODULES
+ select DYNAMIC_CBMEM
select CPU_MICROCODE_IN_CBFS
#select AP_IN_SIPI_WAIT
select TSC_SYNC_MFENCE
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c
index 4ece6c2..1d58191 100644
--- a/src/cpu/intel/haswell/romstage.c
+++ b/src/cpu/intel/haswell/romstage.c
@@ -33,7 +33,6 @@
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <cpu/x86/lapic.h>
-#include <cbmem.h>
#include <cbfs.h>
#include <romstage_handoff.h>
#include <reset.h>
@@ -71,13 +70,17 @@ static inline u32 *stack_push(u32 *stack, u32 value)
return stack;
}
+/* Romstage needs quite a bit of stack for decompressing images since the lzma
+ * lib keeps its state on the stack during romstage. */
+#define ROMSTAGE_RAM_STACK_SIZE 0x5000
static unsigned long choose_top_of_stack(void)
{
unsigned long stack_top;
-#if CONFIG_RELOCATABLE_RAMSTAGE
- stack_top = (unsigned long)cbmem_add(CBMEM_ID_RESUME_SCRATCH,
- CONFIG_HIGH_SCRATCH_MEMORY_SIZE);
- stack_top += CONFIG_HIGH_SCRATCH_MEMORY_SIZE;
+#if CONFIG_DYNAMIC_CBMEM
+ /* cbmem_add() does a find() before add(). */
+ stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK,
+ ROMSTAGE_RAM_STACK_SIZE);
+ stack_top += ROMSTAGE_RAM_STACK_SIZE;
#else
stack_top = ROMSTAGE_STACK;
#endif
@@ -198,7 +201,6 @@ void romstage_common(const struct romstage_params *params)
{
int boot_mode;
int wake_from_s3;
- int cbmem_was_initted;
struct romstage_handoff *handoff;
#if CONFIG_COLLECT_TIMESTAMPS
@@ -266,23 +268,16 @@ void romstage_common(const struct romstage_params *params)
quick_ram_check();
post_code(0x3e);
-#if CONFIG_EARLY_CBMEM_INIT
- cbmem_was_initted = !cbmem_initialize();
-#else
- cbmem_was_initted = cbmem_reinit((uint64_t) (get_top_of_ram()
- - HIGH_MEMORY_SIZE));
-#endif
-
- /* Save data returned from MRC on non-S3 resumes. */
- if (!wake_from_s3)
+ if (!wake_from_s3) {
+ cbmem_initialize_empty();
+ /* Save data returned from MRC on non-S3 resumes. */
save_mrc_data(params->pei_data);
-
-#if CONFIG_HAVE_ACPI_RESUME
- if (wake_from_s3 && !cbmem_was_initted) {
+ } else if (cbmem_initialize()) {
+ #if CONFIG_HAVE_ACPI_RESUME
/* Failed S3 resume, reset to come up cleanly */
reset_system();
+ #endif
}
-#endif
handoff = romstage_handoff_find_or_add();
if (handoff != NULL)
@@ -331,11 +326,16 @@ void romstage_after_car(void)
#if CONFIG_RELOCATABLE_RAMSTAGE
void cache_loaded_ramstage(struct romstage_handoff *handoff,
- void *ramstage_base, uint32_t ramstage_size,
+ const struct cbmem_entry *ramstage,
void *entry_point)
{
struct ramstage_cache *cache;
uint32_t total_size;
+ uint32_t ramstage_size;
+ void *ramstage_base;
+
+ ramstage_size = cbmem_entry_size(ramstage);
+ ramstage_base = cbmem_entry_start(ramstage);
/* The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET.
* The top of ram is defined to be the TSEG base address. */
@@ -359,19 +359,14 @@ void cache_loaded_ramstage(struct romstage_handoff *handoff,
/* Copy over the program. */
memcpy(&cache->program[0], ramstage_base, ramstage_size);
- /* Do not update reserve region if the handoff structure is not
- * available. Perhaps the ramstage will fix things up for the resume
- * path. */
if (handoff == NULL)
return;
- /* Update entry and reserve region. */
- handoff->reserve_base = (uint32_t)ramstage_base;
- handoff->reserve_size = ramstage_size;
handoff->ramstage_entry_point = (uint32_t)entry_point;
}
-void *load_cached_ramstage(struct romstage_handoff *handoff)
+void *load_cached_ramstage(struct romstage_handoff *handoff,
+ const struct cbmem_entry *ramstage)
{
struct ramstage_cache *cache;
diff --git a/src/mainboard/intel/baskingridge/acpi_tables.c b/src/mainboard/intel/baskingridge/acpi_tables.c
index 823abcf..5131ec1 100644
--- a/src/mainboard/intel/baskingridge/acpi_tables.c
+++ b/src/mainboard/intel/baskingridge/acpi_tables.c
@@ -87,7 +87,7 @@ static void acpi_create_gnvs(global_nvs_t *gnvs)
gnvs->s5u1 = 1;
/* CBMEM TOC */
- gnvs->cmem = (u32)get_cbmem_toc();
+ gnvs->cmem = 0;
/* IGD Displays */
gnvs->ndid = 3;
diff --git a/src/mainboard/intel/wtm1/acpi_tables.c b/src/mainboard/intel/wtm1/acpi_tables.c
index 18c9bb2..4232afc 100644
--- a/src/mainboard/intel/wtm1/acpi_tables.c
+++ b/src/mainboard/intel/wtm1/acpi_tables.c
@@ -84,7 +84,7 @@ static void acpi_create_gnvs(global_nvs_t *gnvs)
gnvs->s5u1 = 0;
/* CBMEM TOC */
- gnvs->cmem = (u32)get_cbmem_toc();
+ gnvs->cmem = 0;
/* IGD Displays */
gnvs->ndid = 3;
diff --git a/src/mainboard/intel/wtm2/acpi_tables.c b/src/mainboard/intel/wtm2/acpi_tables.c
index 18c9bb2..4232afc 100644
--- a/src/mainboard/intel/wtm2/acpi_tables.c
+++ b/src/mainboard/intel/wtm2/acpi_tables.c
@@ -84,7 +84,7 @@ static void acpi_create_gnvs(global_nvs_t *gnvs)
gnvs->s5u1 = 0;
/* CBMEM TOC */
- gnvs->cmem = (u32)get_cbmem_toc();
+ gnvs->cmem = 0;
/* IGD Displays */
gnvs->ndid = 3;
diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c
index 53c2f36..b57b28e 100644
--- a/src/northbridge/intel/haswell/northbridge.c
+++ b/src/northbridge/intel/haswell/northbridge.c
@@ -543,6 +543,16 @@ static void northbridge_init(struct device *dev)
MCHBAR32(0x5500) = 0x00100001;
}
+void *cbmem_top(void)
+{
+ u32 reg;
+
+ /* The top the reserve regions fall just below the TSEG region. */
+ reg = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0, 0)), TSEG);
+
+ return (void *)(reg & ~((1 << 20) - 1));
+}
+
static void northbridge_enable(device_t dev)
{
#if CONFIG_HAVE_ACPI_RESUME
diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c
index 1439200..ee21823 100644
--- a/src/northbridge/intel/haswell/raminit.c
+++ b/src/northbridge/intel/haswell/raminit.c
@@ -203,9 +203,10 @@ void sdram_initialize(struct pei_data *pei_data)
report_memory_config();
}
-struct cbmem_entry *get_cbmem_toc(void)
+void *cbmem_top(void)
{
- return (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE);
+ /* Top of cbmem is at lowest usable DRAM address below 4GiB. */
+ return (void *)get_top_of_ram();
}
unsigned long get_top_of_ram(void)
1
0
Patch set updated for coreboot: 0d3e0d9 coreboot: dynamic cbmem requirement
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2849
-gerrit
commit 0d3e0d9d54fb87f3dfafd22f32886a1d44a9a517
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Feb 27 22:50:12 2013 -0600
coreboot: dynamic cbmem requirement
Dynamic cbmem is now a requirement for relocatable ramstage.
This patch replaces the reserve_* fields in the romstage_handoff
structure by using the dynamic cbmem library.
The haswell code is not moved over in this commit, but it should be
safe because there is a hard requirement for DYNAMIC_CBMEM when using
a reloctable ramstage.
Change-Id: I59ab4552c3ae8c2c3982df458cd81a4a9b712cc2
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/Kconfig | 9 +--
src/arch/x86/boot/coreboot_table.c | 20 -------
src/include/cbfs.h | 21 ++++---
src/include/cbmem.h | 5 --
src/include/rmodule.h | 16 ++---
src/include/romstage_handoff.h | 3 -
src/lib/cbfs.c | 91 ++++++++++++++++-------------
src/lib/hardwaremain.c | 9 ---
src/lib/rmodule.c | 38 ++++++------
src/northbridge/intel/haswell/northbridge.c | 15 -----
10 files changed, 94 insertions(+), 133 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index 0297970..18b5bad 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -315,14 +315,7 @@ config HAVE_INIT_TIMER
config HIGH_SCRATCH_MEMORY_SIZE
hex
- default 0x5000 if RELOCATABLE_RAMSTAGE
default 0x0
- help
- The amount of extra memory to reserve from the OS. If
- RELOCATABLE_RAMSTAGE is enabled a size of 20KiB is reserved. This is
- for the use of a stack in romstage after memory has been initialized.
- The stack size required in romstage can be large when needing to
- decompress the ramstage.
config USE_OPTION_TABLE
bool
@@ -390,7 +383,7 @@ config RELOCATABLE_MODULES
loaded anywhere and all the relocations are handled automatically.
config RELOCATABLE_RAMSTAGE
- depends on RELOCATABLE_MODULES
+ depends on (RELOCATABLE_MODULES && DYNAMIC_CBMEM)
bool "Build the ramstage to be relocatable in 32-bit address space."
default n
help
diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c
index 617fab2..530849f 100644
--- a/src/arch/x86/boot/coreboot_table.c
+++ b/src/arch/x86/boot/coreboot_table.c
@@ -31,7 +31,6 @@
#include <stdlib.h>
#include <cbfs.h>
#include <cbmem.h>
-#include <romstage_handoff.h>
#if CONFIG_USE_OPTION_TABLE
#include <option_table.h>
#endif
@@ -596,23 +595,6 @@ static void add_lb_reserved(struct lb_memory *mem)
lb_add_rsvd_range, mem);
}
-static void add_romstage_resources(struct lb_memory *mem)
-{
- struct romstage_handoff *handoff;
-
- /* Reserve memory requested to be reserved from romstage. */
- handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO);
-
- if (handoff == NULL)
- return;
-
- if (handoff->reserve_size == 0)
- return;
-
- lb_add_memory_range(mem, LB_MEM_RESERVED, handoff->reserve_base,
- handoff->reserve_size);
-}
-
unsigned long write_coreboot_table(
unsigned long low_table_start, unsigned long low_table_end,
unsigned long rom_table_start, unsigned long rom_table_end)
@@ -686,8 +668,6 @@ unsigned long write_coreboot_table(
/* Add reserved regions */
add_lb_reserved(mem);
- add_romstage_resources(mem);
-
lb_dump_memory_ranges(mem);
/* Note:
diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index 811df88..ac249aa 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -87,21 +87,24 @@ int init_default_cbfs_media(struct cbfs_media *media);
/* The cache_loaded_ramstage() and load_cached_ramstage() functions are defined
* to be weak so that board and chipset code may override them. Their job is to
* cache and load the ramstage for quick S3 resume. By default a copy of the
- * relocated ramstage is saved just below the running ramstage region. These
+ * relocated ramstage is saved using the cbmem infrastructure. These
* functions are only valid during romstage. */
struct romstage_handoff;
+struct cbmem_entry;
-/* The implementer of cache_loaded_ramstage() needs to ensure that the
- * reserve_* fields in in romstage_handoff reflect the memory footprint of the
- * ramstage (including cached region). Note that the handoff variable can be
- * NULL. */
+/* The implementer of cache_loaded_ramstage() may use the romstage_handoff
+ * structure to store information, but note that the handoff variable can be
+ * NULL. The ramstage cbmem_entry represents the region occupied by the loaded
+ * ramstage. */
void __attribute__((weak))
-cache_loaded_ramstage(struct romstage_handoff *handoff, void *ramstage_base,
- uint32_t ramstage_size, void *entry_point);
-/* Return NULL on error or entry point on success. */
+cache_loaded_ramstage(struct romstage_handoff *handoff,
+ const struct cbmem_entry *ramstage, void *entry_point);
+/* Return NULL on error or entry point on success. The ramstage cbmem_entry is
+ * the region where to load the cached contents to. */
void * __attribute__((weak))
-load_cached_ramstage(struct romstage_handoff *handoff);
+load_cached_ramstage(struct romstage_handoff *handoff,
+ const struct cbmem_entry *ramstage);
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
#endif
diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index 41f5971..b3d9f86 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -131,11 +131,6 @@ void cbmem_add_lb_mem(struct lb_memory *mem);
#ifndef __PRE_RAM__
extern uint64_t high_tables_base, high_tables_size;
-#if CONFIG_EARLY_CBMEM_INIT
-/* Return 0 on success, < 0 on error. */
-int __attribute__((weak)) cbmem_get_table_location(uint64_t *tables_base,
- uint64_t *tables_size);
-#endif
void set_cbmem_toc(struct cbmem_entry *);
#endif
diff --git a/src/include/rmodule.h b/src/include/rmodule.h
index e8e7636..f46a59d 100644
--- a/src/include/rmodule.h
+++ b/src/include/rmodule.h
@@ -42,13 +42,15 @@ int rmodule_memory_size(const struct rmodule *m);
int rmodule_load(void *loc, struct rmodule *m);
int rmodule_load_no_clear_bss(void *base, struct rmodule *m);
int rmodule_load_alignment(const struct rmodule *m);
-/* Returns the an aligned pointer that reflects a region used below addr
- * based on the rmodule_size. i.e. the returned pointer up to addr is memory
- * that may be utilized by the rmodule. program_start and rmodule_start
- * are pointers updated to reflect where the rmodule program starts and where
- * the rmodule (including header) should be placed respectively. */
-void *rmodule_find_region_below(void *addr, size_t rmodule_size,
- void **program_start, void **rmodule_start);
+/* rmodule_calc_region() calculates the region size, offset to place an
+ * rmodule in memory, and load address offset based off of a region allocator
+ * with an alignment of region_alignment. This function helps place an rmodule
+ * in the same location in ram it will run from. The offset to place the
+ * rmodule into the region allocated of size region_size is returned. The
+ * load_offset is the address to load and relocate the rmodule.
+ * region_alignment must be a power of 2. */
+int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size,
+ size_t *region_size, int *load_offset);
#define FIELD_ENTRY(x_) ((u32)&x_)
#define RMODULE_HEADER(entry_, type_) \
diff --git a/src/include/romstage_handoff.h b/src/include/romstage_handoff.h
index 4150e8e..3152fb2 100644
--- a/src/include/romstage_handoff.h
+++ b/src/include/romstage_handoff.h
@@ -28,9 +28,6 @@
* using the CBMEM_ID_ROMSTAGE_INFO id it needs to ensure it doesn't clobber
* fields it doesn't own. */
struct romstage_handoff {
- /* This indicates to the ramstage to reserve a chunk of memory. */
- uint32_t reserve_base;
- uint32_t reserve_size;
/* Inidicate if the current boot is an S3 resume. If
* CONFIG_RELOCTABLE_RAMSTAGE is enabled the chipset code is
* responsible for initializing this variable. Otherwise, ramstage
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 8bcb000..48ee86a 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -120,41 +120,48 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
#include <rmodule.h>
#include <romstage_handoff.h>
/* When CONFIG_RELOCATABLE_RAMSTAGE is enabled and this file is being compiled
- * for the romstage, the rmodule loader is used. The ramstage is placed just
- * below the cbmem location. */
-
+ * for the romstage, the rmodule loader is used. */
void __attribute__((weak))
-cache_loaded_ramstage(struct romstage_handoff *handoff, void *ramstage_base,
- uint32_t ramstage_size, void *entry_point)
+cache_loaded_ramstage(struct romstage_handoff *handoff,
+ const struct cbmem_entry *ramstage, void *entry_point)
{
+ uint32_t ramstage_size;
+ const struct cbmem_entry *entry;
+
if (handoff == NULL)
return;
- /* Cache the loaded ramstage just below the to-be-run ramstage. Then
- * save the base, size, and entry point in the handoff area. */
- handoff->reserve_base = (uint32_t)ramstage_base - ramstage_size;
- handoff->reserve_size = ramstage_size;
- handoff->ramstage_entry_point = (uint32_t)entry_point;
+ ramstage_size = cbmem_entry_size(ramstage);
+ /* cbmem_entry_add() does a find() before add(). */
+ entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE_CACHE, ramstage_size);
- memcpy((void *)handoff->reserve_base, ramstage_base, ramstage_size);
+ if (entry == NULL)
+ return;
+
+ /* Keep track of the entry point in the handoff structure. */
+ handoff->ramstage_entry_point = (uint32_t)entry_point;
- /* Update the reserve region by 2x in order to store the cached copy. */
- handoff->reserve_size += handoff->reserve_size;
+ memcpy(cbmem_entry_start(entry), cbmem_entry_start(ramstage),
+ ramstage_size);
}
void * __attribute__((weak))
-load_cached_ramstage(struct romstage_handoff *handoff)
+load_cached_ramstage(struct romstage_handoff *handoff,
+ const struct cbmem_entry *ramstage)
{
- uint32_t ramstage_size;
+ const struct cbmem_entry *entry_cache;
if (handoff == NULL)
return NULL;
- /* Load the cached ramstage copy into the to-be-run region. It is just
- * above the cached copy. */
- ramstage_size = handoff->reserve_size / 2;
- memcpy((void *)(handoff->reserve_base + ramstage_size),
- (void *)handoff->reserve_base, ramstage_size);
+ entry_cache = cbmem_entry_find(CBMEM_ID_RAMSTAGE_CACHE);
+
+ if (entry_cache == NULL)
+ return NULL;
+
+ /* Load the cached ramstage copy into the to-be-run region. */
+ memcpy(cbmem_entry_start(ramstage), cbmem_entry_start(entry_cache),
+ cbmem_entry_size(ramstage));
return (void *)handoff->ramstage_entry_point;
}
@@ -164,12 +171,12 @@ static void *load_stage_from_cbfs(struct cbfs_media *media, const char *name,
{
struct cbfs_stage *stage;
struct rmodule ramstage;
- char *cbmem_base;
- char *ramstage_base;
- void *decompression_loc;
- void *ramstage_loc;
void *entry_point;
- uint32_t ramstage_size;
+ size_t region_size;
+ char *ramstage_region;
+ int rmodule_offset;
+ int load_offset;
+ const struct cbmem_entry *ramstage_entry;
stage = (struct cbfs_stage *)
cbfs_get_file_content(media, name, CBFS_TYPE_STAGE);
@@ -177,34 +184,34 @@ static void *load_stage_from_cbfs(struct cbfs_media *media, const char *name,
if (stage == NULL)
return (void *) -1;
- cbmem_base = (void *)get_cbmem_toc();
- if (cbmem_base == NULL)
+ rmodule_offset =
+ rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE,
+ stage->memlen, ®ion_size, &load_offset);
+
+ ramstage_entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE, region_size);
+
+ if (ramstage_entry == NULL)
return (void *) -1;
- ramstage_base =
- rmodule_find_region_below(cbmem_base, stage->memlen,
- &ramstage_loc,
- &decompression_loc);
+ ramstage_region = cbmem_entry_start(ramstage_entry);
LOG("Decompressing stage %s @ 0x%p (%d bytes)\n",
- name, decompression_loc, stage->memlen);
+ name, &ramstage_region[rmodule_offset], stage->memlen);
if (cbfs_decompress(stage->compression, &stage[1],
- decompression_loc, stage->len))
+ &ramstage_region[rmodule_offset], stage->len))
return (void *) -1;
- if (rmodule_parse(decompression_loc, &ramstage))
+ if (rmodule_parse(&ramstage_region[rmodule_offset], &ramstage))
return (void *) -1;
/* The ramstage is responsible for clearing its own bss. */
- if (rmodule_load_no_clear_bss(ramstage_loc, &ramstage))
+ if (rmodule_load_no_clear_bss(&ramstage_region[load_offset], &ramstage))
return (void *) -1;
entry_point = rmodule_entry(&ramstage);
- ramstage_size = cbmem_base - ramstage_base;
- cache_loaded_ramstage(handoff, ramstage_base, ramstage_size,
- entry_point);
+ cache_loaded_ramstage(handoff, ramstage_entry, entry_point);
return entry_point;
}
@@ -212,6 +219,7 @@ static void *load_stage_from_cbfs(struct cbfs_media *media, const char *name,
void * cbfs_load_stage(struct cbfs_media *media, const char *name)
{
struct romstage_handoff *handoff;
+ const struct cbmem_entry *ramstage;
void *entry;
handoff = romstage_handoff_find_or_add();
@@ -222,9 +230,14 @@ void * cbfs_load_stage(struct cbfs_media *media, const char *name)
} else if (!handoff->s3_resume)
return load_stage_from_cbfs(media, name, handoff);
+ ramstage = cbmem_entry_find(CBMEM_ID_RAMSTAGE);
+
+ if (ramstage == NULL)
+ return load_stage_from_cbfs(name, handoff);
+
/* S3 resume path. Load a cached copy of the loaded ramstage. If
* return value is NULL load from cbfs. */
- entry = load_cached_ramstage(handoff);
+ entry = load_cached_ramstage(handoff, ramstage);
if (entry == NULL)
return load_stage_from_cbfs(name, handoff);
diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index bc18989..a3ee10b 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -85,15 +85,6 @@ void hardwaremain(int boot_complete)
/* FIXME: Is there a better way to handle this? */
init_timer();
- /* CONFIG_EARLY_CBMEM_INIT indicates that romstage initialized
- * the cbmem area. Therefore the table location can be initialized
- * early in ramstage if cbmem_get_table_location() is implemented.
- */
-#if CONFIG_EARLY_CBMEM_INIT
- if (cbmem_get_table_location != NULL &&
- !cbmem_get_table_location(&high_tables_base, &high_tables_size))
- cbmem_initialize();
-#endif
init_cbmem_pre_device();
timestamp_stash(TS_DEVICE_ENUMERATE);
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index d36f9f3..3dd90d8 100644
--- a/src/lib/rmodule.c
+++ b/src/lib/rmodule.c
@@ -16,6 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -265,16 +266,22 @@ int rmodule_load_no_clear_bss(void *base, struct rmodule *module)
return __rmodule_load(base, module, 0);
}
-void *rmodule_find_region_below(void *addr, size_t rmodule_size,
- void **program_start, void **rmodule_start)
+int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size,
+ size_t *region_size, int *load_offset)
{
- unsigned long ceiling;
- unsigned long program_base;
- unsigned long placement_loc;
- unsigned long program_begin;
+ /* region_alignment must be a power of 2. */
+ if (region_alignment & (region_alignment - 1))
+ BUG();
- ceiling = (unsigned long)addr;
- /* Place the rmodule just under the ceiling. The rmodule files
+ if (region_alignment < 4096)
+ region_alignment = 4096;
+
+ /* Sanity check rmodule_header size. The code below assumes it is less
+ * than the minimum alignment required. */
+ if (region_alignment < sizeof(struct rmodule_header))
+ BUG();
+
+ /* Place the rmodule according to alignment. The rmodule files
* themselves are packed as a header and a payload, however the rmodule
* itself is linked along with the header. The header starts at address
* 0. Immediately following the header in the file is the program,
@@ -284,13 +291,13 @@ void *rmodule_find_region_below(void *addr, size_t rmodule_size,
* to place the rmodule so that the prgoram falls on the aligned
* address with the header just before it. Therefore, we need at least
* a page to account for the size of the header. */
- program_base = ALIGN((ceiling - (rmodule_size + 4096)), 4096);
+ *region_size = ALIGN(rmodule_size + region_alignment, 4096);
/* The program starts immediately after the header. However,
* it needs to be aligned to a 4KiB boundary. Therefore, adjust the
* program location so that the program lands on a page boundary. The
* layout looks like the following:
*
- * +--------------------------------+ ceiling
+ * +--------------------------------+ region_alignment + region_size
* | >= 0 bytes from alignment |
* +--------------------------------+ program end (4KiB aligned)
* | program size |
@@ -298,14 +305,9 @@ void *rmodule_find_region_below(void *addr, size_t rmodule_size,
* | sizeof(struct rmodule_header) |
* +--------------------------------+ rmodule header start
* | >= 0 bytes from alignment |
- * +--------------------------------+ program_base (4KiB aligned)
+ * +--------------------------------+ region_alignment
*/
- placement_loc = ALIGN(program_base + sizeof(struct rmodule_header),
- 4096) - sizeof(struct rmodule_header);
- program_begin = placement_loc + sizeof(struct rmodule_header);
-
- *program_start = (void *)program_begin;
- *rmodule_start = (void *)placement_loc;
+ *load_offset = region_alignment;
- return (void *)program_base;
+ return region_alignment - sizeof(struct rmodule_header);
}
diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c
index 8708138..53c2f36 100644
--- a/src/northbridge/intel/haswell/northbridge.c
+++ b/src/northbridge/intel/haswell/northbridge.c
@@ -543,21 +543,6 @@ static void northbridge_init(struct device *dev)
MCHBAR32(0x5500) = 0x00100001;
}
-#if CONFIG_EARLY_CBMEM_INIT
-int cbmem_get_table_location(uint64_t *tables_base, uint64_t *tables_size)
-{
- uint32_t tseg;
-
- /* Put the CBMEM location just below TSEG. */
- *tables_size = HIGH_MEMORY_SIZE;
- tseg = (pci_read_config32(dev_find_slot(0, PCI_DEVFN(0, 0)),
- TSEG) & ~((1 << 20) - 1)) - HIGH_MEMORY_SIZE;
- *tables_base = tseg;
-
- return 0;
-}
-#endif
-
static void northbridge_enable(device_t dev)
{
#if CONFIG_HAVE_ACPI_RESUME
1
0
Patch set updated for coreboot: 767f161 cbmem: dynamic cbmem support
by Stefan Reinauer March 20, 2013
by Stefan Reinauer March 20, 2013
March 20, 2013
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2848
-gerrit
commit 767f1613b8ed46a8902af03dbe21a84c544cd4a2
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Mar 13 12:41:44 2013 -0500
cbmem: dynamic cbmem support
This patch adds a parallel implementation of cbmem that supports
dynamic sizing. The original implementation relied on reserving
a fixed-size block of memory for adding cbmem entries. In order to
allow for more flexibility for adding cbmem allocations the dynamic
cbmem infrastructure was developed as an alternative to the fixed block
approach. Also, the amount of memory to reserve for cbmem allocations
does not need to be known prior to the first allocation.
The dynamic cbmem code implements the same API as the existing cbmem
code except for cbmem_init() and cbmem_reinit(). The add and find
routines behave the same way. The dynamic cbmem infrastructure
uses a top down allocator that starts allocating from a board/chipset
defined function cbmem_top(). A root pointer lives just below
cbmem_top(). In turn that pointer points to the root block which
contains the entries for all the large alloctations. The corresponding
block for each large allocation falls just below the previous entry.
It should be noted that this implementation rounds all allocations
up to a 4096 byte granularity. Though a packing allocator could
be written for small allocations it was deemed OK to just fragment
the memory as there shouldn't be that many small allocations. The
result is less code with a tradeoff of some wasted memory.
+----------------------+ <- cbmem_top()
| +----| root pointer |
| | +----------------------+
| | | |--------+
| +--->| root block |-----+ |
| +----------------------+ | |
| | | | |
| | | | |
| | alloc N |<----+ |
| +----------------------+ |
| | | |
| | | |
\|/ | alloc N + 1 |<-------+
v +----------------------+
In addition to preserving the previous cbmem API, the dynamic
cbmem API allows for removing blocks from cbmem. This allows for
the boot process to allocate memory that can be discarded after
it's been used for performing more complex boot tasks in romstage.
In order to plumb this support in there were some issues to work
around regarding writing of coreboot tables. There were a few
assumptions to how cbmem was layed out which dictated some ifdef
guarding and other runtime checks so as not to incorrectly
tag the e820 and coreboot memory tables.
The example shown below is using dynamic cbmem infrastructure.
The reserved memory for cbmem is less than 512KiB.
coreboot memory table:
0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES
1. 0000000000001000-000000000002ffff: RAM
2. 0000000000030000-000000000003ffff: RESERVED
3. 0000000000040000-000000000009ffff: RAM
4. 00000000000a0000-00000000000fffff: RESERVED
5. 0000000000100000-0000000000efffff: RAM
6. 0000000000f00000-0000000000ffffff: RESERVED
7. 0000000001000000-000000007bf80fff: RAM
8. 000000007bf81000-000000007bffffff: CONFIGURATION TABLES
9. 000000007c000000-000000007e9fffff: RESERVED
10. 00000000f0000000-00000000f3ffffff: RESERVED
11. 00000000fed10000-00000000fed19fff: RESERVED
12. 00000000fed84000-00000000fed84fff: RESERVED
13. 0000000100000000-00000001005fffff: RAM
Wrote coreboot table at: 7bf81000, 0x39c bytes, checksum f5bf
coreboot table: 948 bytes.
CBMEM ROOT 0. 7bfff000 00001000
MRC DATA 1. 7bffe000 00001000
ROMSTAGE 2. 7bffd000 00001000
TIME STAMP 3. 7bffc000 00001000
ROMSTG STCK 4. 7bff7000 00005000
CONSOLE 5. 7bfe7000 00010000
VBOOT 6. 7bfe6000 00001000
RAMSTAGE 7. 7bf98000 0004e000
GDT 8. 7bf97000 00001000
ACPI 9. 7bf8b000 0000c000
ACPI GNVS 10. 7bf8a000 00001000
SMBIOS 11. 7bf89000 00001000
COREBOOT 12. 7bf81000 00008000
And the corresponding e820 entries:
BIOS-e820: [mem 0x0000000000000000-0x0000000000000fff] type 16
BIOS-e820: [mem 0x0000000000001000-0x000000000002ffff] usable
BIOS-e820: [mem 0x0000000000030000-0x000000000003ffff] reserved
BIOS-e820: [mem 0x0000000000040000-0x000000000009ffff] usable
BIOS-e820: [mem 0x00000000000a0000-0x00000000000fffff] reserved
BIOS-e820: [mem 0x0000000000100000-0x0000000000efffff] usable
BIOS-e820: [mem 0x0000000000f00000-0x0000000000ffffff] reserved
BIOS-e820: [mem 0x0000000001000000-0x000000007bf80fff] usable
BIOS-e820: [mem 0x000000007bf81000-0x000000007bffffff] type 16
BIOS-e820: [mem 0x000000007c000000-0x000000007e9fffff] reserved
BIOS-e820: [mem 0x00000000f0000000-0x00000000f3ffffff] reserved
BIOS-e820: [mem 0x00000000fed10000-0x00000000fed19fff] reserved
BIOS-e820: [mem 0x00000000fed84000-0x00000000fed84fff] reserved
BIOS-e820: [mem 0x0000000100000000-0x00000001005fffff] usable
Change-Id: Ie3bca52211800a8652a77ca684140cfc9b3b9a6b
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/Kconfig | 8 +
src/arch/armv7/boot/coreboot_table.c | 2 +-
src/arch/armv7/include/arch/coreboot_tables.h | 3 +
src/arch/x86/boot/coreboot_table.c | 24 +-
src/arch/x86/boot/tables.c | 2 +
src/arch/x86/include/arch/coreboot_tables.h | 3 +
src/include/cbmem.h | 104 +++++-
src/lib/Makefile.inc | 12 +-
src/lib/cbmem.c | 36 +-
src/lib/cbmem_info.c | 69 ++++
src/lib/dynamic_cbmem.c | 452 ++++++++++++++++++++++++++
src/lib/hardwaremain.c | 7 +-
12 files changed, 677 insertions(+), 45 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index 7a8985c..0297970 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -179,6 +179,14 @@ config EARLY_CBMEM_INIT
some, for instance, execution timestamps. It needs support in
romstage.c and should be enabled by the board's Kconfig.
+config DYNAMIC_CBMEM
+ bool "The CBMEM space is dynamically grown."
+ default n
+ help
+ Instead of reserving a static amount of CBMEM space the CBMEM
+ area grows dynamically. CBMEM can be used both in romstage (after
+ memory initialization) and ramstage.
+
config COLLECT_TIMESTAMPS
bool "Create a table of timestamps collected during boot"
depends on EARLY_CBMEM_INIT
diff --git a/src/arch/armv7/boot/coreboot_table.c b/src/arch/armv7/boot/coreboot_table.c
index 47aad36..e5aa6ed 100644
--- a/src/arch/armv7/boot/coreboot_table.c
+++ b/src/arch/armv7/boot/coreboot_table.c
@@ -484,7 +484,7 @@ static void lb_remove_memory_range(struct lb_memory *mem,
}
}
-static void lb_add_memory_range(struct lb_memory *mem,
+void lb_add_memory_range(struct lb_memory *mem,
uint32_t type, uint64_t start, uint64_t size)
{
lb_remove_memory_range(mem, start, size);
diff --git a/src/arch/armv7/include/arch/coreboot_tables.h b/src/arch/armv7/include/arch/coreboot_tables.h
index 4c2a013..c5eacf8 100644
--- a/src/arch/armv7/include/arch/coreboot_tables.h
+++ b/src/arch/armv7/include/arch/coreboot_tables.h
@@ -12,6 +12,9 @@ unsigned long write_coreboot_table(
void lb_memory_range(struct lb_memory *mem,
uint32_t type, uint64_t start, uint64_t size);
+void lb_add_memory_range(struct lb_memory *mem,
+ uint32_t type, uint64_t start, uint64_t size);
+
void fill_lb_gpios(struct lb_gpios *gpios);
/* Routines to extract part so the coreboot table or information
diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c
index 463f723..617fab2 100644
--- a/src/arch/x86/boot/coreboot_table.c
+++ b/src/arch/x86/boot/coreboot_table.c
@@ -355,6 +355,9 @@ static void lb_memory_range(struct lb_memory *mem,
static void lb_reserve_table_memory(struct lb_header *head)
{
+/* Dynamic cbmem has already reserved the memory where the coreboot tables
+ * reside. Therefore, there is nothing to fix up. */
+#if !CONFIG_DYNAMIC_CBMEM
struct lb_record *last_rec;
struct lb_memory *mem;
uint64_t start;
@@ -383,6 +386,7 @@ static void lb_reserve_table_memory(struct lb_header *head)
mem->map[i].size = pack_lb64(map_end - end);
}
}
+#endif
}
static unsigned long lb_table_fini(struct lb_header *head, int fixup)
@@ -507,7 +511,7 @@ static void lb_remove_memory_range(struct lb_memory *mem,
}
}
-static void lb_add_memory_range(struct lb_memory *mem,
+void lb_add_memory_range(struct lb_memory *mem,
uint32_t type, uint64_t start, uint64_t size)
{
lb_remove_memory_range(mem, start, size);
@@ -664,14 +668,20 @@ unsigned long write_coreboot_table(
lb_add_memory_range(mem, LB_MEM_TABLE,
low_table_start, low_table_end - low_table_start);
- /* Record the pirq table, acpi tables, and maybe the mptable */
- lb_add_memory_range(mem, LB_MEM_TABLE,
- rom_table_start, rom_table_end-rom_table_start);
-
- printk(BIOS_DEBUG, "Adding high table area\n");
- // should this be LB_MEM_ACPI?
+ /* Record the pirq table, acpi tables, and maybe the mptable. However,
+ * these only need to be added when the rom_table is sitting below
+ * 1MiB. If it isn't that means high tables are being written.
+ * The code below handles high tables correctly. */
+ if (rom_table_end <= (1 << 20))
+ lb_add_memory_range(mem, LB_MEM_TABLE,
+ rom_table_start, rom_table_end-rom_table_start);
+
+#if CONFIG_DYNAMIC_CBMEM
+ cbmem_add_lb_mem(mem);
+#else /* CONFIG_DYNAMIC_CBMEM */
lb_add_memory_range(mem, LB_MEM_TABLE,
high_tables_base, high_tables_size);
+#endif /* CONFIG_DYNAMIC_CBMEM */
/* Add reserved regions */
add_lb_reserved(mem);
diff --git a/src/arch/x86/boot/tables.c b/src/arch/x86/boot/tables.c
index 294a10c..d842e73 100644
--- a/src/arch/x86/boot/tables.c
+++ b/src/arch/x86/boot/tables.c
@@ -53,6 +53,7 @@ struct lb_memory *write_tables(void)
*/
unsigned long high_table_pointer;
+#if !CONFIG_DYNAMIC_CBMEM
if (!high_tables_base) {
printk(BIOS_ERR, "ERROR: High Tables Base is not set.\n");
// Are there any boards without?
@@ -60,6 +61,7 @@ struct lb_memory *write_tables(void)
}
printk(BIOS_DEBUG, "High Tables Base is %llx.\n", high_tables_base);
+#endif
rom_table_start = 0xf0000;
rom_table_end = 0xf0000;
diff --git a/src/arch/x86/include/arch/coreboot_tables.h b/src/arch/x86/include/arch/coreboot_tables.h
index e9790db..a8deeed 100644
--- a/src/arch/x86/include/arch/coreboot_tables.h
+++ b/src/arch/x86/include/arch/coreboot_tables.h
@@ -8,6 +8,9 @@ unsigned long write_coreboot_table(
unsigned long low_table_start, unsigned long low_table_end,
unsigned long rom_table_start, unsigned long rom_table_end);
+void lb_add_memory_range(struct lb_memory *mem,
+ uint32_t type, uint64_t start, uint64_t size);
+
/* Routines to extract part so the coreboot table or information
* from the coreboot table.
*/
diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index 1212cb2..41f5971 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2013 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
@@ -62,9 +63,72 @@
#define CBMEM_ID_ELOG 0x454c4f47
#define CBMEM_ID_COVERAGE 0x47434f56
#define CBMEM_ID_ROMSTAGE_INFO 0x47545352
+#define CBMEM_ID_ROMSTAGE_RAM_STACK 0x90357ac4
+#define CBMEM_ID_RAMSTAGE 0x9a357a9e
+#define CBMEM_ID_RAMSTAGE_CACHE 0x9a3ca54e
+#define CBMEM_ID_ROOT 0xff4007ff
#define CBMEM_ID_NONE 0x00000000
#ifndef __ASSEMBLER__
+#include <stdint.h>
+
+struct cbmem_entry;
+
+#if CONFIG_DYNAMIC_CBMEM
+
+/*
+ * The dynamic cbmem infrastructure allows for growing cbmem dynamically as
+ * things are added. It requires an external function, cbmem_top(), to be
+ * implemented by the board or chipset to define the upper address where
+ * cbmem lives. This address is required to be a 32-bit address. Additionally,
+ * the address needs to be consistent in both romstage and ramstage. The
+ * dynamic cbmem infrasturue allocates new regions below the last allocated
+ * region. Regions are defined by a cbmem_entry struct that is opaque. Regions
+ * may be removed, but the last one added is the only that can be removed.
+ *
+ * Dynamic cbmem has two allocators within it. All allocators use a top down
+ * allocation scheme. However, there are 2 modes for each allocation depending
+ * on the requested size. There are large allocations and small allocations.
+ * An allocation is considered to be small when it is less than or equal to
+ * DYN_CBMEM_ALIGN_SIZE / 2. The smaller allocations are fit into a larger
+ * allocation region.
+ */
+
+#define DYN_CBMEM_ALIGN_SIZE (4096)
+
+/* Initialze cbmem to be empty. */
+void cbmem_initialize_empty(void);
+
+/* Return the top address for dynamic cbmem. The address returned needs to
+ * be consistent across romstage and ramstage, and it is required to be
+ * below 4GiB. */
+void *cbmem_top(void);
+
+/* Add a cbmem entry of a given size and id. These return NULL on failure. The
+ * add function performs a find first and do not check against the original
+ * size. */
+const struct cbmem_entry *cbmem_entry_add(u32 id, u64 size);
+
+/* Find a cbmem entry of a given id. These return NULL on failure. */
+const struct cbmem_entry *cbmem_entry_find(u32 id);
+
+/* Remove a region defined by a cbmem_entry. Returns 0 on success, < 0 on
+ * error. Note: A cbmem_entry cannot be removed unless it was the last one
+ * added. */
+int cbmem_entry_remove(const struct cbmem_entry *entry);
+
+/* cbmem_entry accessors to get pointer and size of a cbmem_entry. */
+void *cbmem_entry_start(const struct cbmem_entry *entry);
+u64 cbmem_entry_size(const struct cbmem_entry *entry);
+
+#ifndef __PRE_RAM__
+/* Add the cbmem memory used to the memory tables. */
+struct lb_memory;
+void cbmem_add_lb_mem(struct lb_memory *mem);
+#endif /* __PRE_RAM__ */
+
+#else /* !CONFIG_DYNAMIC_CBMEM */
+
#ifndef __PRE_RAM__
extern uint64_t high_tables_base, high_tables_size;
#if CONFIG_EARLY_CBMEM_INIT
@@ -72,22 +136,44 @@ extern uint64_t high_tables_base, high_tables_size;
int __attribute__((weak)) cbmem_get_table_location(uint64_t *tables_base,
uint64_t *tables_size);
#endif
+void set_cbmem_toc(struct cbmem_entry *);
#endif
-int cbmem_initialize(void);
-
void cbmem_init(u64 baseaddr, u64 size);
int cbmem_reinit(u64 baseaddr);
+
+extern struct cbmem_entry *get_cbmem_toc(void);
+
+#endif /* CONFIG_DYNAMIC_CBMEM */
+
+/* Common API between cbmem and dynamic cbmem. */
+
+/* By default cbmem is attempted to be recovered. Returns 0 if cbmem was
+ * recovered or 1 if cbmem had to be reinitialized. */
+int cbmem_initialize(void);
+/* Add a cbmem entry of a given size and id. These return NULL on failure. The
+ * add function performs a find first and do not check against the original
+ * size. */
void *cbmem_add(u32 id, u64 size);
+/* Find a cbmem entry of a given id. These return NULL on failure. */
void *cbmem_find(u32 id);
+
+#ifndef __PRE_RAM__
+/* Ramstage only functions. */
void cbmem_list(void);
void cbmem_arch_init(void);
+void __attribute__((weak)) cbmem_post_handling(void);
+void cbmem_print_entry(int n, u32 id, u64 start, u64 size);
+/* The pre|post device cbmem initialization functions are for the
+ * ramstage main to call. When cbmem is actually initialized depends on
+ * the cbmem implementation. */
+void init_cbmem_pre_device(void);
+void init_cbmem_post_device(void);
+#else
+static inline void cbmem_arch_init(void) {}
+#endif /* __PRE_RAM__ */
-extern struct cbmem_entry *get_cbmem_toc(void);
+#endif /* __ASSEMBLER__ */
-#ifndef __PRE_RAM__
-void set_cbmem_toc(struct cbmem_entry *);
-void __attribute__((weak)) cbmem_post_handling(void);
-#endif
-#endif
-#endif
+
+#endif /* _CBMEM_H_ */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index fe57f9f..c0372c5 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -42,7 +42,6 @@ romstage-y += cbfs.c
romstage-y += lzma.c
#romstage-y += lzmadecode.c
romstage-$(CONFIG_CACHE_AS_RAM) += ramtest.c
-romstage-$(CONFIG_HAVE_ACPI_RESUME) += cbmem.c
romstage-$(CONFIG_CONSOLE_SERIAL8250) += uart8250.c
romstage-$(CONFIG_CONSOLE_SERIAL8250MEM) += uart8250mem.c
romstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
@@ -76,7 +75,6 @@ ramstage-y += lzma.c
ramstage-y += stack.c
ramstage-$(CONFIG_ARCH_X86) += gcc.c
ramstage-y += clog2.c
-ramstage-y += cbmem.c
ramstage-$(CONFIG_CONSOLE_SERIAL8250) += uart8250.c
ramstage-$(CONFIG_CONSOLE_SERIAL8250MEM) += uart8250mem.c
ramstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
@@ -86,6 +84,16 @@ ramstage-$(CONFIG_TRACE) += trace.c
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
ramstage-$(CONFIG_COVERAGE) += libgcov.c
+# The CBMEM implementations are chosen based on CONFIG_DYNAMIC_CBMEM.
+ifeq ($(CONFIG_DYNAMIC_CBMEM),y)
+ramstage-y += dynamic_cbmem.c
+romstage-y += dynamic_cbmem.c
+else
+ramstage-y += cbmem.c
+romstage-$(CONFIG_HAVE_ACPI_RESUME) += cbmem.c
+endif # CONFIG_DYNAMIC_CBMEM
+ramstage-y += cbmem_info.c
+
ramstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
diff --git a/src/lib/cbmem.c b/src/lib/cbmem.c
index 5663cc8..ad98082 100644
--- a/src/lib/cbmem.c
+++ b/src/lib/cbmem.c
@@ -232,6 +232,18 @@ int cbmem_initialize(void)
#endif
#ifndef __PRE_RAM__
+/* cbmem cannot be initialized before device drivers, but it can be initialized
+ * after the drivers have run. */
+void init_cbmem_pre_device(void) {}
+
+void init_cbmem_post_device(void)
+{
+ cbmem_initialize();
+#if CONFIG_CONSOLE_CBMEM
+ cbmemc_reinit();
+#endif
+}
+
void cbmem_list(void)
{
struct cbmem_entry *cbmem_toc;
@@ -245,28 +257,8 @@ void cbmem_list(void)
if (cbmem_toc[i].magic != CBMEM_MAGIC)
continue;
- printk(BIOS_DEBUG, "%2d. ", i);
- switch (cbmem_toc[i].id) {
- case CBMEM_ID_FREESPACE: printk(BIOS_DEBUG, "FREE SPACE "); break;
- case CBMEM_ID_GDT: printk(BIOS_DEBUG, "GDT "); break;
- case CBMEM_ID_ACPI: printk(BIOS_DEBUG, "ACPI "); break;
- case CBMEM_ID_CBTABLE: printk(BIOS_DEBUG, "COREBOOT "); break;
- case CBMEM_ID_PIRQ: printk(BIOS_DEBUG, "IRQ TABLE "); break;
- case CBMEM_ID_MPTABLE: printk(BIOS_DEBUG, "SMP TABLE "); break;
- case CBMEM_ID_RESUME: printk(BIOS_DEBUG, "ACPI RESUME"); break;
- case CBMEM_ID_RESUME_SCRATCH: printk(BIOS_DEBUG, "ACPISCRATCH"); break;
- case CBMEM_ID_ACPI_GNVS: printk(BIOS_DEBUG, "ACPI GNVS "); break;
- case CBMEM_ID_SMBIOS: printk(BIOS_DEBUG, "SMBIOS "); break;
- case CBMEM_ID_TIMESTAMP: printk(BIOS_DEBUG, "TIME STAMP "); break;
- case CBMEM_ID_MRCDATA: printk(BIOS_DEBUG, "MRC DATA "); break;
- case CBMEM_ID_CONSOLE: printk(BIOS_DEBUG, "CONSOLE "); break;
- case CBMEM_ID_ELOG: printk(BIOS_DEBUG, "ELOG "); break;
- case CBMEM_ID_COVERAGE: printk(BIOS_DEBUG, "COVERAGE "); break;
- case CBMEM_ID_ROMSTAGE_INFO: printk(BIOS_DEBUG, "ROMSTAGE "); break;
- default: printk(BIOS_DEBUG, "%08x ", cbmem_toc[i].id);
- }
- printk(BIOS_DEBUG, "%08llx ", cbmem_toc[i].base);
- printk(BIOS_DEBUG, "%08llx\n", cbmem_toc[i].size);
+ cbmem_print_entry(i, cbmem_toc[i].id, cbmem_toc[i].base,
+ cbmem_toc[i].size);
}
}
#endif
diff --git a/src/lib/cbmem_info.c b/src/lib/cbmem_info.c
new file mode 100644
index 0000000..aaf5840
--- /dev/null
+++ b/src/lib/cbmem_info.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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 wacbmem_entryanty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <console/console.h>
+#include <cbmem.h>
+#include <stdlib.h>
+
+static struct cbmem_id_to_name {
+ u32 id;
+ const char *name;
+} cbmem_ids[] = {
+ { CBMEM_ID_FREESPACE, "FREE SPACE " },
+ { CBMEM_ID_GDT, "GDT " },
+ { CBMEM_ID_ACPI, "ACPI " },
+ { CBMEM_ID_CBTABLE, "COREBOOT " },
+ { CBMEM_ID_PIRQ, "IRQ TABLE " },
+ { CBMEM_ID_MPTABLE, "SMP TABLE " },
+ { CBMEM_ID_RESUME, "ACPI RESUME" },
+ { CBMEM_ID_RESUME_SCRATCH, "ACPISCRATCH" },
+ { CBMEM_ID_ACPI_GNVS, "ACPI GNVS " },
+ { CBMEM_ID_SMBIOS, "SMBIOS " },
+ { CBMEM_ID_TIMESTAMP, "TIME STAMP " },
+ { CBMEM_ID_MRCDATA, "MRC DATA " },
+ { CBMEM_ID_CONSOLE, "CONSOLE " },
+ { CBMEM_ID_ELOG, "ELOG " },
+ { CBMEM_ID_COVERAGE, "COVERAGE " },
+ { CBMEM_ID_ROMSTAGE_INFO, "ROMSTAGE " },
+ { CBMEM_ID_ROMSTAGE_RAM_STACK, "ROMSTG STCK" },
+ { CBMEM_ID_RAMSTAGE, "RAMSTAGE " },
+ { CBMEM_ID_RAMSTAGE_CACHE, "RAMSTAGE $ " },
+ { CBMEM_ID_ROOT, "CBMEM ROOT " },
+};
+
+void cbmem_print_entry(int n, u32 id, u64 base, u64 size)
+{
+ int i;
+ const char *name;
+
+ name = NULL;
+ for (i = 0; i < ARRAY_SIZE(cbmem_ids); i++) {
+ if (cbmem_ids[i].id == id) {
+ name = cbmem_ids[i].name;
+ break;
+ }
+ }
+
+ if (name == NULL)
+ printk(BIOS_DEBUG, "%08x ", id);
+ else
+ printk(BIOS_DEBUG, "%s", name);
+ printk(BIOS_DEBUG, "%2d. ", n);
+ printk(BIOS_DEBUG, "%08llx ", base);
+ printk(BIOS_DEBUG, "%08llx\n", size);
+}
diff --git a/src/lib/dynamic_cbmem.c b/src/lib/dynamic_cbmem.c
new file mode 100644
index 0000000..ae6c87a
--- /dev/null
+++ b/src/lib/dynamic_cbmem.c
@@ -0,0 +1,452 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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 wacbmem_entryanty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <boot/tables.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <string.h>
+#include <stdlib.h>
+#if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__)
+#include <arch/acpi.h>
+#endif
+
+#ifndef UINT_MAX
+#define UINT_MAX 4294967295U
+#endif
+
+/* ACPI resume needs to be cleared in the fail-to-recover case, but that
+ * condition is only handled during ramstage. */
+#if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__)
+static inline void cbmem_handle_acpi_resume(void)
+{
+ /* Something went wrong, our high memory area got wiped */
+ if (acpi_slp_type == 3 || acpi_slp_type == 2)
+ acpi_slp_type = 0;
+}
+#else
+static inline void cbmem_handle_acpi_resume(void) {}
+#endif
+
+/*
+ * The dynamic cbmem code uses a root region. The root region boundary
+ * addresses are determined by cbmem_top() and ROOT_MIN_SIZE. Just below
+ * the address returned by cbmem_top() is a pointer that points to the
+ * root data structure. The root data structure provides the book keeping
+ * for each large entry.
+ */
+
+/* The root region is at least DYN_CBMEM_ALIGN_SIZE . */
+#define ROOT_MIN_SIZE DYN_CBMEM_ALIGN_SIZE
+#define CBMEM_POINTER_MAGIC 0xc0389479
+#define CBMEM_ENTRY_MAGIC ~(CBMEM_POINTER_MAGIC)
+
+/* The cbmem_root_pointer structure lives just below address returned
+ * from cbmem_top(). It points to the root data structure that
+ * maintains the entries. */
+struct cbmem_root_pointer {
+ u32 magic;
+ u32 root;
+} __attribute__((packed));
+
+struct cbmem_entry {
+ u32 magic;
+ u32 start;
+ u32 size;
+ u32 id;
+} __attribute__((packed));
+
+struct cbmem_root {
+ u32 max_entries;
+ u32 num_entries;
+ u32 locked;
+ u32 size;
+ struct cbmem_entry entries[0];
+} __attribute__((packed));
+
+
+static inline void *cbmem_top_cached(void)
+{
+#if !defined(__PRE_RAM__)
+ static void *cached_cbmem_top;
+
+ if (cached_cbmem_top == NULL)
+ cached_cbmem_top = cbmem_top();
+
+ return cached_cbmem_top;
+#else
+ return cbmem_top();
+#endif
+}
+
+static inline void *get_top_aligned(void)
+{
+ unsigned long top;
+
+ /* Align down what is returned from cbmem_top(). */
+ top = (unsigned long)cbmem_top_cached();
+ top &= ~(DYN_CBMEM_ALIGN_SIZE - 1);
+
+ return (void *)top;
+}
+
+static inline void *get_root(void)
+{
+ unsigned long pointer_addr;
+ struct cbmem_root_pointer *pointer;
+
+ pointer_addr = (unsigned long)get_top_aligned();
+ pointer_addr -= sizeof(struct cbmem_root_pointer);
+
+ pointer = (void *)pointer_addr;
+ if (pointer->magic != CBMEM_POINTER_MAGIC)
+ return NULL;
+
+ return (void *)pointer->root;
+}
+
+static inline void cbmem_entry_assign(struct cbmem_entry *entry,
+ u32 id, u32 start, u32 size)
+{
+ entry->magic = CBMEM_ENTRY_MAGIC;
+ entry->start = start;
+ entry->size = size;
+ entry->id = id;
+}
+
+static inline const struct cbmem_entry *
+cbmem_entry_append(struct cbmem_root *root, u32 id, u32 start, u32 size)
+{
+ struct cbmem_entry *cbmem_entry;
+
+ cbmem_entry = &root->entries[root->num_entries];
+ root->num_entries++;
+
+ cbmem_entry_assign(cbmem_entry, id, start, size);
+
+ return cbmem_entry;
+}
+
+void cbmem_initialize_empty(void)
+{
+ unsigned long pointer_addr;
+ unsigned long root_addr;
+ unsigned long max_entries;
+ struct cbmem_root *root;
+ struct cbmem_root_pointer *pointer;
+
+ /* Place the root pointer and the root. The number of entries is
+ * dictated by difference between the root address and the pointer
+ * where the root address is aligned down to
+ * DYN_CBMEM_ALIGN_SIZE. The pointer falls just below the
+ * address returned by get_top_aligned(). */
+ pointer_addr = (unsigned long)get_top_aligned();
+ root_addr = pointer_addr - ROOT_MIN_SIZE;
+ root_addr &= ~(DYN_CBMEM_ALIGN_SIZE - 1);
+ pointer_addr -= sizeof(struct cbmem_root_pointer);
+
+ max_entries = (pointer_addr - (root_addr + sizeof(*root))) /
+ sizeof(struct cbmem_entry);
+
+ pointer = (void *)pointer_addr;
+ pointer->magic = CBMEM_POINTER_MAGIC;
+ pointer->root = root_addr;
+
+ root = (void *)root_addr;
+ root->max_entries = max_entries;
+ root->num_entries = 0;
+ root->locked = 0;
+ root->size = pointer_addr - root_addr +
+ sizeof(struct cbmem_root_pointer);
+
+ /* Add an entry covering the root region. */
+ cbmem_entry_append(root, CBMEM_ID_ROOT, root_addr, root->size);
+
+ printk(BIOS_DEBUG, "CBMEM: root @ %p %d entries.\n",
+ root, root->max_entries);
+
+ cbmem_arch_init();
+}
+
+static inline int cbmem_fail_recovery(void)
+{
+ cbmem_initialize_empty();
+ cbmem_handle_acpi_resume();
+ return 1;
+}
+
+static int validate_entries(struct cbmem_root *root)
+{
+ unsigned int i;
+ u32 current_end;
+
+ current_end = (u32)get_top_aligned();
+
+ printk(BIOS_DEBUG, "CBMEM: recovering %d/%d entries from root @ %p\n",
+ root->num_entries, root->max_entries, root);
+
+ /* Check that all regions are properly aligned and are just below
+ * the previous entry */
+ for (i = 0; i < root->num_entries; i++) {
+ struct cbmem_entry *entry = &root->entries[i];
+
+ if (entry->magic != CBMEM_ENTRY_MAGIC)
+ return -1;
+
+ if (entry->start & (DYN_CBMEM_ALIGN_SIZE - 1))
+ return -1;
+
+ if (entry->start + entry->size != current_end)
+ return -1;
+
+ current_end = entry->start;
+ }
+
+ return 0;
+}
+
+int cbmem_initialize(void)
+{
+ struct cbmem_root *root;
+ void *top_according_to_root;
+
+ root = get_root();
+
+ /* No recovery possible since root couldn't be recovered. */
+ if (root == NULL)
+ return cbmem_fail_recovery();
+
+ /* Sanity check the root. */
+ top_according_to_root = (void *)(root->size + (unsigned long)root);
+ if (get_top_aligned() != top_according_to_root)
+ return cbmem_fail_recovery();
+
+ if (root->num_entries > root->max_entries)
+ return cbmem_fail_recovery();
+
+ if ((root->max_entries * sizeof(struct cbmem_entry)) >
+ (root->size - sizeof(struct cbmem_root_pointer) - sizeof(*root)))
+ return cbmem_fail_recovery();
+
+ /* Validate current entries. */
+ if (validate_entries(root))
+ return cbmem_fail_recovery();
+
+#if defined(__PRE_RAM__)
+ /* Lock the root in the romstage on a recovery. The assumption is that
+ * recovery is called during romstage on the S3 resume path. */
+ root->locked = 1;
+#endif
+
+ cbmem_arch_init();
+
+ /* Recovery successful. */
+ return 0;
+}
+
+static void *cbmem_base(void)
+{
+ struct cbmem_root *root;
+ u32 low_addr;
+
+ root = get_root();
+
+ if (root == NULL)
+ return NULL;
+
+ low_addr = (u32)root;
+
+ /* Assume the lowest address is the last one added. */
+ if (root->num_entries > 0) {
+ low_addr = root->entries[root->num_entries - 1].start;
+ }
+
+ return (void *)low_addr;
+}
+
+
+const struct cbmem_entry *cbmem_entry_add(u32 id, u64 size64)
+{
+ struct cbmem_root *root;
+ const struct cbmem_entry *entry;
+ unsigned long base;;
+ u32 size;
+ u32 aligned_size;
+
+ entry = cbmem_entry_find(id);
+
+ if (entry != NULL)
+ return entry;
+
+ /* Only handle sizes <= UINT_MAX internally. */
+ if (size64 > (u64)UINT_MAX)
+ return NULL;
+
+ size = size64;
+
+ root = get_root();
+
+ if (root == NULL)
+ return NULL;
+
+ /* Nothing can be added once it is locked down. */
+ if (root->locked)
+ return NULL;
+
+ if (root->max_entries == root->num_entries)
+ return NULL;
+
+ aligned_size = ALIGN(size, DYN_CBMEM_ALIGN_SIZE);
+ base = (unsigned long)cbmem_base();
+ base -= aligned_size;
+
+ return cbmem_entry_append(root, id, base, aligned_size);
+}
+
+void *cbmem_add(u32 id, u64 size)
+{
+ const struct cbmem_entry *entry;
+
+ entry = cbmem_entry_add(id, size);
+
+ if (entry == NULL)
+ return NULL;
+
+ return cbmem_entry_start(entry);
+}
+
+/* Retrieve a region provided a given id. */
+const struct cbmem_entry *cbmem_entry_find(u32 id)
+{
+ struct cbmem_root *root;
+ const struct cbmem_entry *entry;
+ unsigned int i;
+
+ root = get_root();
+
+ if (root == NULL)
+ return NULL;
+
+ entry = NULL;
+
+ for (i = 0; i < root->num_entries; i++) {
+ if (root->entries[i].id == id) {
+ entry = &root->entries[i];
+ break;
+ }
+ }
+
+ return entry;
+}
+
+void *cbmem_find(u32 id)
+{
+ const struct cbmem_entry *entry;
+
+ entry = cbmem_entry_find(id);
+
+ if (entry == NULL)
+ return NULL;
+
+ return cbmem_entry_start(entry);
+}
+
+/* Remove a reserved region. Returns 0 on success, < 0 on error. Note: A region
+ * cannot be removed unless it was the last one added. */
+int cbmem_entry_remove(const struct cbmem_entry *entry)
+{
+ unsigned long entry_num;
+ struct cbmem_root *root;
+
+ root = get_root();
+
+ if (root == NULL)
+ return -1;
+
+ if (root->num_entries == 0)
+ return -1;
+
+ /* Nothing can be removed. */
+ if (root->locked)
+ return -1;
+
+ entry_num = entry - &root->entries[0];
+
+ /* If the entry is the last one in the root it can be removed. */
+ if (entry_num == (root->num_entries - 1)) {
+ root->num_entries--;
+ return 0;
+ }
+
+ return -1;
+}
+
+u64 cbmem_entry_size(const struct cbmem_entry *entry)
+{
+ return entry->size;
+}
+
+void *cbmem_entry_start(const struct cbmem_entry *entry)
+{
+ return (void *)entry->start;
+}
+
+
+#if !defined(__PRE_RAM__)
+/* selected cbmem can be initialized early in ramstage. Additionally, that
+ * means cbmem console can be reinitialized early as well. The post_device
+ * function is empty since cbmem was initialized early in ramstage. */
+void init_cbmem_pre_device(void)
+{
+ cbmem_initialize();
+#if CONFIG_CONSOLE_CBMEM
+ cbmemc_reinit();
+#endif /* CONFIG_CONSOLE_CBMEM */
+}
+
+void init_cbmem_post_device(void) {}
+
+void cbmem_add_lb_mem(struct lb_memory *mem)
+{
+ unsigned long base;
+ unsigned long top;
+
+ base = (unsigned long)cbmem_base();
+ top = (unsigned long)get_top_aligned();
+ lb_add_memory_range(mem, LB_MEM_TABLE, base, top - base);
+}
+
+void cbmem_list(void)
+{
+ unsigned int i;
+ struct cbmem_root *root;
+
+ root = get_root();
+
+ if (root == NULL)
+ return;
+
+ for (i = 0; i < root->num_entries; i++) {
+ struct cbmem_entry *entry;
+
+ entry = &root->entries[i];
+
+ cbmem_print_entry(i, entry->id, entry->start, entry->size);
+ }
+}
+#endif /* __PRE_RAM__ */
diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index b29cc93..bc18989 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -94,6 +94,7 @@ void hardwaremain(int boot_complete)
!cbmem_get_table_location(&high_tables_base, &high_tables_size))
cbmem_initialize();
#endif
+ init_cbmem_pre_device();
timestamp_stash(TS_DEVICE_ENUMERATE);
@@ -121,10 +122,8 @@ void hardwaremain(int boot_complete)
timestamp_stash(TS_DEVICE_DONE);
- cbmem_initialize();
-#if CONFIG_CONSOLE_CBMEM
- cbmemc_reinit();
-#endif
+ init_cbmem_post_device();
+
timestamp_sync();
#if CONFIG_HAVE_ACPI_RESUME
1
0