void dram_system_free(struct dram_system_t *system) { int i; /* Free controller list */ for (i = 0; i < system->num_logical_channels; i++) dram_controller_free(list_get(system->dram_controller_list, i)); list_free(system->dram_controller_list); /* Freeing the DRAM request list */ for (i = 0; i < list_count(system->dram_request_list); i++) dram_request_free(list_get(system->dram_request_list, i)); list_free(system->dram_request_list); /* Free */ free(system->name); free(system); }
void dram_bank_info_free(struct dram_bank_info_t *info) { int i, num_requests, num_commands; /* Free command queue */ num_commands = list_count(info->command_queue); for (i = 0; i < num_commands; i++) dram_command_free(list_get(info->command_queue, i)); list_free(info->command_queue); /* Free request queue */ num_requests = list_count(info->request_queue); for (i = 0; i < num_requests; i++) dram_request_free(list_get(info->request_queue, i)); list_free(info->request_queue); /* Free */ free(info); }
void dram_controller_process_request(struct dram_controller_t *controller) { int i; unsigned int num_bank_info; unsigned int row_id, column_id; struct dram_request_t *request; struct dram_bank_info_t *info; struct dram_command_t *command_precharge; struct dram_command_t *command_activate; struct dram_command_t *command_access; /* Go through bank info list */ num_bank_info = list_count(controller->dram_bank_info_list); for (i = 0; i < num_bank_info; i++) { /* Locate bank info */ info = list_get(controller->dram_bank_info_list, i); /* Fetch a request from request queue */ request = list_dequeue(info->request_queue); if (request) { dram_decode_address(request->system, request->addr, NULL, NULL, &row_id, NULL, &column_id, NULL); /* Determine policy to be used */ switch (controller->rb_policy) { /* Open page row buffer policy */ case open_page_row_buffer_policy: /* Row hit */ if (info->row_buffer_valid && info->active_row_id == row_id) { /* Create single read/write command */ command_access = dram_command_create(); command_access->dram = list_get(controller->dram_list, info->channel_id); if (request->type == request_type_read) { command_access->type = dram_command_read; command_access->u.read.rank_id = info->rank_id; command_access->u.read.bank_id = info->bank_id; command_access->u.read.column_id = column_id; } else if (request->type == request_type_write) { command_access->type = dram_command_write; command_access->u.write.rank_id = info->rank_id; command_access->u.write.bank_id = info->bank_id; command_access->u.write.column_id = column_id; } /* Append command to queue */ list_add(info->command_queue, command_access); } /* Row miss - different row was activated */ else if (info->row_buffer_valid) { /* Create pre, act, rd/wr three commands */ command_precharge = dram_command_create(); command_activate = dram_command_create(); command_access = dram_command_create(); /* Precharge */ command_precharge->type = dram_command_precharge; command_precharge->dram = list_get(controller->dram_list, info->channel_id); command_precharge->u.precharge.rank_id = info->rank_id; command_precharge->u.precharge.bank_id = info->bank_id; /* Activate */ command_activate->type = dram_command_activate; command_activate->dram = list_get(controller->dram_list, info->channel_id); command_activate->u.activate.rank_id = info->rank_id; command_activate->u.activate.bank_id = info->bank_id; command_activate->u.activate.row_id = row_id; /* Access */ command_access->dram = list_get(controller->dram_list, info->channel_id); if (request->type == request_type_read) { command_access->type = dram_command_read; command_access->u.read.rank_id = info->rank_id; command_access->u.read.bank_id = info->bank_id; command_access->u.read.column_id = column_id; } else if (request->type == request_type_write) { command_access->type = dram_command_write; command_access->u.write.rank_id = info->rank_id; command_access->u.write.bank_id = info->bank_id; command_access->u.write.column_id = column_id; } list_add(info->command_queue, command_precharge); list_add(info->command_queue, command_activate); list_add(info->command_queue, command_access); /* Update the active row status */ info->active_row_id = row_id; } /* Row miss - no row was activated */ else { /* Create act, rd/wr two commands */ command_activate = dram_command_create(); command_access = dram_command_create(); /* Activate */ command_activate->type = dram_command_activate; command_activate->dram = list_get(controller->dram_list, info->channel_id); command_activate->u.activate.rank_id = info->rank_id; command_activate->u.activate.bank_id = info->bank_id; command_activate->u.activate.row_id = row_id; /* Access */ command_access->dram = list_get(controller->dram_list, info->channel_id); if (request->type == request_type_read) { command_access->type = dram_command_read; command_access->u.read.rank_id = info->rank_id; command_access->u.read.bank_id = info->bank_id; command_access->u.read.column_id = column_id; } else if (request->type == request_type_write) { command_access->type = dram_command_write; command_access->u.write.rank_id = info->rank_id; command_access->u.write.bank_id = info->bank_id; command_access->u.write.column_id = column_id; } list_add(info->command_queue, command_activate); list_add(info->command_queue, command_access); /* Update the active row status */ info->row_buffer_valid = 1; info->active_row_id = row_id; } break; /* Close page row buffer policy */ case close_page_row_buffer_policy: /* Create act, rd/wr, pre three commands */ command_activate = dram_command_create(); command_access = dram_command_create(); command_precharge = dram_command_create(); /* Activate */ command_activate->type = dram_command_activate; command_activate->dram = list_get(controller->dram_list, info->channel_id); command_activate->u.activate.rank_id = info->rank_id; command_activate->u.activate.bank_id = info->bank_id; command_activate->u.activate.row_id = row_id; /* Access */ command_access->dram = list_get(controller->dram_list, info->channel_id); if (request->type == request_type_read) { command_access->type = dram_command_read; command_access->u.read.rank_id = info->rank_id; command_access->u.read.bank_id = info->bank_id; command_access->u.read.column_id = column_id; } else if (request->type == request_type_write) { command_access->type = dram_command_write; command_access->u.write.rank_id = info->rank_id; command_access->u.write.bank_id = info->bank_id; command_access->u.write.column_id = column_id; } /* Precharge */ command_precharge->type = dram_command_precharge; command_precharge->dram = list_get(controller->dram_list, info->channel_id); command_precharge->u.precharge.rank_id = info->rank_id; command_precharge->u.precharge.bank_id = info->bank_id; list_add(info->command_queue, command_activate); list_add(info->command_queue, command_access); list_add(info->command_queue, command_precharge); /* Update the active row status */ info->row_buffer_valid = 0; break; case hybird_page_row_buffer_policy: break; default: break; } dram_request_free(request); } } }