void *handle_accept_req(void* arg) { consensus_component* comp = arg; db_key_type start; db_key_type end; db_key_type index; dare_log_entry_t* entry; set_affinity(1); for (;;) { if (comp->cur_view->leader_id != *comp->node_id) { comp->uc(comp->up_para); entry = log_get_entry(SRV_DATA->log, &SRV_DATA->log->end); if (entry->data_size != 0) { char* dummy = (char*)((char*)entry + log_entry_len(entry) - 1); if (*dummy == DUMMY_END) // atmoic opeartion { #ifdef MEASURE_LATENCY clock_handler c_k; clock_init(&c_k); clock_add(&c_k); #endif if(entry->msg_vs.view_id < comp->cur_view->view_id){ // TODO //goto reloop; } // if we this message is not from the current leader if(entry->msg_vs.view_id == comp->cur_view->view_id && entry->node_id != comp->cur_view->leader_id){ // TODO //goto reloop; } // update highest seen request if(view_stamp_comp(&entry->msg_vs, comp->highest_seen_vs) > 0){ *(comp->highest_seen_vs) = entry->msg_vs; } db_key_type record_no = vstol(&entry->msg_vs); // record the data persistently request_record* record_data = (request_record*)((char*)entry + offsetof(dare_log_entry_t, data_size)); store_record(comp->db_ptr, sizeof(record_no), &record_no, REQ_RECORD_SIZE(record_data) - 1, record_data); #ifdef MEASURE_LATENCY clock_add(&c_k); #endif SRV_DATA->log->tail = SRV_DATA->log->end; SRV_DATA->log->end += log_entry_len(entry); uint32_t my_id = *comp->node_id; uint32_t offset = (uint32_t)(offsetof(dare_log_t, entries) + SRV_DATA->log->tail + ACCEPT_ACK_SIZE * my_id); accept_ack* reply = (accept_ack*)((char*)entry + ACCEPT_ACK_SIZE * my_id); reply->node_id = my_id; reply->msg_vs.view_id = entry->msg_vs.view_id; reply->msg_vs.req_id = entry->msg_vs.req_id; if (entry->type == P_OUTPUT) { // up = get_mapping_fd() is defined in ev_mgr.c int fd = comp->ug(entry->clt_id, comp->up_para); // consider entry->data as a pointer. uint64_t hash = get_output_hash(fd, *(long*)entry->data); reply->hash = hash; } rem_mem_t rm; dare_ib_ep_t *ep = (dare_ib_ep_t*)SRV_DATA->config.servers[entry->node_id].ep; memset(&rm, 0, sizeof(rem_mem_t)); uint32_t *send_count_ptr = &(ep->rc_ep.rc_qp.send_count); int send_flags, poll_completion = 0; if((*send_count_ptr & S_DEPTH_) == 0) send_flags = IBV_SEND_SIGNALED; else send_flags = 0; if ((*send_count_ptr & S_DEPTH_) == S_DEPTH_) poll_completion = 1; (*send_count_ptr)++; rm.raddr = ep->rc_ep.rmt_mr.raddr + offset; rm.rkey = ep->rc_ep.rmt_mr.rkey; post_send(entry->node_id, reply, ACCEPT_ACK_SIZE, IBDEV->lcl_mr, IBV_WR_RDMA_WRITE, &rm, send_flags, poll_completion); if(view_stamp_comp(&entry->req_canbe_exed, comp->highest_committed_vs) > 0) { start = vstol(comp->highest_committed_vs)+1; end = vstol(&entry->req_canbe_exed); for(index = start; index <= end; index++) { comp->ucb(index,comp->up_para); } *(comp->highest_committed_vs) = entry->req_canbe_exed; } #ifdef MEASURE_LATENCY clock_add(&c_k); clock_display(comp->sys_log_file, &c_k); #endif } } } } };
/* this is really aimed at the lcd panel. That said, there are two display * devices on this part and we may someday want to extend it for other boards. */ void display_startup(device_t dev) { struct soc_nvidia_tegra124_config *config = dev->chip_info; struct display_controller *disp_ctrl = (void *)config->display_controller; struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE; struct tegra_dc *dc = &dc_data; u32 plld_rate; /* init dc */ dc->base = (void *)TEGRA_ARM_DISPLAYA; dc->config = config; config->dc_data = dc; /* Note dp_init may read EDID and change some config values. */ dp_init(config); /* should probably just make it all MiB ... in future */ u32 framebuffer_size_mb = config->framebuffer_size / MiB; u32 framebuffer_base_mb= config->framebuffer_base / MiB; /* light it all up */ /* This one may have been done in romstage but that's ok for now. */ if (config->panel_vdd_gpio){ gpio_output(config->panel_vdd_gpio, 1); printk(BIOS_SPEW,"%s: panel_vdd setting gpio %08x to %d\n", __func__, config->panel_vdd_gpio, 1); } udelay(config->vdd_delay_ms * 1000); if (config->backlight_vdd_gpio){ gpio_output(config->backlight_vdd_gpio, 1); printk(BIOS_SPEW,"%s: backlight vdd setting gpio %08x to %d\n", __func__, config->backlight_vdd_gpio, 1); } if (config->lvds_shutdown_gpio){ gpio_output(config->lvds_shutdown_gpio, 0); printk(BIOS_SPEW,"%s: lvds shutdown setting gpio %08x to %d\n", __func__, config->lvds_shutdown_gpio, 0); } if (framebuffer_size_mb == 0){ framebuffer_size_mb = ALIGN_UP(config->xres * config->yres * (config->framebuffer_bits_per_pixel / 8), MiB)/MiB; } if (! framebuffer_base_mb) framebuffer_base_mb = fb_base_mb(); config->framebuffer_size = framebuffer_size_mb * MiB; config->framebuffer_base = framebuffer_base_mb * MiB; mmu_config_range(framebuffer_base_mb, framebuffer_size_mb, config->cache_policy); printk(BIOS_SPEW, "LCD frame buffer at %dMiB to %dMiB\n", framebuffer_base_mb, framebuffer_base_mb + framebuffer_size_mb); /* GPIO magic here if needed to start powering up things. You * really only want to enable vdd, wait a bit, and then enable * the panel. However ... the timings in the tegra20 dts make * no sense to me. I'm pretty sure they're wrong. * The panel_vdd is done in the romstage, so we need only * light things up here once we're sure it's all working. */ /* The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the * update_display_mode() for detail. */ plld_rate = clock_display(config->pixel_clock * 2); if (plld_rate == 0) { printk(BIOS_ERR, "dc: clock init failed\n"); return; } else if (plld_rate != config->pixel_clock * 2) { printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate); config->pixel_clock = plld_rate / 2; } /* Init dc */ if (tegra_dc_init(disp_ctrl)) { printk(BIOS_ERR, "dc: init failed\n"); return; } /* Configure dc mode */ if (update_display_mode(disp_ctrl, config)) { printk(BIOS_ERR, "dc: failed to configure display mode.\n"); return; } /* Enable dp */ dp_enable(dc->out); /* Init frame buffer */ memset((void *)(framebuffer_base_mb*MiB), 0x00, framebuffer_size_mb*MiB); update_window(disp_ctrl, config); /* Set up Tegra PWM n (where n is specified in config->pwm) to drive the * panel backlight. */ printk(BIOS_SPEW, "%s: enable panel backlight pwm\n", __func__); WRITEL(((1 << NV_PWM_CSR_ENABLE_SHIFT) | (220 << NV_PWM_CSR_PULSE_WIDTH_SHIFT) | /* 220/256 */ 0x02e), /* frequency divider */ &pwm->pwm[config->pwm].csr); udelay(config->pwm_to_bl_delay_ms * 1000); if (config->backlight_en_gpio){ gpio_output(config->backlight_en_gpio, 1); printk(BIOS_SPEW,"%s: backlight enable setting gpio %08x to %d\n", __func__, config->backlight_en_gpio, 1); } printk(BIOS_INFO, "%s: display init done.\n", __func__); /* tell depthcharge ... */ struct edid edid; edid.bytes_per_line = ((config->xres * config->framebuffer_bits_per_pixel / 8 + 31) / 32 * 32); edid.x_resolution = edid.bytes_per_line / (config->framebuffer_bits_per_pixel / 8); edid.y_resolution = config->yres; edid.framebuffer_bits_per_pixel = config->framebuffer_bits_per_pixel; set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB)); }
dare_log_entry_t* leader_handle_submit_req(struct consensus_component_t* comp, size_t data_size, void* data, uint8_t type, view_stamp* clt_id) { #ifdef MEASURE_LATENCY clock_handler c_k; clock_init(&c_k); clock_add(&c_k); #endif #ifdef USE_SPIN_LOCK pthread_spin_lock(&comp->spinlock); #else pthread_mutex_lock(&comp->lock); #endif view_stamp next = get_next_view_stamp(comp); if (type == P_TCP_CONNECT) { clt_id->view_id = next.view_id; clt_id->req_id = next.req_id; } db_key_type record_no = vstol(&next); comp->highest_seen_vs->req_id = comp->highest_seen_vs->req_id + 1; dare_log_entry_t *entry = log_add_new_entry(SRV_DATA->log); if (!log_fit_entry_header(SRV_DATA->log, SRV_DATA->log->end)) { SRV_DATA->log->end = 0; } SRV_DATA->log->tail = SRV_DATA->log->end; entry->data_size = data_size + 1; SRV_DATA->log->end += log_entry_len(entry); uint32_t offset = (uint32_t)(offsetof(dare_log_t, entries) + SRV_DATA->log->tail); dare_ib_ep_t *ep; uint32_t i, *send_count_ptr; int send_flags[MAX_SERVER_COUNT], poll_completion[MAX_SERVER_COUNT] = {0}; for (i = 0; i < comp->group_size; i++) { ep = (dare_ib_ep_t*)SRV_DATA->config.servers[i].ep; if (i == *SRV_DATA->config.idx || 0 == ep->rc_connected) continue; send_count_ptr = &(ep->rc_ep.rc_qp.send_count); if((*send_count_ptr & S_DEPTH_) == 0) send_flags[i] = IBV_SEND_SIGNALED; else send_flags[i] = 0; if ((*send_count_ptr & S_DEPTH_) == S_DEPTH_) poll_completion[i] = 1; (*send_count_ptr)++; } #ifdef USE_SPIN_LOCK pthread_spin_unlock(&comp->spinlock); #else pthread_mutex_unlock(&comp->lock); #endif entry->req_canbe_exed.view_id = comp->highest_committed_vs->view_id; entry->req_canbe_exed.req_id = comp->highest_committed_vs->req_id; if (data != NULL) memcpy(entry->data,data,data_size); entry->msg_vs = next; entry->node_id = *comp->node_id; entry->type = type; entry->clt_id.view_id = (type != P_NOP)?clt_id->view_id:0; entry->clt_id.req_id = (type != P_NOP)?clt_id->req_id:0; request_record* record_data = (request_record*)((char*)entry + offsetof(dare_log_entry_t, data_size)); if(store_record(comp->db_ptr, sizeof(record_no), &record_no, REQ_RECORD_SIZE(record_data) - 1, record_data)) { fprintf(stderr, "Can not save record from database.\n"); goto handle_submit_req_exit; } #ifdef MEASURE_LATENCY clock_add(&c_k); #endif char* dummy = (char*)((char*)entry + log_entry_len(entry) - 1); *dummy = DUMMY_END; uint32_t my_id = *comp->node_id; uint64_t bit_map = (1<<my_id); rem_mem_t rm; memset(&rm, 0, sizeof(rem_mem_t)); for (i = 0; i < comp->group_size; i++) { ep = (dare_ib_ep_t*)SRV_DATA->config.servers[i].ep; if (i == *SRV_DATA->config.idx || 0 == ep->rc_connected) continue; rm.raddr = ep->rc_ep.rmt_mr.raddr + offset; rm.rkey = ep->rc_ep.rmt_mr.rkey; post_send(i, entry, log_entry_len(entry), IBDEV->lcl_mr, IBV_WR_RDMA_WRITE, &rm, send_flags[i], poll_completion[i]); } recheck: for (i = 0; i < MAX_SERVER_COUNT; i++) { if (entry->ack[i].msg_vs.view_id == next.view_id && entry->ack[i].msg_vs.req_id == next.req_id) { bit_map = bit_map | (1<<entry->ack[i].node_id); } } if (reached_quorum(bit_map, comp->group_size)) { //TODO: do we need the lock here? while (entry->msg_vs.req_id > comp->highest_committed_vs->req_id + 1); comp->highest_committed_vs->req_id = comp->highest_committed_vs->req_id + 1; #ifdef MEASURE_LATENCY clock_add(&c_k); clock_display(comp->sys_log_file, &c_k); #endif }else{ goto recheck; } handle_submit_req_exit: return entry; }