/** * Check if graceful shutdown is finished * * check if board is in S3 state, or if there occurred a timeout * * \return * -#E_OK started successful */ unsigned char graceful_shutdown_finished(void) { /* check if processor is in S3 */ if (signal_read(&sig_shutdown_s3)) { signal_deactivate(&sig_payload_pw_button); debug_uart_printf(DBG_GRP_PAYLOAD, 2, "graceful shutdown processor in S3\n"); gsd_finished = 1; gsd_active = 0; /* clear sleep sticky interrupt bits */ signal_int_clear(&sig_sleep_s3); signal_int_clear(&sig_sleep_s4); signal_int_clear(&sig_sleep_s5); } if (gp_timer_once(&gsd_timeout)) { signal_deactivate(&sig_payload_pw_button); debug_uart_printf(DBG_GRP_PAYLOAD, 2, "graceful shutdown timeout\n"); #ifdef ADV_OEM_INTEGRITY_SENSOR sensor_integrity_send_event(IS_BMC_FW, IS_ACTION_GRACE_SHUTDOWN, IS_TIMEOUT); #endif gsd_finished = 1; gsd_active = 0; } return E_OK; }
/** * Print DIMM configuration */ void spd_print_dimm_presence(void) { unsigned char i, reading; /* walk through all dimms */ for (i = 0; i < SDRAM_MAX_DIMMS; i++) { uart_printf("DDR3 DIMM %d: ", i + 1); /* if payload power is not active - read out SPD EEPROM's */ if (!signal_read(&sig_payload_power)) { /* try to read DIMM SPD register */ if (spd_read_register(i, SDRAM_SPD_REVISION, &reading) == E_OK) { /* get memory size */ spd_get_memory_values(i); } } /* if memory size value not zero */ if (ddr_modules[i].populated != 0) { uart_printf("%d MB ", ddr_modules[i].value); uart_printf(" Type: %d\n", ddr_modules[i].voltage); } else { uart_printf("not populated\n"); } } }
/** * Switch bios flash * * \return active bios flash */ unsigned char bios_switch_flash(void) { unsigned char bios_flash; /* payload is on, or nvram copy running */ if (signal_read(&sig_payload_power) || helper_task_get_bios_redundancy_status()) { debug_uart_printf(DBG_GRP_FRU, 2, "in progress: %x\n", helper_task_get_bios_redundancy_status()); return E_FAILURE; } /* read active version */ bios_flash = bios_get_active_flash(); /* switch to inactive version */ if (bios_flash == BIOS_SELECT_0) { bios_set_active_flash(BIOS_SELECT_1); } else { bios_set_active_flash(BIOS_SELECT_0); } return E_OK; }
void bmc_oem_get_boot_bank (ipmbMSG_t *rq, ipmbMSG_t *rs) { unsigned char curr_bank = 0; if(rq->data_len != 3) { rs->data[0] = CC_REQ_DATALEN_INVALID; rs->data_len = 1; return; } if(check_iana(rq,rs)) { return; } rs->data_len = 5; rs->data[0] = CC_COMPLETED_NORMALLY; curr_bank = signal_read(&sig_norflash_sel); if( oem_config.payload_flash_sel == curr_bank ) rs->data[4] = FALSE; // FALSE = NO Switch to Backup = Main bank else rs->data[4] = TRUE; // TRUE = Switched to Backup = Backup bank }
/** * read proc hot status * * \return status code */ unsigned char sensor_proc_hot_get(sdr_data_t *sdr) { unsigned char data = 0; sdr->data[0] = 0x00; sdr->data[2] = 0x00; sdr->data[3] = 0x00; /* read proc hot signals */ data |= signal_read(&sig_proc_hot[0]); data |= (signal_read(&sig_proc_hot[1]) << 1); /* write proc hot state to sensor */ sdr->data[3] = data; return E_OK; }
/** * read vr hot status * * \return status code */ unsigned char sensor_vr_hot_get(sdr_data_t *sdr) { unsigned char data = 0; sdr->data[0] = 0; sdr->data[2] = 0; sdr->data[3] = 0; /* read vrhot signals */ #ifdef CFG_DUAL_CPU data |= signal_read(&sig_vr_hot[0]); data |= (signal_read(&sig_vr_hot[1]) << 1); #else data |= signal_read(&sig_vr_hot); #endif /* write vrhot state to sensor */ sdr->data[3] = data; return E_OK; }
/** * get active bios flash from fpga register * * \return active bios 0 - 1 */ unsigned char bios_get_active_flash(void) { /* send back active bios */ if (signal_read(&sig_bios_select)) { return BIOS_SELECT_1; } else { return BIOS_SELECT_0; } }
/** * enable/disable IPMB0-A/B bus buffer when bus is free */ unsigned char ipmb0_bus_ctrl(unsigned char bus, unsigned char control) { /* enable is always allowed */ if (control == IPMB_ENABLE) { /* activate buffers */ signal_activate(&sig_ipmb0en[bus]); } /* control is disable */ else { /* check for isolation of both busses */ if (bus == IPMB0_A) { /* is IPMB0-B enabled? */ if (!(signal_read(&sig_ipmb0en[IPMB0_B]))) { /* do not deactivate bus A */ return E_INVALID; } } else { /* is IPMB0-A enabled? */ if (!(signal_read(&sig_ipmb0en[IPMB0_A]))) { /* do not deactivate bus A */ return E_INVALID; } } /* deactivate buffers */ signal_deactivate(&sig_ipmb0en[bus]); } return E_OK; }
/** * Read the current value of the GPIO sensor * * \param data pointer to data structure to write data to * \return status code */ unsigned char sensor_gpio_get_local(unsigned char signum, sdr_data_t *data) { if (data == NULL) { return E_FAILURE; } /* write current state to data structure */ data->data[0] = 0x00; /* sensor reading = 0x00 */ data->data[1] = 0x00; /* NOTE: will be modified by calling function */ data->data[2] = (1 << signal_read(&sensor_gpio_signal)); data->data[3] = 0x00; return E_OK; } /* int sensor_gpio_get */
unsigned char graceful_shutdown_finished(void) { /* check if processor is in S3 */ if(signal_read(&sig_payload_isdown)) { signal_deactivate(&sig_payload_shutdown); GSD_DEBUG_PRINTF((DEBUG_UART,"processor in S3\n")); return E_TRUE; } /* check if timeout is exceeded */ if(global_data.timer > fru_info.timeout) { signal_deactivate(&sig_payload_shutdown); GSD_DEBUG_PRINTF((DEBUG_UART,"graceful shutdown timeout\n")); return E_TRUE; } return E_OK; }
/** * read therm trip status * * \return status code */ unsigned char sensor_therm_trip_get(sdr_data_t *sdr) { sdr->data[0] = 0x00; sdr->data[2] = 0x00; sdr->data[3] = 0x00; /* read therm trip and mem hot signals and write states to sensor */ sdr->data[3] |= signal_read(&sig_therm_trip[0]); sdr->data[3] |= (signal_read(&sig_therm_trip[1]) << 1); sdr->data[3] |= (signal_read(&sig_mem_hot[0]) << 2); sdr->data[3] |= (signal_read(&sig_mem_hot[1]) << 3); sdr->data[3] |= (signal_read(&sig_mem_hot[2]) << 4); sdr->data[3] |= (signal_read(&sig_mem_hot[3]) << 5); return E_OK; }
/** * Perform a fallback to the default nvram settings * at next payload reboot * * \return active bios flash */ unsigned char bios_load_nvram_defaults(void) { /* set fpga register bit, to load nvram defaults */ signal_activate(&sig_cmos_soft_reset); debug_uart_printf(DBG_GRP_FRU, 2, "Load NVRAM defaults at following boot\n"); /* only allow rtc reset, when payload is off */ /* this if part of the implementation is only needed for backwards compatibility */ if (!signal_read(&sig_payload_power)) { /* set cmos clear */ signal_activate(&sig_cmos_clear); /* wait for 5 ms */ util_wait_ms(5); /* reset cmos clear */ signal_deactivate(&sig_cmos_clear); } return E_OK; }
/** * Read the current value of the Module hot swap sensor * * \param sensor pointer to sensor-specific control values * \param data pointer to data structure to write data to * \return status code */ unsigned char sensor_mod_hotswap_get_dev(sdr_data_t *data) { unsigned char state = 0; /* check SDR data pointer */ if (data == NULL) { return E_FAILURE; } /* check hot swap handle signal status */ if (!signal_read(&sig_hs_handle)) { state = SENSOR_MOD_HOTSWAP_ST_HANDLE_OPENED; } else { state = SENSOR_MOD_HOTSWAP_ST_HANDLE_CLOSED; } /* AMC module quiesced hot swap event ready? */ #ifdef CFG_IRTM if (irtm_get_fru_ctrl_quiesce_state()) #else if (amc_get_fru_ctrl_quiesce_state()) #endif { state = SENSOR_MOD_HOTSWAP_ST_QUIESCED; } data->data[0] = 0x00; data->data[2] = SENSOR_SSO(state); data->data[3] = SENSOR_EVT(0x80); return E_OK; }
/* This state machine is based on the one from udhcpc written by Russ Dill */ int dhcp_run (options_t *options) { interface_t *iface; int mode = SOCKET_CLOSED; int state = STATE_INIT; struct timeval tv; int xid = 0; long timeout = 0; fd_set rset; int maxfd; int retval; dhcpmessage_t message; dhcp_t *dhcp; int type = DHCP_DISCOVER; int last_type = DHCP_DISCOVER; bool daemonised = false; unsigned long start = 0; unsigned long last_send = 0; int sig; unsigned char *buffer = NULL; int buffer_len = 0; int buffer_pos = 0; if (! options || (iface = (read_interface (options->interface, options->metric))) == NULL) return -1; /* Remove all existing addresses. After all, we ARE a DHCP client whose job it is to configure the interface. We only do this on start, so persistent addresses can be added afterwards by the user if needed. */ flush_addresses (iface->name); dhcp = xmalloc (sizeof (dhcp_t)); memset (dhcp, 0, sizeof (dhcp_t)); strcpy (dhcp->classid, options->classid); if (options->clientid[0]) strcpy (dhcp->clientid, options->clientid); else sprintf (dhcp->clientid, "%s", ether_ntoa (&iface->ethernet_address)); if (options->requestaddress.s_addr != 0) dhcp->address.s_addr = options->requestaddress.s_addr; signal_setup (); while (1) { if (timeout > 0 || (options->timeout == 0 && (state != STATE_INIT || xid))) { if (options->timeout == 0 || dhcp->leasetime == -1) { logger (LOG_DEBUG, "waiting on select for infinity"); maxfd = signal_fd_set (&rset, iface->fd); retval = select (maxfd + 1, &rset, NULL, NULL, NULL); } else { /* Resend our message if we're getting loads of packets that aren't for us. This mainly happens on Linux as it doesn't have a nice BPF filter. */ if (iface->fd > -1 && uptime () - last_send >= TIMEOUT_MINI) SEND_MESSAGE (last_type); logger (LOG_DEBUG, "waiting on select for %d seconds", timeout); /* If we're waiting for a reply, then we re-send the last DHCP request periodically in-case of a bad line */ retval = 0; while (timeout > 0 && retval == 0) { if (iface->fd == -1) tv.tv_sec = SELECT_MAX; else tv.tv_sec = TIMEOUT_MINI; if (timeout < tv.tv_sec) tv.tv_sec = timeout; tv.tv_usec = 0; start = uptime (); maxfd = signal_fd_set (&rset, iface->fd); retval = select (maxfd + 1, &rset, NULL, NULL, &tv); timeout -= uptime () - start; if (retval == 0 && iface->fd != -1 && timeout > 0) SEND_MESSAGE (last_type); } } } else retval = 0; /* We should always handle our signals first */ if (retval > 0 && (sig = signal_read (&rset))) { switch (sig) { case SIGINT: logger (LOG_INFO, "receieved SIGINT, stopping"); retval = 0; goto eexit; case SIGTERM: logger (LOG_INFO, "receieved SIGTERM, stopping"); retval = 0; goto eexit; case SIGALRM: logger (LOG_INFO, "receieved SIGALRM, renewing lease"); switch (state) { case STATE_BOUND: case STATE_RENEWING: case STATE_REBINDING: state = STATE_RENEW_REQUESTED; break; case STATE_RENEW_REQUESTED: case STATE_REQUESTING: case STATE_RELEASED: state = STATE_INIT; break; } timeout = 0; xid = 0; break; case SIGHUP: if (state == STATE_BOUND || state == STATE_RENEWING || state == STATE_REBINDING) { logger (LOG_INFO, "received SIGHUP, releasing lease"); SOCKET_MODE (SOCKET_OPEN); xid = random_xid (); if ((open_socket (iface, false)) >= 0) SEND_MESSAGE (DHCP_RELEASE); SOCKET_MODE (SOCKET_CLOSED); unlink (iface->infofile); } else logger (LOG_ERR, "receieved SIGUP, but no we have lease to release"); retval = 0; goto eexit; default: logger (LOG_ERR, "received signal %d, but don't know what to do with it", sig); } } else if (retval == 0) /* timed out */ { switch (state) { case STATE_INIT: if (iface->previous_address.s_addr != 0) { logger (LOG_ERR, "lost lease"); xid = 0; SOCKET_MODE (SOCKET_CLOSED); if (! options->persistent) { free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp_t)); configure (options, iface, dhcp); } if (! daemonised) { retval = -1; goto eexit; } break; } if (xid == 0) xid = random_xid (); else { logger (LOG_ERR, "timed out"); if (! daemonised) { retval = -1; goto eexit; } } SOCKET_MODE (SOCKET_OPEN); timeout = options->timeout; iface->start_uptime = uptime (); if (dhcp->address.s_addr == 0) { logger (LOG_INFO, "broadcasting for a lease"); SEND_MESSAGE (DHCP_DISCOVER); } else { logger (LOG_INFO, "broadcasting for a lease of %s", inet_ntoa (dhcp->address)); SEND_MESSAGE (DHCP_REQUEST); state = STATE_REQUESTING; } break; case STATE_BOUND: case STATE_RENEW_REQUESTED: state = STATE_RENEWING; xid = random_xid (); case STATE_RENEWING: iface->start_uptime = uptime (); logger (LOG_INFO, "renewing lease of %s", inet_ntoa (dhcp->address)); SOCKET_MODE (SOCKET_OPEN); SEND_MESSAGE (DHCP_REQUEST); timeout = dhcp->rebindtime - dhcp->renewaltime; state = STATE_REBINDING; break; case STATE_REBINDING: logger (LOG_ERR, "lost lease, attemping to rebind"); SOCKET_MODE (SOCKET_OPEN); SEND_MESSAGE (DHCP_DISCOVER); timeout = dhcp->leasetime - dhcp->rebindtime; state = STATE_INIT; break; case STATE_REQUESTING: logger (LOG_ERR, "timed out"); if (! daemonised) goto eexit; state = STATE_INIT; SOCKET_MODE (SOCKET_CLOSED); timeout = 0; xid = 0; free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp_t)); break; case STATE_RELEASED: dhcp->leasetime = -1; break; } } else if (retval > 0 && mode != SOCKET_CLOSED && FD_ISSET(iface->fd, &rset)) { /* Allocate our buffer space for BPF. We cannot do this until we have opened our socket as we don't know how much of a buffer we need until then. */ if (! buffer) buffer = xmalloc (iface->buffer_length); buffer_len = iface->buffer_length; buffer_pos = -1; /* We loop through until our buffer is empty. The benefit is that if we get >1 DHCP packet in our buffer and the first one fails for any reason, we can use the next. */ memset (&message, 0, sizeof (struct dhcpmessage_t)); int valid = 0; struct dhcp_t *new_dhcp; new_dhcp = xmalloc (sizeof (dhcp_t)); while (buffer_pos != 0) { if (get_packet (iface, (unsigned char *) &message, buffer, &buffer_len, &buffer_pos) < 0) break; if (xid != message.xid) { logger (LOG_ERR, "ignoring packet with xid %d as it's not ours (%d)", message.xid, xid); continue; } logger (LOG_DEBUG, "got a packet with xid %d", message.xid); memset (new_dhcp, 0, sizeof (dhcp_t)); if ((type = parse_dhcpmessage (new_dhcp, &message)) < 0) { logger (LOG_ERR, "failed to parse packet"); free_dhcp (new_dhcp); continue; } /* If we got here then the DHCP packet is valid and appears to be for us, so let's clear the buffer as we don't care about any more DHCP packets at this point. */ valid = 1; break; } /* No packets for us, so wait until we get one */ if (! valid) { free (new_dhcp); continue; } /* new_dhcp is now our master DHCP message */ free_dhcp (dhcp); free (dhcp); dhcp = new_dhcp; new_dhcp = NULL; /* We should restart on a NAK */ if (type == DHCP_NAK) { logger (LOG_INFO, "received NAK: %s", dhcp->message); state = STATE_INIT; timeout = 0; xid = 0; free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp_t)); configure (options, iface, dhcp); continue; } switch (state) { case STATE_INIT: if (type == DHCP_OFFER) { logger (LOG_INFO, "offered lease of %s", inet_ntoa (dhcp->address)); SEND_MESSAGE (DHCP_REQUEST); state = STATE_REQUESTING; } break; case STATE_RENEW_REQUESTED: case STATE_REQUESTING: case STATE_RENEWING: case STATE_REBINDING: if (type == DHCP_ACK) { SOCKET_MODE (SOCKET_CLOSED); if (options->doarp && iface->previous_address.s_addr != dhcp->address.s_addr) { if (arp_check (iface, dhcp->address)) { SOCKET_MODE (SOCKET_OPEN); SEND_MESSAGE (DHCP_DECLINE); SOCKET_MODE (SOCKET_CLOSED); free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp)); if (daemonised) configure (options, iface, dhcp); xid = 0; state = STATE_INIT; /* RFC 2131 says that we should wait for 10 seconds before doing anything else */ sleep (10); continue; } } if (! dhcp->leasetime) { dhcp->leasetime = DEFAULT_TIMEOUT; logger(LOG_INFO, "no lease time supplied, assuming %d seconds", dhcp->leasetime); } if (! dhcp->renewaltime) { dhcp->renewaltime = dhcp->leasetime / 2; logger (LOG_INFO, "no renewal time supplied, assuming %d seconds", dhcp->renewaltime); } if (! dhcp->rebindtime) { dhcp->rebindtime = (dhcp->leasetime * 0x7) >> 3; logger (LOG_INFO, "no rebind time supplied, assuming %d seconds", dhcp->rebindtime); } if (dhcp->leasetime == -1) logger (LOG_INFO, "leased %s for infinity", inet_ntoa (dhcp->address)); else logger (LOG_INFO, "leased %s for %u seconds", inet_ntoa (dhcp->address), dhcp->leasetime, dhcp->renewaltime); state = STATE_BOUND; timeout = dhcp->renewaltime; xid = 0; if (configure (options, iface, dhcp) < 0 && ! daemonised) { retval = -1; goto eexit; } if (! daemonised) { if ((daemonise (options->pidfile)) < 0 ) { retval = -1; goto eexit; } daemonised = true; } } else if (type == DHCP_OFFER) logger (LOG_INFO, "got subsequent offer of %s, ignoring ", inet_ntoa (dhcp->address)); else logger (LOG_ERR, "no idea what to do with DHCP type %d at this point", type); break; }
/** * BMC watchdog timer interrupt service routine */ void bmc_isr_wd_timer(void) { unsigned short pre_timer; #ifdef CFG_SENSOR_BOOT_ERROR sdr_data_t reading_data; unsigned short sensor_data; #endif /* the watchdog timer is running with 100ms */ wd_timer.present_count--; /* check only pre-timeout actions */ if (wd_timer.timer_action & 0x70) { if (wd_timer.pre_timeout) { pre_timer = wd_timer.present_count; /* the pre-timeout timer is runnung with 1000ms */ /* pre-timeout timer expired */ if ((wd_timer.pre_timeout * 10) == pre_timer) { wd_timer.pretimeout_flag |= IPMB_WD_PRETO_FLAG; if (wd_timer.timer_action & WD_PRETIMER_ACT_NMI) { bmc_oem_set_diag_int_reason (DIAG_INT_REASON_WATCHDOG, FALSE); custom_payload_ctrl_send_cmd_from_ISR(PAYLOAD_CTRL_CMD_DIAG_INT); } if (!(wd_timer.timer_use & WD_TIMER_USE_DONT_LOG)) { #ifdef CFG_SENSOR_BMCWDT #ifdef CFG_CPCI8220 sensor_bmcwdt_set_state(WD_TIMER_ACT_TIMER_INT, (wd_timer.timer_action & 0x70) | (wd_timer.timer_use & 0x07)); #else sensor_bmcwdt_set_state(wd_timer.timer_action & 0x07, (wd_timer.timer_use & 0x07)|0xF0); #endif #endif } } } } /* timer expired? */ if (wd_timer.present_count == 0) { /* timer expired */ wd_timer.timer_use_flag |= (1 << (wd_timer.timer_use & 0x7)); /* stop timer */ watchdog_stop(); /* timer control register bit0 = 0 -> disable timer */ wd_timer.timer_use &= ~WD_TIMER_START; if ((wd_timer.timer_action & 0x07) == WD_TIMER_ACT_HARD_RESET) { #ifdef CFG_CPCI debug_uart_printf(DBG_GRP_WDT, 1,"BMC Watchdog: Reset Payload\n"); /* TODO wdt reset payload */ switch (wd_timer.timer_use & 0x07) { case WD_TIMER_USE_RSV_IWD: { unsigned char curr_bank = 0; curr_bank = signal_read(&sig_norflash_sel); if(oem_config.payload_flash_sel == curr_bank) { sensor_bmcwdt_set_state(WD_TIMER_ACT_HARD_RESET, (wd_timer.timer_use & 0x07)|0xF0); custom_payload_ctrl_send_cmd_from_ISR(PAYLOAD_CTRL_CMD_INITIAL_WATCHDOG_COLD_RESET); } else { wd_timer.timer_action = WD_TIMER_ACT_PWR_DOWN; #ifdef CFG_SENSOR_BOOT_ERROR sensor_boot_error_state_get( &reading_data ); sensor_data = reading_data.data[2] + (reading_data.data[3]<<8); if( !(sensor_data & (1 << BOOT_ERR_SEC_BANK_BOOT_FAIL)) ) { sensor_boot_error_state_set(BOOT_ERR_SEC_BANK_BOOT_FAIL); } #endif } } break; default: custom_payload_ctrl_send_cmd_from_ISR(PAYLOAD_CTRL_CMD_WATCHDOG_COLD_RESET); break; } debug_uart_printf(DBG_GRP_WDT, 1, "BMC Watchdog: Timer Use = 0x%02X\n", wd_timer.timer_use); #else /* #ifdef CFG_CPCI */ if ((wd_timer.timer_use & 0x07) == WD_TIMER_USE_BIOS_FRB2) { debug_uart_printf(DBG_GRP_WDT, 1, "Watchdog timeout\n"); #ifdef CFG_HPM1_BIOS_UPDATE bios_redundancy_handle_watchdog_timeout(); /* restart watchdog timer only if payload power is on */ if (signal_read(&sig_payload_power)) { watchdog_start(); wd_timer.present_count = CFG_BIOS_TIMEOUT; /* timer control register bit0 = 0 -> enable timer */ wd_timer.timer_use |= WD_TIMER_START; } #endif } else { /* if payload power is on */ if (signal_read(&sig_payload_power)) { #ifdef CFG_CM signal_activate(&sig_payload_keep_enabled); #endif /* perform payload power cycle */ signal_deactivate(&sig_payload_power); signal_activate(&sig_payload_power); #ifdef CFG_CM signal_deactivate(&sig_payload_keep_enabled); #endif } } #endif /* #ifdef CFG_CPCI */ #ifdef CFG_X86 sensor_nuvoton_reset_peci(); #endif } if ((wd_timer.timer_action & 0x07) == WD_TIMER_ACT_PWR_DOWN) { /* power down */ #ifdef CFG_CPCI custom_payload_ctrl_send_cmd_from_ISR(PAYLOAD_CTRL_CMD_POWEROFF); #else signal_deactivate(&sig_payload_power); #endif debug_uart_printf(DBG_GRP_WDT, 1, "BMC Watchdog: Turn Off Payload\n"); } if ((wd_timer.timer_action & 0x07) == WD_TIMER_ACT_PWR_CYCLE) { /* if payload power is on */ if (signal_read(&sig_payload_power)) { #ifdef CFG_CM signal_activate(&sig_payload_keep_enabled); #endif /* perform payload power cycle */ #ifdef CFG_CPCI custom_payload_ctrl_send_cmd_from_ISR(PAYLOAD_CTRL_CMD_POWEROFF); custom_payload_ctrl_send_cmd_from_ISR(PAYLOAD_CTRL_CMD_POWERON); #else signal_deactivate(&sig_payload_power); signal_activate(&sig_payload_power); #endif /* #ifdef CFG_CPCI */ #ifdef CFG_CM signal_deactivate(&sig_payload_keep_enabled); #endif } debug_uart_printf(DBG_GRP_WDT, 1, "BMC Watchdog: Power Cycle Payload\n"); } if (!(wd_timer.timer_use & WD_TIMER_USE_DONT_LOG)) { #ifdef CFG_SENSOR_BMCWDT #ifdef CFG_CPCI if ((wd_timer.timer_use & 0x07) != WD_TIMER_USE_RSV_IWD) { sensor_bmcwdt_set_state(wd_timer.timer_action & 0x07, (wd_timer.timer_use & 0x07)|0xF0); } #else sensor_bmcwdt_set_state(wd_timer.timer_action & 0x07, (wd_timer.timer_use & 0x07)|0xF0); #endif #endif } else { /* clear do not log bit if timer expired, see IPMI 2.0 27.3 */ wd_timer.timer_use &= ~WD_TIMER_USE_DONT_LOG; } } }
/** * Task to send and receive IPMB messages over IPMB0-A and B to/from backplane. * * Every IPMI message is handled in a seperate ISR for IPMB0-A or IPMB0-B. * Received messages from the backplane regardless of source (IPMB0-A or * IPMB0-B) are put into the global queue ipmb0_recv_queue in the MCMC * internal used IPMB format. IPMB messages to the backplane are send * alternating to IPMB0-A and IPMB0-B. Task/Queue wait time calculation: * a 10 byte message is handled within 1ms on 100kHz i2c bus */ void ipmb0_i2c_task(void *pvParameters) { ipmbMSG_t *message; /* alternate Flag: 1 == IPMB0-A and 2 == IPMB0-B */ static int ipmb0_tx_bus = IPMB0_B; /* alternate Flag: 1 == IPMB0-A and 2 == IPMB0-B */ static int ipmb0_rx_bus = IPMB0_A; unsigned long timeout; struct gp_timer timer_bus_fault_retry; while (1) { #ifdef CFG_DEBUG_PERFORMANCE perf_ipmb0_task_stack = uxTaskGetStackHighWaterMark(NULL); unsigned char perf_temp; perf_temp = uxQueueMessagesWaiting(ipmb0_rx_queue); if (perf_temp > perf_ipmb0_rx_waiting) perf_ipmb0_rx_waiting = perf_temp; #endif /* re-enable i2c buffer to retry communication */ if (gp_timer_once(&timer_bus_fault_retry)) { /* reenable buffer just in local control mode */ if ((ipmb_control & (1 << IPMB0_A)) == 0) { signal_activate(&sig_ipmb0en[IPMB0_A]); } if ((ipmb_control & (1 << IPMB0_B)) == 0) { signal_activate(&sig_ipmb0en[IPMB0_B]); } } /* get new message from ipmb0_rx_queue if last message has been sent */ if (get_new_ipmb0_message == IPMB_TX_BUFFER_FREE) { /* poll ipmb0_rx_queue for message, don't block */ if (xQueueReceive(ipmb0_rx_queue, &message, QUEUE_BLOCK_NONE)) { /* convert and copy the internal IPMI message to IPMB format */ ipmb0_tx.length = convert_msg_to_ipmb(ipmb0_tx.buffer, message); if (!ipmb0_tx.length) /* error */ { /* print error message */ debug_uart_printf(DBG_GRP_IPMB0, 2, "ERR: %s: Invalid length in IPMB message.\n", __func__); } else { /* set TX buffer busy flag */ get_new_ipmb0_message = IPMB_TX_BUFFER_FULL; timeout = xTaskGetTickCount(); retrycnt = 0; } /* free message buffer */ msg_free(message); } } /* we have lost arbitration, repeat message */ if (get_new_ipmb0_message == IPMB_TX_BUFFER_REPEAT) { debug_uart_printf(DBG_GRP_IPMB0, 2, "%s: Arbitration lost, repeating.\n", __func__); /* check if bus is free and repeat */ if ((ipmb0_flag[IPMB0_A] == I2C_FREE) && (ipmb0_flag[IPMB0_B] == I2C_FREE)) { timeout = 0; /* resend message */ get_new_ipmb0_message = IPMB_TX_BUFFER_FULL; timeout = xTaskGetTickCount(); } } /* send message if there is one to be sent */ if ((get_new_ipmb0_message == IPMB_TX_BUFFER_FULL) && (((ipmb0_flag[IPMB0_A] == I2C_FREE) && (ipmb0_flag[IPMB0_B] != I2C_MASTER_WR)) || ((ipmb0_flag[IPMB0_A] != I2C_MASTER_WR) && (ipmb0_flag[IPMB0_B] == I2C_FREE)))) { /* PICMG REQ 3.546 IPM Controllers should alternate * transmission of messages on all enabled IPMBs */ if (ipmb0_tx_bus == IPMB0_A && signal_read(&sig_ipmb0en[IPMB0_B])) { ipmb0_tx_bus = IPMB0_B; } else if (ipmb0_tx_bus == IPMB0_B && signal_read(&sig_ipmb0en[IPMB0_A])) { ipmb0_tx_bus = IPMB0_A; } debug_uart_printf(DBG_GRP_IPMB0, 1, "<- IPMB-0%c: [", (ipmb0_tx_bus == IPMB0_A) ? 'A' : 'B'); for (int i = 0; i < ipmb0_tx.length; i++) { debug_uart_printf(DBG_GRP_IPMB0, 1, "%02X", ipmb0_tx.buffer[i]); if (i != ipmb0_tx.length - 1) { debug_uart_printf(DBG_GRP_IPMB0, 1, " "); } } debug_uart_printf(DBG_GRP_IPMB0, 1, "]\n"); /* IPMB0-A: Send if previous message has been sent and no slave RX */ { /* Trigger sending IPMI message on IPMB0-A/B with START Flag on I2C-1/2 */ retrycnt++; ipmb0_flag[ipmb0_tx_bus] = I2C_MASTER_WR; if (ipmb0_tx_bus == IPMB0_A) { IPMB0A_I2CCONSET = STA; } else { /* ipmb0_tx_bus == IPMB0_B */ IPMB0B_I2CCONSET = STA; } } } else if (get_new_ipmb0_message == IPMB_TX_BUFFER_FULL) { if ((xTaskGetTickCount() - timeout) > I2C_ACK_TIMEOUT_TICKS) { /* no ack received, device not available */ /* abort transmission and discard message */ if (ipmb0_flag[0] == I2C_MASTER_WR) { IPMB0A_I2CCONSET = STO | AA; debug_uart_printf(DBG_GRP_IPMB0, 2, "ERR: %s: Time out on IPMB0-A.\n", __func__); /* disable buffer */ signal_deactivate(&sig_ipmb0en[IPMB0_A]); } if (ipmb0_flag[1] == I2C_MASTER_WR) { IPMB0B_I2CCONSET = STO | AA; debug_uart_printf(DBG_GRP_IPMB0, 2, "ERR: %s: Time out on IPMB0-B.\n", __func__); /* disable buffer */ signal_deactivate(&sig_ipmb0en[IPMB0_B]); } /* schedule buffer retry in 5 seconds */ gp_timer_start(&timer_bus_fault_retry, 5000); ipmb0_flag[0] = I2C_FREE; ipmb0_flag[1] = I2C_FREE; get_new_ipmb0_message = IPMB_TX_BUFFER_FREE; /* discard message */ timeout = 0; } } /* handle received IPMB0 messages if available */ /* alternate TX channels */ if (ipmb0_rx_bus == IPMB0_A) ipmb0_rx_bus = IPMB0_B; else ipmb0_rx_bus = IPMB0_A; /* handle IPMB0-A and IPMB0-B */ { while (ipmb0_rx_list[ipmb0_rx_bus].read_pos != ipmb0_rx_list[ipmb0_rx_bus].write_pos) { if (ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].status == IPMB_RX_BUF_FILLED) { /* allocate free message from global buffer */ if (!(message = msg_malloc())) { /* error */ uart_printf("ERR: %s: Could not msg_malloc() for message.\n", __func__); } else { /* convert IPMB message to internal IPMI format */ if (convert_ipmb_to_msg(ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].buffer, ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].length, message, global_data.bmc_ipmb_addr) != E_FAILURE) { /* forward message to the message hub */ if (xQueueSend(msg_hub_rx_queue, &message, QUEUE_BLOCK_10) != pdPASS) { /* queue size to small, change this */ uart_printf("ERR: %s: msg_hub_rx_queue full\n", __func__); /* set error flag */ mon_queues |= MON_QUEUE_MSG_HUB_RX; /* and discard message */ msg_free(message); } debug_uart_printf(DBG_GRP_IPMB0, 1, "-> IPMB-0%c: [%02X ", ipmb0_rx_bus ? 'B' : 'A', global_data.bmc_ipmb_addr); for (int i = 0; i < ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].length; i++) { debug_uart_printf(DBG_GRP_IPMB0, 1, "%02X", ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].buffer[i]); if (i != ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].length - 1) { debug_uart_printf(DBG_GRP_IPMB0, 1, " "); } } debug_uart_printf(DBG_GRP_IPMB0, 1, "]\n"); } else { /* if message error discard message */ msg_free(message); debug_uart_printf(DBG_GRP_IPMB0, 1, "ERR: %s: IPMB0 RX message error.\n", __func__); } } } /* free message buffer and go to the next in list */ ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].status = IPMB_RX_BUF_EMPTY; ipmb0_rx_list[ipmb0_rx_bus].entry[ipmb0_rx_list[ipmb0_rx_bus].read_pos].length = 0; ipmb0_rx_list[ipmb0_rx_bus].read_pos = (ipmb0_rx_list[ipmb0_rx_bus].read_pos + 1) % IPMB0_RX_LIST_ENTRIES; } } /* block task for some ticks if queue is empty */ if (uxQueueMessagesWaiting(ipmb0_rx_queue) == 0) vTaskDelay((portTickType) IPMB_I2C_TASK_WAIT_TICKS); } /* while (1) never ends */ }
/** * This function handles the OEM command to read a specific configuration * from the EEPROM * * \param rq request message * \param rs reponse message */ void bmc_oem_read_config_setting(ipmbMSG_t *rq, ipmbMSG_t *rs) { /* Device * Port * SATA FLASH: 0x02 * - WRITE PROTECT 0x00 * BIOS FLASH: 0x03 * - IMAGE SEL 0x00 * - NVRAM SEL 0x01 * - NVRAM ACT 0x02 * LAN CONTROLLER: 0x04 * - INTERFACE 0x00 * - CHANNEL PRIO 0x01 * RTC: 0x07 * - SYNC 0x00 * FPGA: 0x08 * - COM1 MUX 0x00 * - COM2 MUX 0x01 * - IPMC MUX 0x02 * PCIE: 0x0B * - RTM 0x00 * - FMM 0x01 * CLI: 0x0C * - UART BAUDRATE 0x00 * - UART ENABLE 0x01 * IRQ: 0x0D * - PROC HOT 0x00 * TIMER: 0x0E * - CM TIMEOUT 0x00 * - GF TIMEOUT 0x01 */ /* check for valid iana and fill iana in response */ if (check_iana(rq, rs)) { /* invalid request */ return; } /* check if request length is valid */ else if (rq->data_len != 5) { rs->data[0] = CC_REQ_DATALEN_INVALID; return; } /* IANA valid */ else { rs->data[0] = CC_COMPLETED_NORMALLY; rs->data_len = 5; /* switch depending to setting */ switch (rq->data[3]) { #ifdef CFG_SATA_FLASH case SETTING_SATA_FLASH_WP: switch (rq->data[4]) { case PORT_SATA_FLASH_1: /* read sata flash wp */ rs->data[4] = signal_read(&sig_sata_wp); break; default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #endif /* CFG_SATA_FLASH */ #ifdef CFG_BIOS_FLASH case SETTING_BIOS: switch (rq->data[4]) { case PORT_BIOS_SELECT: rs->data[4] = bios_get_active_flash(); break; #ifdef CFG_HPM1_BIOS_SETTING_UPDATE case PORT_NVRAM_ACTIVATE_SELECT: rs->data[4] = oem_config.activate_nvram; break; case PORT_NVRAM_UPDATE_SELECT: rs->data[4] = oem_config.update_nvram; break; #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #endif /* CFG_BIOS_FLASH */ #ifdef CFG_LAN case SETTING_LAN_CONTROLLER: switch (rq->data[4]) { case PORT_LAN_INTERFACE: rs->data[4] = oem_config.lan_intf_sel; break; case PORT_LAN_CHAN_PRIO: rs->data[4] = oem_config.lan_chan_prio; break; default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #endif /* CFG_LAN */ #ifdef ADV_OEM_FAILURE_RETRY case SETTING_FAILURE_RETRIES: switch (rq->data[4]) { case PORT_POWER_FAILURE: rs->data[4] = oem_config.fail_retries_pwr; break; case PORT_TEMP_FAILURE: rs->data[4] = oem_config.fail_retries_temp; break; default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #endif /* ADV_OEM_FAILURE_RETRY */ case SETTING_MISC_SETTINGS: switch (rq->data[4]) { #ifdef CFG_POWER_BUDGETING case PORT_POWER_BUDGETING: rs->data[4] = oem_config.power_budget; break; #endif #ifdef REDRIVER_UPDATE_CHANNEL case PORT_UPDATE_CHANNEL: rs->data[4] = oem_config.update_chan_offset; break; #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #ifdef ADV_OEM_RTC_SYNC #ifdef CFG_ATCA case SETTING_RTC: switch (rq->data[4]) { case PORT_TIME_SYNC_ENABLE: rs->data[4] = oem_config.rtc_time_sync; break; default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #endif #endif /* ADV_OEM_RTC_SYNC */ case SETTING_FPGA: /* setting subsection */ switch (rq->data[4]) { #ifdef CFG_UART_MUX case PORT_COM1_MUX: rs->data[4] = oem_config.uart_mux1; break; case PORT_COM2_MUX: rs->data[4] = oem_config.uart_mux2; break; #ifdef ADV_CLI_SWITCHING case PORT_BMC_MUX: rs->data[4] = oem_config.uart_mux_bmc; break; #endif #endif /* CFG_UART_MUX */ default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; case SETTING_PCI_E_SPLITTING: /* setting subsection */ switch (rq->data[4]) { #ifdef CFG_CM #ifdef ADV_OEM_RTM_PCIE_CONFIG case PORT_PCIE_RTM: /* return value only, when rtm is plugged */ if (signal_read(&sig_cm_ps[0])) { rs->data[4] = oem_config.pcie_rtm_conf; break; } rs->data[4] = PCIE_SPLITTING_NOT_SUPPORTED; break; #endif #endif #if defined (I2C_BUS_MM) && (CFG_NUM_MMS_USED > 0) case PORT_PCIE_FMM1: rs->data[4] = mezzanine_modules[0].pci_e_setting[0]; break; #else #if defined(ADV_OEM_PCIE_CONFIG_OVERWRITE) && (CFG_NUM_MMS_USED == 0 || !defined(CFG_NUM_MMS_USED)) case PORT_PCIE_FMM1: rs->data[4] = ADV_OEM_PCIE_CONFIG_OVERWRITE; break; #endif #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; case SETTING_CLI: /* setting subsection */ switch (rq->data[4]) { case PORT_UART_BAUDRATE: rs->data[4] = oem_config.cli_baudrate; break; #ifdef ADV_CLI_SWITCHING case PORT_UART_ENABLE: rs->data[4] = oem_config.cli_uart_enable; break; #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; case SETTING_IRQ: /* setting subsection */ switch (rq->data[4]) { #ifdef ADV_OEM_PROC_HOT_IRQ case PORT_PROC_HOT: rs->data[4] = oem_config.proc_hot_irq; break; #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; case SETTING_TIMER: /* setting subsection */ switch (rq->data[4]) { #ifdef CFG_CM case PORT_CM_TIMEOUT: rs->data[4] = oem_config.cm_timeout; break; #endif /* CFG_CM */ #ifdef OEM_GF_SHUTDOWN_TIMEOUT_DEFAULT case PORT_GF_TIMEOUT: rs->data[4] = oem_config.gf_timeout; break; #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #ifdef CFG_CPCI /* Payload boot bank selection */ case SETTING_PAYLOAD_FLASH: switch (rq->data[4]) { case PORT_CURR_FLASH_BANK_SEL: rs->data[4] = signal_read(&sig_norflash_sel); break; case PORT_NEXT_FLASH_BANK_SEL: if(oem_config.payload_flash_sel_for_next == OEM_PAYLOAD_FLASH_SEL_FOR_NEXT_DEFAULT) { rs->data[4] = oem_config.payload_flash_sel; } else { rs->data[4] = oem_config.payload_flash_sel_for_next; } break; default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } break; #endif default: rs->data[0] = CC_PARAMETER_OUT_OF_RANGE; rs->data_len = 1; break; } return; } }
/** * MMC payload power control state machine * * \param carrier_pwr_on carrier 12V payload power on/off measurement judgement * \param pwr_seq_on onboard payload power sequencing done / power on */ void mmc_payload_pwr_states(unsigned char carrier_pwr_on, unsigned char pwr_seq_on) { /* handle states */ if (mmc_payload_state.old_st == mmc_payload_state.new_st) { /* state has not changed */ switch (mmc_payload_state.old_st) { case MMC_STATE_UNKWN: /* detect current state */ if (!carrier_pwr_on) { /* 12V from carrier off */ mmc_payload_state.new_st = MMC_STATE_PWR_OFF; } else if (carrier_pwr_on && !pwr_seq_on) { /* 12V from carrier on, but onboard power not started */ mmc_payload_state.new_st = MMC_STATE_PWR_ON; } else if (carrier_pwr_on && pwr_seq_on) { /* 12V from carrier on and onboard power running */ mmc_payload_state.new_st = MMC_STATE_PWR_STABLE; } break; case MMC_STATE_PWR_OFF: /* 12V from carrier enabled and "off" state active for at least 9 seconds? */ if (carrier_pwr_on && gp_timer_expired(&timer_payload_pwr)) { /* start onboard power */ mmc_payload_state.new_st = MMC_STATE_PWR_ON; } break; case MMC_STATE_PWR_ON: /* onboard power running for at least six seconds */ if (gp_timer_expired(&timer_payload_pwr)) { /* move to onboard power stable */ mmc_payload_state.new_st = MMC_STATE_PWR_STABLE; } /* don't waste time if power sequence is done already */ else if (carrier_pwr_on && pwr_seq_on) { mmc_payload_state.new_st = MMC_STATE_PWR_STABLE; } break; case MMC_STATE_PWR_STABLE: /* check for payload system resets and any pending update actions */ #ifdef CFG_x86 fru_check_system_reset(); #endif /* deactivation of payload - onboard power disabled */ if (!signal_read(&sig_payload_power)) { /* onboard power disabled */ mmc_payload_state.new_st = MMC_STATE_PWR_OFF; } /* carrier power gone by mistake (onboard power enable still on) */ else if (!carrier_pwr_on && signal_read(&sig_payload_power)) { /* 12V carrier power fail */ mmc_payload_state.new_st = MMC_STATE_PWR_FAIL; } break; case MMC_STATE_PWR_FAIL: /* hot swap handle open */ if (!signal_read(&sig_hs_handle)) { /* payload power enable still on */ if (signal_read(&sig_payload_power)) { /* switch off onboard power enable */ //fru_payload_poweroff(); } } /* payload power disabled? */ if (!signal_read(&sig_payload_power)) { /* turn off red OOS LED */ led_set(LED_ID_1, LED_FUNC_OFF, 0); /* return to normal payload power off state */ mmc_payload_state.new_st = MMC_STATE_PWR_OFF; } break; default: /* unknown state, set back to valid state */ mmc_payload_state.new_st = MMC_STATE_UNKWN; break; } } else { /* state has changed */ switch (mmc_payload_state.new_st) { case MMC_STATE_UNKWN: /* store time */ uptime_payload_pwr = uptime(); break; case MMC_STATE_PWR_OFF: /* store payload power off start time */ uptime_payload_pwr = uptime(); gp_timer_start(&timer_payload_pwr, 9 * configTICK_RATE_HZ); #ifdef CFG_BIOS_FLASH /* check if there's BIOS redundancy work to do */ bios_redundancy_handle_update(); #endif #ifdef CFG_IRTM signal_deactivate(&sig_rtm_ready); #endif break; case MMC_STATE_PWR_ON: /* switch on payload power sequencing */ fru_payload_poweron(); /* store payload power on start time */ uptime_payload_pwr = uptime(); gp_timer_start(&timer_payload_pwr, 6 * configTICK_RATE_HZ); break; case MMC_STATE_PWR_STABLE: #ifdef CFG_IRTM signal_activate(&sig_rtm_ready); #endif /* store payload power stable start time */ uptime_payload_pwr = uptime(); break; case MMC_STATE_PWR_FAIL: #ifndef CFG_IRTM /* turn on red OOS LED */ led_set(LED_ID_1, LED_FUNC_ON, 0); #ifdef ADV_OEM_INTEGRITY_SENSOR sensor_integrity_send_event(IS_HW, IS_ACTION_PAYLOAD_PWR, IS_FAIL); #endif #endif /* !CFG_IRTM */ /* store payload power fail start time */ uptime_payload_pwr = uptime(); break; default: /* unknown state, go back to unknown state */ mmc_payload_state.new_st = MMC_STATE_UNKWN; break; } /* save new state */ mmc_payload_state.old_st = mmc_payload_state.new_st; } }
/** * Starts the initialization, the tasks and then the scheduler. */ int main(void) { /* disable ETM at very first */ PINSEL10 &= ~((unsigned int)(1 << 3)); /* Initialize BMC hardware */ global_data.bmc_resetcause = 0x00; /* IPMI message sequence counter */ global_data.seq_counter = 0x00; /* site number used for entity instance */ global_data.bmc_siteno = 0x00; /* reset sdr list */ sdr_list.sdr_count = 0; /* init PLL */ init_clock(); /* init interrupts */ init_irq(); /* get reset cause */ init_resetcause(); /* init port pins */ init_portpins(); /* CUSTOM BOARD INIT CODE LOCATION 1 */ custom_init_1(); /* get HW and IPMB address */ custom_get_hw_ipmb_address(); uptime_init(); /* init RTC */ rtc_init(); /* create the FreeRTOS queues */ create_queues(); uart_init(UART_DEBUG_CONNECTOR, 115200); uart_printf("Firmware started...\n"); /* init SPI/SSP controllers */ spi_init(); /* init SPI FLASH */ spi_flash_init_devices(); spi_flash_init(&spi_flash); #ifdef CFG_MMC_I2C_MASTER /* init BMC master I2C bus */ master_i2c_init(MASTER_BUS_I2C); #endif /* init EEPROM file system */ //spi_eeprom_init(&spi_eeprom); #ifdef CFG_FS if (fs_init(&efs, &spi_eeprom) != 0) { uart_printf("\nEEPROM not accesable!\n"); /* reboot bmc */ lpc_watchdog_start(CFG_BL_WATCHDOG_TIMEOUT, WD_RESET_MODE); while (1); } #endif /* init leds */ //led_init(); #ifndef CFG_ONCHIP_FLASH_GLOBAL_CONF /* check EEPROM areas */ //eeprom_integrity_check_areas(); #endif /* init CLI (and debug console) */ cli_uart_init(115200); /* handle reset type warm/cold? */ //fru_handle_reset_type(); #ifdef CFG_CM cm_fru_get_last_known_state(); #endif #ifdef CFG_EXT_INT /* init external interrupts */ external_interrupt_init(); #endif #ifdef CFG_HELPER /* init the helper task */ helper_init(); #endif #ifdef CFG_BIOS_FLASH /* init BIOS FLASH */ spi_flash_init(&bios_flash); /* init FPGA BIOS flash selection */ bios_restore_active_flash_from_eeprom(); #endif /* CUSTOM BOARD INIT CODE LOCATION 2 */ //custom_init_2(); /* get global configuration from EEPROM */ global_config(); /* CUSTOM BOARD INIT CODE LOCATION 3 */ //custom_init_3(); /* parse FRU */ fru_init(0); #if defined (CFG_CM) || defined (CFG_MMC) || defined (CFG_IRTM) || defined(CFG_MCMC) /* init the IPMB-L interface(s) */ ipmbl_init(); #endif #ifdef CFG_LAN /* read and set ncsi mac address from fru */ custom_set_ncsi_mac(); #endif /* create message pool for IPMI messages */ message_pool_init(); /* init board task */ board_init(); /* init the BMC task */ bmc_init(); #ifdef CFG_PI_SERIAL_BASIC /* init the payload interface */ pi_uart_b_init(CFG_PI_PORT_RATE); #endif /* CFG_PI_SERIAL_BASIC */ #ifdef CFG_PI_SERIAL_TERMINAL /* init the payload interface */ pi_uart_t_init(CFG_PI_PORT_RATE); #endif /* CFG_PI_SERIAL_TERMINAL */ #ifdef CFG_PI_KCS /* initialise kcs interface */ kcs_init(); #endif /* CFG_PI_KCS */ #ifdef CFG_ATCA if (global_conf.operation_mode == OPERATION_MODE_STANDALONE) { /* configure IPMB-A and IPMB-B as master only in stanalone mode */ master_i2c_init(IPMB0A_I2C); master_i2c_init(IPMB0B_I2C); /* enable IPMB-0 pull ups and buffer */ ipmb0_bus_ctrl(IPMB0_A, IPMB_ENABLE); ipmb0_bus_ctrl(IPMB0_B, IPMB_ENABLE); } else { /* init the IPMB-0 interface */ ipmb0_init(); } #endif #ifdef CFG_LAN_PLUS sol_init(); #endif #ifdef CFG_LAN /* init ethernet hardware and Task */ eth_start(); #endif /* init the SDR task */ /* PORT_NOTE: Needs to be started AFTER BMC task because of Semaphore dependency */ sdr_init(); /* parse all PICMG Records in FRU data and store relevant information */ //fru_parse_picmg(); /* init the IPMI message hub */ msg_hub_init(); /* init the event task */ event_init(); #ifdef CFG_CM /* init the CM task */ init_cm(); #endif #ifdef CFG_COOLING_MANAGER cool_init(); #endif /* do all post tests */ //post_test(); /* needs to be done after sdr initialization */ //hpm_check_bl_flags(); #ifdef CFG_BIOS_FLASH /* collect BIOS/NVRAM version info (if payload power is off) */ if (!(signal_read(&sig_payload_power_enable))) { bios_redundancy_get_versions(); } #endif #ifdef CFG_WATCHDOG /* start the FW watchdog */ lpc_watchdog_start(CFG_FW_WATCHDOG_TIMEOUT, WD_RESET_MODE); #endif /* set desired debug output mode before starting scheduler */ global_debug_uart_enabled = CFG_GLOBAL_DEBUG_UART; /* all tasks have been initialized, start the scheduler */ vTaskStartScheduler(); /* Should never reach here! */ while (1); }
static ssize_t signal_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long niov, loff_t pos) { return signal_read(iocb->ki_filp, (char*)iov->iov_base,iocb->ki_nbytes, &pos);; }