/* * Executar uma função (indicada pelo opcode na msg) e retorna o resultado na * própria struct msg. * Retorna 0 (OK) ou -1 (erro, por exemplo, tabela nao inicializada). */ int invoke(struct message_t *msg) { int retVal = 0; char *key; struct entry_t *entry; if(sharedPtable && msg) { switch (msg->opcode) { case OP_RT_GET: // table_get: (struct table_t* char*) -> (struct data_t*) if(msg->content.key) { key = msg->content.key; if(!(msg->content.value = ptable_get(sharedPtable, key))) { if(!(msg->content.value = data_create(0))) { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } } if(msg->content.value) { msg->opcode ++; // Incrementa para dizer que esta mensagem contem o resultado msg->c_type = CT_VALUE; free(key); } } else { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } break; case OP_RT_PUT: // table_put: (struct table_t* char* struct data_t*) -> (int) if(msg->content.entry) { entry = msg->content.entry; if((retVal = ptable_put(sharedPtable, entry->key, entry->value)) != -1) { msg->content.result = retVal; msg->opcode ++; msg->c_type = CT_RESULT; } else { // Deu erro pq ficamos sem espaço de log. //cria um ficheiro temporário com o estado da tabela if(pmanager_store_table(sharedPtable->pmanager, sharedPtable->table) < 0) { ERROR("persistent_table: pmanager_store_table"); msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } //cria um ficheiro temporário com o estado da tabela if(pmanager_rotate_log(sharedPtable->pmanager) != 0) { ERROR("persistent_table: pmanager_rotate_log"); msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } if((retVal = ptable_put(sharedPtable, entry->key, entry->value)) != -1) { msg->content.result = retVal; msg->opcode ++; msg->c_type = CT_RESULT; } else { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } } entry_destroy(entry); } else { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } break; case OP_RT_SIZE: // table_size: (struct table_t*) -> (int) msg->content.result = ptable_size(sharedPtable); msg->opcode ++; msg->c_type = CT_RESULT; // Nao temos nada para libertar... break; case OP_RT_DEL: // table_del: (struct table_t* char*) -> (int) if(msg->content.key) { key = msg->content.key; msg->content.key = NULL; retVal = ptable_del(sharedPtable, key); msg->content.result = retVal; msg->opcode ++; msg->c_type = CT_RESULT; free(key); } else { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } break; case OP_RT_GETKEYS: // table_get_keys: (struct table_t*) -> (char**) if((msg->content.keys = ptable_get_keys(sharedPtable))) { msg->opcode ++; msg->c_type = CT_KEYS; } else { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } // Não temos nada para libertar... break; case OP_RT_GETTS: // table_get: (struct table_t* char*) -> (int) if(msg->content.key) { key = strdup(msg->content.key); free(msg->content.key); // Verifica a validade da resposta if((msg->content.timestamp = ptable_get_ts(sharedPtable, key)) < 0) { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } else if(msg->content.timestamp >= 0) { msg->opcode ++; // Incrementa para dizer que esta mensagem contem o resultado msg->c_type = CT_TIMESTAMP; } } else { msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; } free(key); break; default: ERROR("opcode"); msg->opcode = OP_RT_ERROR; msg->c_type = CT_RESULT; msg->content.result = -1; break; } } else { ERROR("NULL sharedPtable"); retVal = -1; } return retVal; }
void boot_linux(void *kernel, unsigned *tags, const char *cmdline, unsigned machtype, void *ramdisk, unsigned ramdisk_size) { unsigned *ptr = tags; unsigned pcount = 0; void (*entry)(unsigned,unsigned,unsigned*) = kernel; struct ptable *ptable; int cmdline_len = 0; int have_cmdline = 0; int pause_at_bootup = 0; /* CORE */ *ptr++ = 2; *ptr++ = 0x54410001; if (ramdisk_size) { *ptr++ = 4; *ptr++ = 0x54420005; *ptr++ = (unsigned)ramdisk; *ptr++ = ramdisk_size; } ptr = target_atag_mem(ptr); if (!target_is_emmc_boot()) { /* Skip NAND partition ATAGS for eMMC boot */ if ((ptable = flash_get_ptable()) && (ptable->count != 0)) { int i; for(i=0; i < ptable->count; i++) { struct ptentry *ptn; ptn = ptable_get(ptable, i); if (ptn->type == TYPE_APPS_PARTITION) pcount++; } *ptr++ = 2 + (pcount * (sizeof(struct atag_ptbl_entry) / sizeof(unsigned))); *ptr++ = 0x4d534d70; for (i = 0; i < ptable->count; ++i) ptentry_to_tag(&ptr, ptable_get(ptable, i)); } } if (cmdline && cmdline[0]) { cmdline_len = strlen(cmdline); have_cmdline = 1; } if (target_is_emmc_boot()) { cmdline_len += strlen(emmc_cmdline); } if (target_pause_for_battery_charge()) { pause_at_bootup = 1; cmdline_len += strlen(battchg_pause); } if (cmdline_len > 0) { const char *src; char *dst; unsigned n; /* include terminating 0 and round up to a word multiple */ n = (cmdline_len + 4) & (~3); *ptr++ = (n / 4) + 2; *ptr++ = 0x54410009; dst = (char *)ptr; if (have_cmdline) { src = cmdline; while ((*dst++ = *src++)); } if (target_is_emmc_boot()) { src = emmc_cmdline; if (have_cmdline) --dst; have_cmdline = 1; while ((*dst++ = *src++)); } if (pause_at_bootup) { src = battchg_pause; if (have_cmdline) --dst; while ((*dst++ = *src++)); } ptr += (n / 4); } /* END */ *ptr++ = 0; *ptr++ = 0; dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n", kernel, ramdisk, ramdisk_size); if (cmdline) dprintf(INFO, "cmdline: %s\n", cmdline); enter_critical_section(); platform_uninit_timer(); arch_disable_cache(UCACHE); arch_disable_mmu(); #if DISPLAY_SPLASH_SCREEN display_shutdown(); #endif entry(0, machtype, tags); }