Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/28445
Change subject: lib/gpio.c: Fix _gpio_base3_value invalid shift ......................................................................
lib/gpio.c: Fix _gpio_base3_value invalid shift
In function _gpio_base3_value(), if gpio_num is 32 and gpio[31] is floating, the end result is 1 << 32, which does not fit into a int. To avoid a possible error, in this condition set value to 0xffffffff.
Add a comment explaining why and the work around.
BUG=b:113788440 TEST=Add a fake code to southbridge_final calling the function and printing the result. Build and boot grunt, check result.
Change-Id: I0b79725bcbaf120587c7440e176643aaa7a1d5bb Signed-off-by: Richard Spiegel richard.spiegel@silverbackltd.com --- M src/lib/gpio.c 1 file changed, 13 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/45/28445/1
diff --git a/src/lib/gpio.c b/src/lib/gpio.c index da74849..4549166 100644 --- a/src/lib/gpio.c +++ b/src/lib/gpio.c @@ -75,7 +75,7 @@ * internally pulled to. */
- static const char tristate_char[] = {[0] = '0', [1] = '1', [Z] = 'Z'}; + static const char tristate_char[] = {[0] = '0', [1] = '1', [2] = 'Z'}; uint32_t result = 0; int has_z = 0; int binary_below = 0; @@ -138,6 +138,14 @@ * '2' at 3^1: Add 2^(1+1) = 4 to account for binaries 1000-1011 * Stop adding for lower digits (3^0), all already accounted * now. We know that there can be no binary numbers 1020-102X. + * + * If gpio_num is 32 and gpio[31] is floating, the end result is + * 1 << 32, which does not fit into a int. To avoid a possible + * error, in this condition the value will be set to 0xffffffff. + * There's a second condition which would set this value, to + * have all inputs as 1. To differentiate between these results, + * the caller needs to test if gpio[31] is floating. If gpio_num + * is less than 32, no care is needed. */ if (binary_first && !has_z) { switch (temp) { @@ -147,7 +155,10 @@ binary_below += 1 << index; break; case 2: /* Account for binaries 0 to 2^(index+1) - 1. */ - binary_below += 1 << (index + 1); + if (index >= 31) + binary_below = 0xffffffff; + else + binary_below += 1 << (index + 1); has_z = 1; } }