1 /** @file
2   This code fills in standard CMOS values and updates the standard CMOS
3   checksum. The Legacy16 code or LegacyBiosPlatform.c is responsible for
4   non-standard CMOS locations and non-standard checksums.
5 
6 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
7 
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9 
10 **/
11 
12 #include "LegacyBiosInterface.h"
13 
14 /**
15   Read CMOS register through index/data port.
16 
17   @param[in]  Index   The index of the CMOS register to read.
18 
19   @return  The data value from the CMOS register specified by Index.
20 
21 **/
22 UINT8
LegacyReadStandardCmos(IN UINT8 Index)23 LegacyReadStandardCmos (
24   IN UINT8  Index
25   )
26 {
27   IoWrite8 (PORT_70, Index);
28   return IoRead8 (PORT_71);
29 }
30 
31 /**
32   Write CMOS register through index/data port.
33 
34   @param[in]  Index  The index of the CMOS register to write.
35   @param[in]  Value  The value of CMOS register to write.
36 
37   @return  The value written to the CMOS register specified by Index.
38 
39 **/
40 UINT8
LegacyWriteStandardCmos(IN UINT8 Index,IN UINT8 Value)41 LegacyWriteStandardCmos (
42   IN UINT8  Index,
43   IN UINT8  Value
44   )
45 {
46   IoWrite8 (PORT_70, Index);
47   return IoWrite8 (PORT_71, Value);
48 }
49 
50 /**
51   Calculate the new standard CMOS checksum and write it.
52 
53   @param  Private      Legacy BIOS Instance data
54 
55   @retval EFI_SUCCESS  Calculate 16-bit checksum successfully
56 
57 **/
58 EFI_STATUS
LegacyCalculateWriteStandardCmosChecksum(VOID)59 LegacyCalculateWriteStandardCmosChecksum (
60   VOID
61   )
62 {
63   UINT8   Register;
64   UINT16  Checksum;
65 
66   for (Checksum = 0, Register = 0x10; Register < 0x2e; Register++) {
67     Checksum = (UINT16)(Checksum + LegacyReadStandardCmos (Register));
68   }
69   LegacyWriteStandardCmos (CMOS_2E, (UINT8)(Checksum >> 8));
70   LegacyWriteStandardCmos (CMOS_2F, (UINT8)(Checksum & 0xff));
71   return EFI_SUCCESS;
72 }
73 
74 
75 /**
76   Fill in the standard CMOS stuff before Legacy16 load
77 
78   @param  Private      Legacy BIOS Instance data
79 
80   @retval EFI_SUCCESS  It should always work.
81 
82 **/
83 EFI_STATUS
LegacyBiosInitCmos(IN LEGACY_BIOS_INSTANCE * Private)84 LegacyBiosInitCmos (
85   IN  LEGACY_BIOS_INSTANCE    *Private
86   )
87 {
88   UINT32  Size;
89 
90   //
91   //  Clear all errors except RTC lost power
92   //
93   LegacyWriteStandardCmos (CMOS_0E, (UINT8)(LegacyReadStandardCmos (CMOS_0E) & BIT7));
94 
95   //
96   // Update CMOS locations 15,16,17,18,30,31 and 32
97   // CMOS 16,15 = 640Kb = 0x280
98   // CMOS 18,17 = 31,30 = 15Mb max in 1Kb increments =0x3C00 max
99   // CMOS 32 = 0x20
100   //
101   LegacyWriteStandardCmos (CMOS_15, 0x80);
102   LegacyWriteStandardCmos (CMOS_16, 0x02);
103 
104   Size = 15 * SIZE_1MB;
105   if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) {
106     Size  = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10;
107   }
108 
109   LegacyWriteStandardCmos (CMOS_17, (UINT8)(Size & 0xFF));
110   LegacyWriteStandardCmos (CMOS_30, (UINT8)(Size & 0xFF));
111   LegacyWriteStandardCmos (CMOS_18, (UINT8)(Size >> 8));
112   LegacyWriteStandardCmos (CMOS_31, (UINT8)(Size >> 8));
113 
114   LegacyCalculateWriteStandardCmosChecksum ();
115 
116   return EFI_SUCCESS;
117 }
118