Bug Summary

File:home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c
Warning:line 103, column 32
The result of the left shift is undefined because the left operand is negative

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name SerialPortLib.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-jump-tables -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/build/StmPkg/EdkII/PcAtChipsetPkg/Library/SerialIoLib -resource-dir /opt/xgcc/lib/clang/17 -include PcdData.h -D COREBOOT32 -D RELEASE -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EDKII/BaseTools/Source/C/Include/X64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/MdePkg/Include -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/MdePkg/Include/X64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Include -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Include/x64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Runtime -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1714465709 -Os -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/build/StmPkg/EdkII/PcAtChipsetPkg/Library/SerialIoLib -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-max-loop 10 -analyzer-output=plist-html -faddrsig -o /cb-build/coreboot_scanbuild.0/PURISM_LIBREM15_V4_STM-scanbuildtmp/2024-05-02-081243-2232343-1/report-v3hJ_W.plist -x c /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c
1/** @file
2 UART Serial Port library functions
3
4 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include <Base.h>
16#include <Library/IoLib.h>
17#include <Library/SerialPortLib.h>
18
19//---------------------------------------------
20// UART Register Offsets
21//---------------------------------------------
22#define BAUD_LOW_OFFSET0x00 0x00
23#define BAUD_HIGH_OFFSET0x01 0x01
24#define IER_OFFSET0x01 0x01
25#define LCR_SHADOW_OFFSET0x01 0x01
26#define FCR_SHADOW_OFFSET0x02 0x02
27#define IR_CONTROL_OFFSET0x02 0x02
28#define FCR_OFFSET0x02 0x02
29#define EIR_OFFSET0x02 0x02
30#define BSR_OFFSET0x03 0x03
31#define LCR_OFFSET0x03 0x03
32#define MCR_OFFSET0x04 0x04
33#define LSR_OFFSET0x05 0x05
34#define MSR_OFFSET0x06 0x06
35
36//---------------------------------------------
37// UART Register Bit Defines
38//---------------------------------------------
39#define LSR_TXRDY0x20 0x20
40#define LSR_RXDA0x01 0x01
41#define DLAB0x01 0x01
42
43//---------------------------------------------
44// UART Settings
45//---------------------------------------------
46#ifndef UARTBASE
47UINT16 gUartBase = 0x3F8;
48#else
49UINT16 gUartBase = UARTBASE;
50#endif
51UINTN gBps = 115200;
52UINT8 gData = 8;
53UINT8 gStop = 1;
54UINT8 gParity = 0;
55UINT8 gBreakSet = 0;
56
57/**
58 Initialize the serial device hardware.
59
60 If no initialization is required, then return RETURN_SUCCESS.
61 If the serial device was successfuly initialized, then return RETURN_SUCCESS.
62 If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
63
64 @retval RETURN_SUCCESS The serial device was initialized.
65 @retval RETURN_DEVICE_ERROR The serail device could not be initialized.
66
67**/
68RETURN_STATUS
69EFIAPI
70SerialPortInitialize (
71 VOIDvoid
72 )
73{
74 UINTN Divisor;
75 UINT8 OutputData;
76 UINT8 Data;
77
78 //
79 // Map 5..8 to 0..3
80 //
81 Data = (UINT8) (gData - (UINT8) 5);
82
83 //
84 // Calculate divisor for baud generator
85 //
86 Divisor = 115200 / gBps;
87
88 //
89 // Set communications format
90 //
91 OutputData = (UINT8) ((DLAB0x01 << 7) | (gBreakSet << 6) | (gParity << 3) | (gStop << 2) | Data);
92 IoWrite8 ((UINTN) (gUartBase + LCR_OFFSET0x03), OutputData);
93
94 //
95 // Configure baud rate
96 //
97 IoWrite8 ((UINTN) (gUartBase + BAUD_HIGH_OFFSET0x01), (UINT8) (Divisor >> 8));
98 IoWrite8 ((UINTN) (gUartBase + BAUD_LOW_OFFSET0x00), (UINT8) (Divisor & 0xff));
99
100 //
101 // Switch back to bank 0
102 //
103 OutputData = (UINT8) ((~DLAB0x01 << 7) | (gBreakSet << 6) | (gParity << 3) | (gStop << 2) | Data);
The result of the left shift is undefined because the left operand is negative
104 IoWrite8 ((UINTN) (gUartBase + LCR_OFFSET0x03), OutputData);
105
106 return RETURN_SUCCESS0;
107}
108
109/**
110 Write data from buffer to serial device.
111
112 Writes NumberOfBytes data bytes from Buffer to the serial device.
113 The number of bytes actually written to the serial device is returned.
114 If the return value is less than NumberOfBytes, then the write operation failed.
115
116 If Buffer is NULL, then ASSERT().
117
118 If NumberOfBytes is zero, then return 0.
119
120 @param Buffer Pointer to the data buffer to be written.
121 @param NumberOfBytes Number of bytes to written to the serial device.
122
123 @retval 0 NumberOfBytes is 0.
124 @retval >0 The number of bytes written to the serial device.
125 If this value is less than NumberOfBytes, then the read operation failed.
126
127**/
128UINTN
129EFIAPI
130SerialPortWrite (
131 IN UINT8 *Buffer,
132 IN UINTN NumberOfBytes
133)
134{
135 UINTN Result;
136 UINT8 Data;
137
138 if (Buffer == NULL((void *) 0)) {
139 return 0;
140 }
141
142 Result = NumberOfBytes;
143
144 while (NumberOfBytes--) {
145 SerialPortWriteSingle(*Buffer++);
146 }
147
148 return Result;
149}
150
151UINTN
152EFIAPI
153SerialPortWriteSingle(
154 IN UINT8 Buffer
155)
156{
157 UINT8 Data;
158
159 //
160 // Wait for the serail port to be ready.
161 //
162 do {
163 Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET0x05);
164 } while ((Data & LSR_TXRDY0x20) == 0);
165 IoWrite8 ((UINT16) gUartBase, Buffer);
166 return 0;
167}
168
169
170/**
171 Reads data from a serial device into a buffer.
172
173 @param Buffer Pointer to the data buffer to store the data read from the serial device.
174 @param NumberOfBytes Number of bytes to read from the serial device.
175
176 @retval 0 NumberOfBytes is 0.
177 @retval >0 The number of bytes read from the serial device.
178 If this value is less than NumberOfBytes, then the read operation failed.
179
180**/
181UINTN
182EFIAPI
183SerialPortRead (
184 OUT UINT8 *Buffer,
185 IN UINTN NumberOfBytes
186)
187{
188 UINTN Result;
189 UINT8 Data;
190
191 if (NULL((void *) 0) == Buffer) {
192 return 0;
193 }
194
195 Result = NumberOfBytes;
196
197 while (NumberOfBytes--) {
198 //
199 // Wait for the serail port to be ready.
200 //
201 do {
202 Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET0x05);
203 } while ((Data & LSR_RXDA0x01) == 0);
204
205 *Buffer++ = IoRead8 ((UINT16) gUartBase);
206 }
207
208 return Result;
209}
210
211/**
212 Polls a serial device to see if there is any data waiting to be read.
213
214 Polls aserial device to see if there is any data waiting to be read.
215 If there is data waiting to be read from the serial device, then TRUE is returned.
216 If there is no data waiting to be read from the serial device, then FALSE is returned.
217
218 @retval TRUE Data is waiting to be read from the serial device.
219 @retval FALSE There is no data waiting to be read from the serial device.
220
221**/
222BOOLEAN
223EFIAPI
224SerialPortPoll (
225 VOIDvoid
226 )
227{
228 UINT8 Data;
229
230 //
231 // Read the serial port status.
232 //
233 Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET0x05);
234
235 return (BOOLEAN) ((Data & LSR_RXDA0x01) != 0);
236}
237