void serial_irq_handle(void) { int UNUSED error; error = serial_lock(); bool got_command = clear_iir(); error = serial_irq_acknowledge(); error = serial_unlock(); if (got_command) { handle_gdb(gdb_state); error = serial_lock(); clear_buffer(); command_wait = false; error = serial_unlock(); } }
static int fetch_nodelist(struct motefs_node *nodes) { int n, i, k, op, result, res = 0; uint8_t buf[MFS_DATA_SIZE]; serial_lock(); if (serial_send(0, MFS_OP_NODELIST, NULL, 0)) { res = -EIO; goto ret; } /* the mote should send exactly `node_count` packets */ for (i = 0; i < node_count; i++) { res = serial_receive(&n, &op, &result, buf, sizeof buf); if (res == -1 || !result || !(op & MFS_OP_NODELIST)) { res = -1; goto ret; } nodes[n].type = result; for (k = 0; k < MFS_DATA_SIZE; k++) nodes[n].name[k] = buf[k]; } ret: serial_unlock(); if (res < 0) return -1; return 0; }
void pre_init(void) { morecore_area = core_buf; morecore_size = SERVER_CORE_SIZE; serial_lock(); // Initialize the serial port set_dlab(0); // we always assume the dlab is 0 unless we explicitly change it disable_interrupt(); disable_fifo(); reset_lcr(); reset_mcr(); clear_iir(); set_baud_rate(BAUD_RATE); reset_state(); enable_fifo(); enable_interrupt(); clear_iir(); // all done init_colours(); /* query what getchar clients exist */ num_getchar_clients = getchar_num_badges(); getchar_clients = calloc(num_getchar_clients, sizeof(getchar_client_t)); for (int i = 0; i < num_getchar_clients; i++) { unsigned int badge = getchar_enumerate_badge(i); assert(badge <= num_getchar_clients); getchar_clients[badge].client_id = badge; getchar_clients[badge].buf = getchar_buf(badge); getchar_clients[badge].last_head = -1; } set_putchar(serial_putchar); serial_irq_reg_callback(serial_irq, 0); /* Start regular heartbeat of 500ms */ timeout_periodic(0, 500000000); serial_unlock(); }
static void timer_callback(void *data) { serial_lock(); if (done_output) { done_output = 0; } else if (has_data) { /* flush everything if no writes since last callback */ int i; for (i = 0; i < VM_NUM_GUESTS * 2; i++) { flush_buffer(i); } } serial_unlock(); }
static void internal_putchar(int b, int c) { serial_lock(); /* Add to buffer */ int index = output_buffers_used[b]; uint8_t *buffer = output_buffers[b]; buffer[index] = (uint8_t)c; output_buffers_used[b]++; if (index + 1 == GUEST_OUTPUT_BUFFER_SIZE || (index >= 1 && is_newline(buffer + index - 1)) || last_out == b) { flush_buffer(b); } has_data = 1; serial_unlock(); }
void gdb_printf(const char *format, ...) { va_list arg; char text_buf[MAX_PRINTF_LENGTH]; va_start(arg, format); vsnprintf(text_buf, MAX_PRINTF_LENGTH, format, arg); va_end(arg); int UNUSED error; error = serial_lock(); for (int i = 0; i < strlen(text_buf); i++) { serial_putchar(text_buf[i]); } error = serial_unlock(); }
void serial_init(gdb_state_t *gdb) { // Initialize the serial port int UNUSED error; error = serial_lock(); gdb_state = gdb; set_dlab(0); // we always assume the dlab is 0 unless we explicitly change it disable_interrupt(); disable_fifo(); reset_lcr(); reset_mcr(); clear_iir(); set_baud_rate(BAUD_RATE); reset_state(); enable_fifo(); enable_interrupt(); clear_iir(); initialise_buffer(); error = serial_unlock(); }
static int fetch_nodecount(int *count) { int op, result, res = 0; serial_lock(); res = serial_send(0, MFS_OP_NODECOUNT, NULL, 0); if (res == -1) goto ret; res = serial_receive(NULL, &op, &result, NULL, 0); if (res == -1 || !result || op != MFS_OP_NODECOUNT) { res = -EIO; goto ret; } *count = result; res = 0; ret: serial_unlock(); return res; }
static int op_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { (void) fi; (void) offset; int n, op, result, res = 0; uint8_t data[MFS_DATA_SIZE]; size_t i, len; char line[MFS_DATA_SIZE]; n = get_node(path); if (n == -1) return -ENOENT; /* copy one line without '\n' to temporary buffer * (and truncate it if too long) */ for (i = 0; i < MFS_DATA_SIZE - 1 && i < size && buf[i] != '\n'; i++) line[i] = buf[i]; line[i] = '\0'; len = i; /* convert the line to appropriate format which can be send as a serial * packet */ if (nodes[n].type & MFS_BOOL) { if (!strcmp(line, "true")) data[0] = 1; else if (!strcmp(line, "false")) data[0] = 0; else data[0] = atoi(line) != 0; len = 1; } else if (nodes[n].type & MFS_INT) { int64_t val = atoll(line); len = pack(data, "l", val); } else if (nodes[n].type & MFS_STR) { unsigned i; for (i = 0; i < len; i++) data[i] = line[i]; data[len] = '\0'; } serial_lock(); if (serial_send(n, MFS_OP_WRITE, data, len)) { res = -EIO; goto ret; } res = serial_receive(NULL, &op, &result, NULL, 0); if (res == -1 || !result || op != MFS_OP_WRITE) { res = -EIO; goto ret; } ret: serial_unlock(); if (!res) return size; return res; }
static int op_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { (void) fi; (void) offset; int n, i, op, result, res = 0; uint8_t data[MFS_DATA_SIZE]; n = get_node(path); if (n == -1) return -ENOENT; if (size <= MFSMSG_SIZE) return -EIO; serial_lock(); if (serial_send(n, MFS_OP_READ, NULL, 0)) { res = -EIO; goto ret; } res = serial_receive(NULL, &op, &result, data, sizeof data); if (res == -1 || !result || op != MFS_OP_READ) { res = -EIO; goto ret; } /* format reply */ switch (MFS_TYPE(nodes[n].type)) { case MFS_BOOL: strcpy(buf, (*data) ? "1" : "0"); break; case MFS_INT: { int64_t val; unpack(data, "l", &val); sprintf(buf, "%" PRIi64, val); } break; case MFS_STR: for (i = 0; i < MFS_DATA_SIZE - 1; i++) buf[i] = data[i]; buf[i] = '\0'; break; } /* add a newline because that looks better */ strcat(buf, "\n"); res = strlen(buf); ret: serial_unlock(); return res; }
static void serial_irq(void *cookie) { serial_lock(); clear_iir(); serial_irq_reg_callback(serial_irq, cookie); serial_unlock(); }