int mmio_map(struct mmio *io, unsigned long base, size_t length) { memset(io, 0, sizeof(*io)); io->iobase = base; io->offset = 0; io->range = length; mmio_normalize(io); mmio_init(io); return 0; }
// Initialize and start PSL thread // // The return value is encode int a 16-bit value divided into 4 for each // possible adapter. Then the 4 bits in each adapter represent the 4 possible // AFUs on an adapter. For example: afu0.0 is 0x8000 and afu3.0 is 0x0008. uint16_t psl_init(struct psl **head, struct parms *parms, char *id, char *host, int port, pthread_mutex_t * lock, FILE * dbg_fp) { struct psl *psl; struct job_event *reset; uint16_t location; location = 0x8000; if ((psl = (struct psl *)calloc(1, sizeof(struct psl))) == NULL) { perror("malloc"); error_msg("Unable to allocation memory for psl"); goto init_fail; } psl->timeout = parms->timeout; if ((strlen(id) != 6) || strncmp(id, "afu", 3) || (id[4] != '.')) { warn_msg("Invalid afu name: %s", id); goto init_fail; } if ((id[3] < '0') || (id[3] > '3')) { warn_msg("Invalid afu major: %c", id[3]); goto init_fail; } if ((id[5] < '0') || (id[5] > '3')) { warn_msg("Invalid afu minor: %c", id[5]); goto init_fail; } psl->dbg_fp = dbg_fp; psl->major = id[3] - '0'; psl->minor = id[5] - '0'; psl->dbg_id = psl->major << 4; psl->dbg_id |= psl->minor; location >>= (4 * psl->major); location >>= psl->minor; if ((psl->name = (char *)malloc(strlen(id) + 1)) == NULL) { perror("malloc"); error_msg("Unable to allocation memory for psl->name"); goto init_fail; } strcpy(psl->name, id); if ((psl->host = (char *)malloc(strlen(host) + 1)) == NULL) { perror("malloc"); error_msg("Unable to allocation memory for psl->host"); goto init_fail; } strcpy(psl->host, host); psl->port = port; psl->client = NULL; psl->idle_cycles = PSL_IDLE_CYCLES; psl->lock = lock; // Connect to AFU psl->afu_event = (struct AFU_EVENT *)malloc(sizeof(struct AFU_EVENT)); if (psl->afu_event == NULL) { perror("malloc"); goto init_fail; } info_msg("Attempting to connect AFU: %s @ %s:%d", psl->name, psl->host, psl->port); if (psl_init_afu_event(psl->afu_event, psl->host, psl->port) != PSL_SUCCESS) { warn_msg("Unable to connect AFU: %s @ %s:%d", psl->name, psl->host, psl->port); goto init_fail; } // DEBUG debug_afu_connect(psl->dbg_fp, psl->dbg_id); // Initialize job handler if ((psl->job = job_init(psl->afu_event, &(psl->state), psl->name, psl->dbg_fp, psl->dbg_id)) == NULL) { perror("job_init"); goto init_fail; } // Initialize mmio handler if ((psl->mmio = mmio_init(psl->afu_event, psl->timeout, psl->name, psl->dbg_fp, psl->dbg_id)) == NULL) { perror("mmio_init"); goto init_fail; } // Initialize cmd handler if ((psl->cmd = cmd_init(psl->afu_event, parms, psl->mmio, &(psl->state), psl->name, psl->dbg_fp, psl->dbg_id)) == NULL) { perror("cmd_init"); goto init_fail; } // Set credits for AFU if (psl_aux1_change(psl->afu_event, psl->cmd->credits) != PSL_SUCCESS) { warn_msg("Unable to set credits"); goto init_fail; } // Start psl loop thread if (pthread_create(&(psl->thread), NULL, _psl_loop, psl)) { perror("pthread_create"); goto init_fail; } // Add psl to list while ((*head != NULL) && ((*head)->major < psl->major)) { head = &((*head)->_next); } while ((*head != NULL) && ((*head)->major == psl->major) && ((*head)->minor < psl->minor)) { head = &((*head)->_next); } psl->_next = *head; if (psl->_next != NULL) psl->_next->_prev = psl; *head = psl; // Send reset to AFU reset = add_job(psl->job, PSL_JOB_RESET, 0L); while (psl->job->job == reset) { /*infinite loop */ lock_delay(psl->lock); } // Read AFU descriptor psl->state = PSLSE_DESC; read_descriptor(psl->mmio, psl->lock); // Finish PSL configuration psl->state = PSLSE_IDLE; if (dedicated_mode_support(psl->mmio)) { // AFU supports Dedicated Mode psl->max_clients = 1; } if (directed_mode_support(psl->mmio)) { // AFU supports Directed Mode psl->max_clients = psl->mmio->desc.num_of_processes; } if (psl->max_clients == 0) { error_msg("AFU programming model is invalid"); goto init_fail; } psl->client = (struct client **)calloc(psl->max_clients, sizeof(struct client *)); psl->cmd->client = psl->client; psl->cmd->max_clients = psl->max_clients; return location; init_fail: if (psl) { if (psl->afu_event) { psl_close_afu_event(psl->afu_event); free(psl->afu_event); } if (psl->host) free(psl->host); if (psl->name) free(psl->name); free(psl); } pthread_mutex_unlock(lock); return 0; }