/* image.c -- start a node from a capsule image. See image.h. * * Nothing here uses the C library: the bare-metal kernel links this file. */ #include "v4/image.h" int v4_image_boot(v4_node *n, v4_exec_state *es, v4_heat *h, const v4_image *im, unsigned char *disk, unsigned blocks) { unsigned i; if (im->cell_bits != (unsigned)V4_CELL_BITS || im->node_words != (unsigned)V4_NODE_WORDS || im->data_ring != (unsigned)V4_DATA_RING || im->ret_ring != (unsigned)V4_RET_RING) return 0; v4_node_reset(n); v4_exec_reset(es); v4_heat_reset(h); for (i = 0; i < im->count; i++) if (v4_node_addr_ok(im->cells[i].addr)) n->mem[im->cells[i].addr] = im->cells[i].value; v4_node_console_attach(n, im->console_tx); v4_node_console_input_attach(n, im->console_rx, im->console_status); v4_node_stack_regs_attach(n, im->dstack_reg, im->rstack_reg); v4_node_error_attach(n, im->node_error); v4_node_fault_attach(n, im->fault_table); v4_node_port_attach(n, im->port); if (disk && blocks) v4_node_storage_attach(n, im->storage_reg, disk, blocks); n->mem[im->line_status] = V4_LINE_COMPLETED; n->p = im->idle; return 1; } int v4_image_waiting(const v4_node *n, const v4_image *im) { return n->input_pos == n->input_len && n->p >= im->key_start && n->p < im->key_end; } /* One byte of the node's memory: four to a cell, the first lowest, at either * cell width -- as C! stores them (v4/capsule/core.v4). */ static void put_byte(v4_node *n, v4_cell baddr, unsigned c) { v4_cell word = baddr / 4; unsigned shift = 8u * (unsigned)(baddr % 4); v4_ucell mask = (v4_ucell)0xFFu << shift; n->mem[word] = (v4_cell)(((v4_ucell)n->mem[word] & ~mask) | ((v4_ucell)(c & 0xFFu) << shift)); } int v4_line_begin(v4_node *n, const v4_image *im, const char *text, unsigned len) { unsigned i; if (len + 1u > im->tib_bytes) return 0; for (i = 0; i < len; i++) put_byte(n, im->tib + (v4_cell)i, (unsigned char)text[i]); put_byte(n, im->tib + (v4_cell)len, 0); n->mem[im->span] = (v4_cell)len; v4_rstack_reset(&n->rs); n->p = im->line; return 1; } int v4_line_done(const v4_node *n, const v4_image *im) { return n->p == im->idle; } int v4_line_status(const v4_node *n, const v4_image *im) { return (int)n->mem[im->line_status]; } void v4_image_seal(v4_node *n, const v4_image *im) { n->mem[im->boot_cells] = n->mem[im->dp]; n->mem[im->boot_cells + 1] = n->mem[im->latest]; n->mem[im->fence] = (n->mem[im->dp] + 3) / 4; }