static void dhcp_send_packet(struct uip_udp_conn *conn, const char *name, DhcpPacket *out, DhcpPacket *in) { // Send the outbound packet. printf("Sending %s... ", name); uip_udp_packet_send(conn, out, sizeof(*out)); printf("done.\n"); // Prepare for the reply. printf("Waiting for reply... "); dhcp_in = in; dhcp_out = out; dhcp_in_ready = 0; // Poll network driver until we get a reply. Resend periodically. net_set_callback(&dhcp_callback); for (;;) { uint64_t start = timer_us(0); do { net_poll(); } while (!dhcp_in_ready && timer_us(start) < DhcpRespTimeoutUs); if (dhcp_in_ready) break; // No response, try again. uip_udp_packet_send(conn, out, sizeof(*out)); } net_set_callback(NULL); printf("done.\n"); }
uint64_t VbExGetTimer(void) { static uint64_t start = 0; if (!start) start = timer_us(0); return timer_us(start); }
// print per-task accumulated usec runtime since last dump void TaskDump() { int i; TASK *t; u4_t now = timer_us(); u4_t elapsed = now - epoch; float f_elapsed = ((float) elapsed) / 1e6; float f_sum = 0; for (i=0; i<MAX_TASKS; i++) { t = Tasks + i; if (t->valid) { float f_usec = ((float) t->usec) / 1e6; f_sum += f_usec; lprintf("T%02d %c%c%c %.3fuS %4.1f%% %6.3fM %7.3fdl %s\n", i, (t->priority == HIGH_PRIORITY)? 'H':'L', t->stopped? 'S':'R', t->quanta? 'q':' ', f_usec, f_usec/f_elapsed*100, (float) t->run / 1e6, t->deadline? ((float) (t->deadline-now) / 1e3) : 0, t->name); t->usec = 0; } } float f_remain = f_elapsed - f_sum; if (f_remain > 0) lprintf(" %.3f %4.1f%% (unaccounted)\n", f_remain, f_remain/f_elapsed*100); epoch = timer_us(); }
int apollolake_get_gpe(int gpe) { int bank; uint32_t mask, sts; uint64_t start; int rc = 0; const uint64_t timeout_us = 1000; if (gpe < 0 || gpe > GPE0_DW3_31) return -1; bank = gpe / 32; mask = 1 << (gpe % 32); /* Wait for GPE status to clear */ start = timer_us(0); do { if (timer_us(start) > timeout_us) break; sts = inl(ACPI_PMIO_BASE + GPE0_STS(bank)); if (sts & mask) { outl(mask, ACPI_PMIO_BASE + GPE0_STS(bank)); rc = 1; } } while (sts & mask); return rc; }
void spin_us(u4_t usec) { u4_t tref = timer_us(), diff; do { diff = time_diff(timer_us(), tref); } while (diff < usec); }
//void s4285_data(int rx_chan, int ch, int nsamps, TYPECPX *samps) void s4285_data(int rx_chan, int ch, int nsamps, TYPEMONO16 *samps) { s4285_t *e = &s4285[rx_chan]; if (e->mode == MODE_TX_LOOPBACK) { //m_CSt4285[rx_chan].getTxOutput((void *) samps, nsamps, TYPE_IQ_F32_DATA, K_AMPMAX); m_CSt4285[rx_chan].getTxOutput((void *) samps, nsamps, TYPE_REAL_S16_DATA, K_AMPMAX); if (e->rx_task) TaskWakeup(e->rx_task, TRUE, e->rx_chan); } else { #if 0 static u4_t last_time; u4_t now = timer_us(); printf("s4285 nsamps %d %7.3f msec\n", nsamps, (float) (now - last_time) / 1e3); last_time = now; #endif assert(nsamps == N_RXBLK); memcpy(&s4285_rx_blocks[s4285_rx_wa][0], samps, sizeof(TYPEMONO16)*N_RXBLK); s4285_rx_wa++; if (s4285_rx_wa == N_RXBLKS) s4285_rx_wa = 0; s4285_rx_count++; if (s4285_rx_count > s4285_rx_count_max) { printf("%d\n", s4285_rx_count); s4285_rx_count_max = s4285_rx_count; } assert(s4285_rx_count < N_RXBLKS); if (e->rx_task) TaskWakeup(e->rx_task, TRUE, e->rx_chan); } }
/* * apl_i2s_send - Send audio samples to I2s controller. * @me: I2sOps structure * @data: Audio samples * @length: Number of samples * * Send audio samples to I2s controller. */ static int apl_i2s_send(I2sOps *me, unsigned int *data, unsigned int length) { int i; uint64_t start; AplI2s *bus = container_of(me, AplI2s, ops); struct AplI2sRegs *i2s_reg = bus->regs; if (!bus->initialized) { if (apl_i2s_init(bus)) return -1; bus->initialized = 1; } if (length < LPE_SSP_FIFO_SIZE) { printf("%s : Invalid data size\n", __func__); return -1; } gpio_set(bus->sdmode_gpio, 1); for (i = 0; i < LPE_SSP_FIFO_SIZE; i++) writel(*data++, &i2s_reg->ssdr); i2s_enable(bus->regs); length -= LPE_SSP_FIFO_SIZE; while (length > 0) { start = timer_us(0); if (read_SSSR(bus->regs) & 0x4) { writel(*data++, &i2s_reg->ssdr); length--; } else { if (timer_us(start) > 100000) { i2s_disable(bus->regs); gpio_set(bus->sdmode_gpio, 0); printf("I2S Transfer Timeout\n"); return -1; } } } mdelay(1); gpio_set(bus->sdmode_gpio, 0); i2s_disable(bus->regs); return 0; }
void ev(int event, const char *s, const char *s2) { int i; ev_t *e = &evs[evc++]; u4_t now = timer_us(); int reset=0; u64_t freeS2 = (u64_t) s2 & 1; s2 = (char*) ((u64_t) s2 & ~1); if (!triggered && (event == EV_TRIGGER)) { epoch = last_time = now; for (i=0; i<NEVT; i++) tlast[i] = now; evc=0; triggered=1; if (freeS2) free((void*) s2); return; } if (!triggered) { if (freeS2) free((void*) s2); return; } if (event < 0) { event = -event; tlast[event] = now; reset=1; } e->event = event; e->reset = reset; e->s = s; e->s2 = s2; e->tseq = now - last_time; e->tlast = now - tlast[event]; e->tepoch = now - epoch; e->task = TaskName(); if (evc == NEV) { for (i=0; i<NEV; i++) { e = &evs[i]; printf("%4d %8s%c %7.3f %7.3f %9.3f %16s, %16s %s\n", i, evn[e->event], e->reset? '*':' ', (float) e->tlast / 1000, (float) e->tseq / 1000, (float) e->tepoch / 1000, e->task, e->s, e->s2); } exit(0); } last_time = now; }
void TaskInit() { static bool init; TASK *t; //printf("MAX_TASKS %d\n", MAX_TASKS); epoch = start_us = timer_us(); start_ms = timer_ms(); t = Tasks; cur_task = cur_low = t; prio_low = t; t->next = t->prev = NULL; task_init(t, 0, NULL, NULL, "main", LOW_PRIORITY); }
int TaskSleep(u4_t usec) { TASK *t = cur_task; //printf("sleep T%02d %d usec\n", t->id, usec); t->deadline = usec? (timer_us() + usec) : 0; t->stopped = TRUE; do { NextTaskL("TaskSleep"); } while (!t->wakeup); //printf("woke T%02d %d usec\n", t->id, usec); //if (t->id==4 || t->id==6) printf("wo%d ", t->id); fflush(stdout); t->deadline = 0; t->stopped = FALSE; t->wakeup = FALSE; return t->wake_param; }
void pru_start() { unsigned int ret; char *bin; tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; prussdrv_init(); if (prussdrv_open(PRU_EVTOUT_0)) panic("prussdrv_open"); if (prussdrv_pruintc_init(&pruss_intc_initdata)) panic("prussdrv_pruintc_init"); if (prussdrv_map_prumem(PRUSS0_PRU0_DATARAM, &pruDataMem)) panic("prussdrv_map_prumem"); pru = (com_t *) pruDataMem; pru2 = (com2_t *) (pruDataMem + PRU_COM_SIZE); bin = background_mode? "/usr/local/bin/hp5370d_realtime.bin" : "pru/pru_realtime.bin"; if (prussdrv_exec_program(PRU_NUM, bin)) panic("prussdrv_exec_program"); u4_t key1 = timer_us(); u4_t key2 = key1 >> 8; pru->p[0] = key1; pru->p[1] = key2; pru->p[2] = 0; pru->p[3] = 0; pru2->m2_offset = 0xbeefcafe; send_pru_cmd(PRU_PING); if (pru->p[2] != (key1+key2)) panic("PRU didn't start"); if (pru->p[3] != 0xbeefcafe) panic("PRU com2_t at wrong offset?"); send_pru_cmd(PRU_CLEAR); lprintf("PRU started\n"); #if 0 prussdrv_pru_wait_event(PRU_EVTOUT_0); // wait for halt prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT); prussdrv_pru_disable(PRU_NUM); prussdrv_exit(); #endif }
void NewPing::ping_timer(void (*userFunc)(void), unsigned int updateInterval_us,unsigned int maxTime_us) { if (!ping_trigger(maxTime_us)) return; // Trigger a ping, if it returns false, return without starting the echo timer. timer_us(updateInterval_us, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS. _isRunning=true; }
void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) { if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance. if (!ping_trigger()) return; // Trigger a ping, if it returns false, return without starting the echo timer. timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS. }
static void spi_scan(SPI_MOSI *mosi, SPI_MISO *miso=&junk, int rbytes=0) { int i; assert(rbytes <= NSPI_RX); int tx_bytes = sizeof(SPI_MOSI); int tx_xfers = SPI_B2X(tx_bytes); int rx_bytes = sizeof(miso->status) + rbytes; int rx_xfers = SPI_B2X(rx_bytes); int arx_xfers = MAX(tx_xfers, prev->len_xfers); int arx_bytes = SPI_X2B(arx_xfers); //jks #if 0 static u4_t last_st; static float acc_st, acc2_st; static int big_rx; if (arx_bytes > 1024) big_rx = 1; u4_t st = timer_us(); float inc_st = (float) (st - last_st) / 1000.0; acc_st += inc_st; if (mosi->cmd == CmdSetWFFreq) acc2_st = 0; printf("SCAN +%.3f %6.3f %6.3f %12s %16s tx(%dX=%dB) rx(%dX=%dB) arx(%dX=%dB)\n", inc_st, acc_st, acc2_st, TaskName(), cmds[mosi->cmd], tx_xfers, tx_bytes, rx_xfers, rx_bytes, arx_xfers, arx_bytes); if (mosi->cmd == CmdDuplex && big_rx) { acc_st = 0; big_rx = 0; } else { } acc2_st += inc_st; last_st = st; #endif //memset(miso, 0xee, sizeof(*miso)); miso->len_xfers = rx_xfers; miso->cmd = mosi->cmd; rx_xfers = arx_xfers; if (mosi->cmd == CmdDuplex) mosi->cmd = CmdDummy; if (mosi->cmd == CmdNoDuplex) mosi->cmd = CmdDummy; for (;;) { peri_spi(SPI_HOST, mosi->msg, tx_xfers, // MOSI: new request prev->msg, rx_xfers); // MISO: response to previous caller's request evSpi(EV_SPILOOP, "spiScan", "peri_spi done"); // fixme: understand why is this needed (hangs w/o it) if (spi_delay) spin_us(spi_delay); else usleep(10); evSpi(EV_SPILOOP, "spiScan", "spin_us done"); if (prev->status != BUSY) break; // new request accepted? evSpi(EV_SPILOOP, "spiScan", "BUSY -> NextTask"); NextTaskL("spi_scan"); // wait and try again } //jks #if 0 printf("RX %d: ", prev->len_xfers); if (prev == &junk) { printf("(junk) "); } else { printf("%s ", cmds[prev->cmd]); } for (i=0; i<(prev->len_xfers+10); i++) { printf("%d:", i); #ifdef SPI_8 printf("%02x ", prev->msg[i]); #endif #ifdef SPI_16 printf("%04x ", prev->msg[i]); #endif #ifdef SPI_32 printf("%08x ", prev->msg[i]); #endif } printf("\n"); #endif u4_t status = prev->status; prev = miso; // next caller collects this for us pcmd=mosi->cmd; //if (status & 0x0fff) //printf("st %04x\n", status); //if (mosi->cmd == CmdGetRXCount) printf("C"); //if (mosi->cmd == CmdGetRX) printf("GRX\n"); static int ff; if (status & (1<<SPI_SFT)) { rx0_wakeup = 1; evSnd(EV_SND, "wakeup", ""); //printf("."); ff = 0; } else { rx0_wakeup = 0; if (!ff) { //printf("."); ff = 1; } } // process rx channel wakeup bits for (i=0; i<RX_CHANS; i++) { u4_t ch = 1<<(i+SPI_SFT); conn_t *c; if (status & ch) { c = &conns[i*2]; assert(c->type == STREAM_SOUND); //if (c->task && !c->stop_data) printf("wakeup %d\n", c->task); //if (c->task && !c->stop_data) { printf("%d:%d ", i, c->task); fflush(stdout); } if (c->task && !c->stop_data) TaskWakeup(c->task, FALSE, 0); } } }
void NewPing::ping_timer(void (*userFunc)(void)) { ping_trigger(); // Trigger a ping. if (!ping_wait()) return; // Wait for ping to start, if it returns false, return without starting the echo timer. timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS. }
/* Get charger power info in Watts. Also returns type of charger */ int google_chromeec_get_usb_pd_power_info(enum usb_chg_type *type, u32 *max_watts) { struct ec_params_usb_pd_power_info req = { .port = PD_POWER_CHARGING_PORT, }; struct ec_response_usb_pd_power_info rsp; struct chromeec_command cmd = { .cmd_code = EC_CMD_USB_PD_POWER_INFO, .cmd_version = 0, .cmd_data_in = &req, .cmd_size_in = sizeof(req), .cmd_data_out = &rsp, .cmd_size_out = sizeof(rsp), .cmd_dev_index = 0, }; struct usb_chg_measures m; int rv = google_chromeec_command(&cmd); if (rv != 0) return rv; /* values are given in milliAmps and milliVolts */ *type = rsp.type; m = rsp.meas; *max_watts = (m.current_max * m.voltage_max) / 1000000; return 0; } int google_chromeec_override_dedicated_charger_limit(u16 current_lim, u16 voltage_lim) { struct ec_params_dedicated_charger_limit p = { .current_lim = current_lim, .voltage_lim = voltage_lim, }; struct chromeec_command cmd = { .cmd_code = EC_CMD_OVERRIDE_DEDICATED_CHARGER_LIMIT, .cmd_version = 0, .cmd_data_in = &p, .cmd_size_in = sizeof(p), .cmd_data_out = NULL, .cmd_size_out = 0, .cmd_dev_index = 0, }; return google_chromeec_command(&cmd); } int google_chromeec_set_usb_pd_role(u8 port, enum usb_pd_control_role role) { struct ec_params_usb_pd_control req = { .port = port, .role = role, .mux = USB_PD_CTRL_MUX_NO_CHANGE, .swap = USB_PD_CTRL_SWAP_NONE, }; struct ec_response_usb_pd_control rsp; struct chromeec_command cmd = { .cmd_code = EC_CMD_USB_PD_CONTROL, .cmd_version = 0, .cmd_data_in = &req, .cmd_size_in = sizeof(req), .cmd_data_out = &rsp, .cmd_size_out = sizeof(rsp), .cmd_dev_index = 0, }; return google_chromeec_command(&cmd); } static int google_chromeec_hello(void) { struct chromeec_command cec_cmd; struct ec_params_hello cmd_hello; struct ec_response_hello rsp_hello; cmd_hello.in_data = 0x10203040; cec_cmd.cmd_code = EC_CMD_HELLO; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_in = &cmd_hello.in_data; cec_cmd.cmd_data_out = &rsp_hello.out_data; cec_cmd.cmd_size_in = sizeof(cmd_hello.in_data); cec_cmd.cmd_size_out = sizeof(rsp_hello.out_data); cec_cmd.cmd_dev_index = 0; google_chromeec_command(&cec_cmd); printk(BIOS_DEBUG, "Google Chrome EC: Hello got back %x status (%x)\n", rsp_hello.out_data, cec_cmd.cmd_code); return cec_cmd.cmd_code; } /* Cached EC image type (ro or rw). */ static int ec_image_type = EC_IMAGE_UNKNOWN; static void google_chromeec_get_version(void) { struct chromeec_command cec_cmd; struct ec_response_get_version cec_resp; cec_cmd.cmd_code = EC_CMD_GET_VERSION; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_in = 0; cec_cmd.cmd_data_out = &cec_resp; cec_cmd.cmd_size_in = 0; cec_cmd.cmd_size_out = sizeof(cec_resp); cec_cmd.cmd_dev_index = 0; google_chromeec_command(&cec_cmd); if (cec_cmd.cmd_code) { printk(BIOS_DEBUG, "Google Chrome EC: version command failed!\n"); } else { printk(BIOS_DEBUG, "Google Chrome EC: version:\n"); printk(BIOS_DEBUG, " ro: %s\n", cec_resp.version_string_ro); printk(BIOS_DEBUG, " rw: %s\n", cec_resp.version_string_rw); printk(BIOS_DEBUG, " running image: %d\n", cec_resp.current_image); ec_image_type = cec_resp.current_image; } } void google_chromeec_init(void) { printk(BIOS_DEBUG, "Google Chrome EC: Initializing\n"); google_chromeec_hello(); /* Get version to check which EC image is active */ google_chromeec_get_version(); /* Check/update EC RW image if needed */ if (google_chromeec_swsync()) { printk(BIOS_ERR, "ChromeEC: EC SW SYNC FAILED\n"); } else if (ec_image_type != EC_IMAGE_RW) { /* EC RW image is up to date, switch to it if not already*/ google_chromeec_reboot(0, EC_REBOOT_JUMP_RW, 0); mdelay(100); /* Use Hello cmd to "reset" EC now in RW mode */ google_chromeec_hello(); /* re-run version command & print */ google_chromeec_get_version(); } } int google_ec_running_ro(void) { return (ec_image_type == EC_IMAGE_RO); } void google_chromeec_reboot_ro(void) { /* Reboot the EC and make it come back in RO mode */ printk(BIOS_DEBUG, "Rebooting with EC in RO mode:\n"); post_code(0); /* clear current post code */ google_chromeec_reboot(0, EC_REBOOT_COLD, 0); udelay(1000); board_reset(); halt(); } /* Timeout waiting for EC hash calculation completion */ static const int CROS_EC_HASH_TIMEOUT_MS = 2000; /* Time to delay between polling status of EC hash calculation */ static const int CROS_EC_HASH_CHECK_DELAY_MS = 10; int google_chromeec_swsync(void) { static struct ec_response_vboot_hash resp; uint8_t *ec_hash; int ec_hash_size; uint8_t *ecrw_hash, *ecrw; int need_update = 0, i; size_t ecrw_size; /* skip if on S3 resume path */ if (acpi_is_wakeup_s3()) return 0; /* Get EC_RW hash from CBFS */ ecrw_hash = cbfs_boot_map_with_leak("ecrw.hash", CBFS_TYPE_RAW, NULL); if (!ecrw_hash) { /* Assume no EC update file for this board */ printk(BIOS_DEBUG, "ChromeEC SW Sync: no EC_RW update available\n"); return 0; } /* Got an expected hash */ printk(BIOS_DEBUG, "ChromeEC SW Sync: Expected hash: "); for (i = 0; i < SHA256_DIGEST_SIZE; i++) printk(BIOS_DEBUG, "%02x", ecrw_hash[i]); printk(BIOS_DEBUG, "\n"); /* Get hash of current EC-RW */ if (google_chromeec_read_hash(&resp)) { printk(BIOS_ERR, "Failed to read current EC_RW hash.\n"); return -1; } ec_hash = resp.hash_digest; ec_hash_size = resp.digest_size; /* Check hash size */ if (ec_hash_size != SHA256_DIGEST_SIZE) { printk(BIOS_ERR, "ChromeEC SW Sync: - " "read_hash says size %d, not %d\n", ec_hash_size, SHA256_DIGEST_SIZE); return -1; } /* We got a proper hash */ printk(BIOS_DEBUG, "ChromeEC SW Sync: current EC_RW hash: "); for (i = 0; i < SHA256_DIGEST_SIZE; i++) printk(BIOS_DEBUG, "%02x", ec_hash[i]); printk(BIOS_DEBUG, "\n"); /* compare hashes */ need_update = SafeMemcmp(ec_hash, ecrw_hash, SHA256_DIGEST_SIZE); /* If in RW and need to update, return/reboot to RO */ if (need_update && ec_image_type == EC_IMAGE_RW) { printk(BIOS_DEBUG, "ChromeEC SW Sync: EC_RW needs update but in RW; rebooting to RO\n"); google_chromeec_reboot_ro(); return -1; } /* Update EC if necessary */ if (need_update) { printk(BIOS_DEBUG, "ChromeEC SW Sync: updating EC_RW...\n"); /* Get ecrw image from CBFS */ ecrw = cbfs_boot_map_with_leak("ecrw", CBFS_TYPE_RAW, &ecrw_size); if (!ecrw) { printk(BIOS_ERR, "ChromeEC SW Sync: no ecrw image found in CBFS; cannot update\n"); return -1; } if (google_chromeec_flash_update_rw(ecrw, ecrw_size)) { printk(BIOS_ERR, "ChromeEC SW Sync: Failed to update EC_RW.\n"); return -1; } /* Have EC recompute hash for new EC_RW block */ if (google_chromeec_read_hash(&resp) ) { printk(BIOS_ERR, "ChromeEC SW Sync: Failed to read new EC_RW hash.\n"); return -1; } /* Compare new EC_RW hash to value from CBFS */ ec_hash = resp.hash_digest; if(SafeMemcmp(ec_hash, ecrw_hash, SHA256_DIGEST_SIZE)) { /* hash mismatch! */ printk(BIOS_DEBUG, "ChromeEC SW Sync: Expected hash: "); for (i = 0; i < SHA256_DIGEST_SIZE; i++) printk(BIOS_DEBUG, "%02x", ecrw_hash[i]); printk(BIOS_DEBUG, "\n"); printk(BIOS_DEBUG, "ChromeEC SW Sync: EC hash: "); for (i = 0; i < SHA256_DIGEST_SIZE; i++) printk(BIOS_DEBUG, "%02x", ec_hash[i]); printk(BIOS_DEBUG, "\n"); return -1; } printk(BIOS_DEBUG, "ChromeEC SW Sync: EC_RW hashes match\n"); printk(BIOS_DEBUG, "ChromeEC SW Sync: done\n"); } else { printk(BIOS_DEBUG, "ChromeEC SW Sync: EC_RW is up to date\n"); } return 0; } int google_chromeec_read_hash(struct ec_response_vboot_hash *hash) { struct chromeec_command cec_cmd; struct ec_params_vboot_hash p; int recalc_requested = 0; uint64_t start = timer_us(0); do { /* Get hash if available. */ p.cmd = EC_VBOOT_HASH_GET; cec_cmd.cmd_code = EC_CMD_VBOOT_HASH; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_in = &p; cec_cmd.cmd_data_out = hash; cec_cmd.cmd_size_in = sizeof(p); cec_cmd.cmd_size_out = sizeof(*hash); cec_cmd.cmd_dev_index = 0; printk(BIOS_DEBUG, "ChromeEC: Getting hash:\n"); if (google_chromeec_command(&cec_cmd)) return -1; switch (hash->status) { case EC_VBOOT_HASH_STATUS_NONE: /* We have no valid hash - let's request a recalc * if we haven't done so yet. */ if (recalc_requested != 0) { mdelay(CROS_EC_HASH_CHECK_DELAY_MS); break; } printk(BIOS_DEBUG, "ChromeEC: No valid hash (status=%d size=%d). " "Compute one...\n", hash->status, hash->size); p.cmd = EC_VBOOT_HASH_RECALC; p.hash_type = EC_VBOOT_HASH_TYPE_SHA256; p.nonce_size = 0; p.offset = EC_VBOOT_HASH_OFFSET_RW; p.size = 0; cec_cmd.cmd_code = EC_CMD_VBOOT_HASH; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_in = &p; cec_cmd.cmd_data_out = hash; cec_cmd.cmd_size_in = sizeof(p); cec_cmd.cmd_size_out = sizeof(*hash); cec_cmd.cmd_dev_index = 0; printk(BIOS_DEBUG, "ChromeEC: Starting EC hash:\n"); if (google_chromeec_command(&cec_cmd)) return -1; recalc_requested = 1; /* Command will wait to return until hash is done/ready */ break; case EC_VBOOT_HASH_STATUS_BUSY: /* Hash is still calculating. */ mdelay(CROS_EC_HASH_CHECK_DELAY_MS); break; case EC_VBOOT_HASH_STATUS_DONE: default: /* We have a valid hash. */ break; } } while (hash->status != EC_VBOOT_HASH_STATUS_DONE && timer_us(start) < CROS_EC_HASH_TIMEOUT_MS * 1000); if (hash->status != EC_VBOOT_HASH_STATUS_DONE) { printk(BIOS_DEBUG, "ChromeEC: Hash status not done: %d\n", hash->status); return -1; } return 0; } int google_chromeec_flash_update_rw(const uint8_t *image, int image_size) { uint32_t rw_offset, rw_size; int ret; /* get max size that can be written, offset to write */ if (google_chromeec_flash_offset(EC_FLASH_REGION_RW, &rw_offset, &rw_size)) return -1; if (image_size > rw_size) return -1; /* * Erase the entire RW section, so that the EC doesn't see any garbage * past the new image if it's smaller than the current image. * */ ret = google_chromeec_flash_erase(rw_offset, rw_size); if (ret) return ret; /* Write the image */ return(google_chromeec_flash_write(image, rw_offset, image_size)); }
void _NextTaskL() #endif { int i; TASK *t, *tn; u4_t now, quanta; t = cur_task; // don't switch until quanta expired (if any) if (t->quanta && ((timer_ms() - start_ms) < t->quanta)) return; ev(EV_NEXTTASK, "NextTask", ""); now = timer_us(); quanta = now - start_us; t->usec += quanta; if (slice) { TSLICE *ts = &slices[slice-1]; ts->id = t->id; ts->usec = quanta; ts->wakeup = rx0_wakeup; ts->twoke = now - rx0_twoke; #ifdef DEBUG ts->s = s; #endif slice++; if (slice == NSLICES) { u4_t maxv=0; int maxi=0; for (i=0; i<NSLICES; i++) { ts = &slices[i]; if (ts->usec > maxv) { maxv = ts->usec; maxi = i; } } for (i=0; i<NSLICES; i++) { ts = &slices[i]; printf("%4d T%02d %7.3f %7.3f w%d %s %s %s %s\n", i, ts->id, ((float) ts->usec) / 1e3, ((float) ts->twoke) / 1e3, ts->wakeup, Tasks[ts->id].name, ts->s? ts->s : "", ts->msg, (i==maxi)? "############################################": ( (ts->usec>=2000.0)? "------------------------------------------":"") ); } xit(0); slice = 0; } } if (setjmp(t->jb)) { return; } //printf("P%d-%s %.3f ms pc %p\n", t->id, t->name, ((float) quanta) / 1e3, (void *) t->pc); fflush(stdout); for (i=0; i<MAX_TASKS; i++) { TASK *tp = Tasks + i; if (tp->valid && tp->deadline && (tp->deadline < now)) { tp->deadline = 0; tp->stopped = FALSE; tp->wakeup = TRUE; //printf("wake T%02d\n", tp->id); } } if (t->priority == HIGH_PRIORITY) { do { // after a high priority finishes run next high priority t = t->next; } while (t && t->stopped); if (!t) { // no other high priority, so run next low priority t = cur_low; do { t = t->next; if (!t) t = prio_low; } while (t->stopped); } } else { // run _all_ high priority after each low priority finishes for (t = prio_high; t && t->stopped; t = t->next) ; if (!t) { // no high priority so run next low priority t = cur_task; do { t = t->next; if (!t) t = prio_low; } while (t->stopped); } } cur_task = t; if (t->priority == LOW_PRIORITY) cur_low = t; t->run++; //printf("N%d-%s pc %p\n", t->id, t->name, (void *) t->pc); fflush(stdout); start_us = now; if (t->quanta) start_ms = timer_ms(); longjmp(t->jb, 1); }
static int i2ctpm_xmit(TpmOps *me, const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len) { I2cTpm *tpm = container_of(me, I2cTpm, ops); if (!tpm->initialized && i2ctpm_init(tpm)) return -1; uint32_t count, ordinal; memcpy(&count, sendbuf + TpmCmdCountOffset, sizeof(count)); count = betohl(count); memcpy(&ordinal, sendbuf + TpmCmdOrdinalOffset, sizeof(ordinal)); ordinal = betohl(ordinal); if (count == 0) { printf("%s: No data.\n", __func__); return -1; } if (count > sbuf_size) { printf("%s: Invalid count value %x, max %zx.\n", __func__, count, sbuf_size); return -1; } assert(tpm->chip_ops.send); ssize_t rc = tpm->chip_ops.send(&tpm->chip_ops, sendbuf, count); if (rc < 0) { printf("%s: tpm_send: error %zd\n", __func__, rc); *rbuf_len = 0; return -1; } uint64_t start = timer_us(0); while (1) { assert(tpm->chip_ops.status); uint8_t status = tpm->chip_ops.status(&tpm->chip_ops); if ((status & tpm->req_complete_mask) == tpm->req_complete_val) { break; } if (status == tpm->req_canceled) { printf("%s: Operation canceled.\n", __func__); return -1; } mdelay(1); // Two minute timeout. if (timer_us(start) > 2 * 60 * 1000 * 1000) { if (tpm->chip_ops.cancel) tpm->chip_ops.cancel(&tpm->chip_ops); printf("%s: Operation timed out.\n", __func__); return -1; } } ssize_t len = tpm->chip_ops.recv(&tpm->chip_ops, recvbuf, *rbuf_len); if (len < 0) { printf("%s: tpm_recv: error %zd\n", __func__, len); *rbuf_len = 0; return -1; } if (len < 10) { printf("%s: Too few bytes received (%zd).\n", __func__, len); *rbuf_len = 0; return -1; } if (len > *rbuf_len) { printf("%s: Too many bytes received (%zd).\n", __func__, len); *rbuf_len = len; return -1; } *rbuf_len = len; return 0; }