Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion meta-facebook/gc2-es/src/ipmi/include/plat_ipmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
Expand All @@ -20,9 +20,19 @@
#include <stdbool.h>
#include <stdint.h>

#define IANA_SIZE 3
#define BITS_PER_BYTE 8

enum REQ_GET_CARD_TYPE {
GET_1OU_CARD_TYPE = 0x0,
GET_2OU_CARD_TYPE,
};

enum GPIO_CONFIG_SETTING_BIT {
GPIO_CONF_SET_DIR = 0, // 0: input, 1: output
GPIO_CONF_SET_INT, // 0: disable, 1 : enable
GPIO_CONF_SET_TRG_TYPE, // 0: edge, 1: level
GPIO_CONF_SET_TRG_EDGE, // 0: fall, 1: rise
GPIO_CONF_SET_TRG_BOTH // 1: both edge
};
#endif
141 changes: 133 additions & 8 deletions meta-facebook/gc2-es/src/ipmi/plat_ipmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
Expand All @@ -16,16 +16,17 @@

#include "plat_ipmi.h"

#include <stdio.h>
#include <stdlib.h>
#include <logging/log.h>
#include "libutil.h"
#include "ipmi.h"
#include "fru.h"
#include "eeprom.h"
#include "plat_fru.h"
#include "fru.h"
#include "hal_gpio.h"
#include "ipmi.h"
#include "libutil.h"
#include "plat_class.h"
#include "plat_fru.h"
#include "plat_ipmb.h"
#include <logging/log.h>
#include <stdio.h>
#include <stdlib.h>

LOG_MODULE_REGISTER(plat_ipmi);

Expand Down Expand Up @@ -138,3 +139,127 @@ void OEM_1S_GET_CARD_TYPE(ipmi_msg *msg)

return;
}

void OEM_1S_GET_GPIO_CONFIG(ipmi_msg *msg)
{
CHECK_NULL_ARG(msg);
if (msg->data_len == 0) {
msg->completion_code = CC_INVALID_LENGTH;
return;
}

uint8_t idx = 0;
uint8_t bitmap_len = msg->data_len;
uint8_t *gpio_bitmap = (uint8_t *)malloc(bitmap_len * sizeof(uint8_t));
if (gpio_bitmap == NULL) {
return;
}
memcpy(gpio_bitmap, &msg->data[0], bitmap_len);

for (uint8_t num = 0; num < gpio_ind_to_num_table_cnt; num++) {
if (num / BITS_PER_BYTE >= bitmap_len) {
break;
}

uint8_t byte = msg->data[num / BITS_PER_BYTE];
uint8_t pin_mask = (1 << (num % BITS_PER_BYTE));
if (!(byte & pin_mask)) {
continue;
}

uint8_t gpio_num = gpio_ind_to_num_table[num];
uint8_t cfg_byte = 0;

uint8_t dir = (uint8_t)gpio_get_direction(gpio_num);
cfg_byte |= (dir & 0x1u) << GPIO_CONF_SET_DIR;

uint8_t interrupt_en = gpio_get_reg_value(gpio_num, REG_INTERRUPT_ENABLE_OFFSET);
cfg_byte |= (interrupt_en & 0x1u) << GPIO_CONF_SET_INT;

uint8_t interrupt_type1 = gpio_get_reg_value(gpio_num, REG_INTERRUPT_TYPE1_OFFSET);
cfg_byte |= (interrupt_type1 & 0x1u) << GPIO_CONF_SET_TRG_TYPE;

uint8_t interrupt_type2 = gpio_get_reg_value(gpio_num, REG_INTERRUPT_TYPE2_OFFSET);
if (interrupt_type2) {
cfg_byte |= (interrupt_type2 & 0x1u) << GPIO_CONF_SET_TRG_BOTH;
} else {
uint8_t interrupt_type0 =
gpio_get_reg_value(gpio_num, REG_INTERRUPT_TYPE0_OFFSET);
cfg_byte |= (interrupt_type0 & 0x1u) << GPIO_CONF_SET_TRG_EDGE;
}

msg->data[idx++] = cfg_byte;
}
free(gpio_bitmap);
msg->data_len = idx;
msg->completion_code = CC_SUCCESS;
}

void OEM_1S_SET_GPIO_CONFIG(ipmi_msg *msg)
{
CHECK_NULL_ARG(msg);
uint8_t bitmap_len = (gpio_ind_to_num_table_cnt + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
if (msg->data_len < bitmap_len + 1) {
msg->completion_code = CC_INVALID_LENGTH;
msg->data_len = 0;
return;
}

uint8_t idx = bitmap_len;
for (uint8_t num = 0; num < gpio_ind_to_num_table_cnt; num++) {
if (num / BITS_PER_BYTE >= bitmap_len) {
break;
}

uint8_t byte = msg->data[num / BITS_PER_BYTE];
uint8_t pin_mask = (uint8_t)(1u << (num % BITS_PER_BYTE));
if (!(byte & pin_mask)) {
continue;
}

uint8_t cfg = msg->data[idx];
uint8_t gpio_num = gpio_ind_to_num_table[num];

if (gpio_cfg[gpio_num].is_init == DISABLE) {
msg->data_len = 0;
msg->completion_code = CC_INVALID_DATA_FIELD;
return;
}

if (cfg & BIT(GPIO_CONF_SET_DIR)) {
gpio_conf(gpio_num, GPIO_OUTPUT);
} else {
gpio_conf(gpio_num, GPIO_INPUT);
}

if (cfg & BIT(GPIO_CONF_SET_INT)) {
if (cfg & BIT(GPIO_CONF_SET_TRG_BOTH)) {
gpio_interrupt_conf(gpio_num, GPIO_INT_EDGE_BOTH);
} else {
if (cfg & BIT(GPIO_CONF_SET_TRG_TYPE)) {
// level
if (cfg & BIT(GPIO_CONF_SET_TRG_EDGE)) {
gpio_interrupt_conf(gpio_num, GPIO_INT_LEVEL_HIGH);
} else {
gpio_interrupt_conf(gpio_num, GPIO_INT_LEVEL_LOW);
}
} else {
// edge
if (cfg & BIT(GPIO_CONF_SET_TRG_EDGE)) {
gpio_interrupt_conf(gpio_num, GPIO_INT_EDGE_RISING);
} else {
gpio_interrupt_conf(gpio_num,
GPIO_INT_EDGE_FALLING);
}
}
}
} else {
gpio_interrupt_conf(gpio_num, GPIO_INT_DISABLE);
}

idx++;
}

msg->data_len = 0;
msg->completion_code = CC_SUCCESS;
}