struct request * rq_create(struct sourcelist *sl,char *spec,int64_t version, int64_t offset,int64_t length, req_fn done,void *priv) { struct request *rq; log_info(("creating request spec='%s' offset=%"PRId64"+%"PRId64, spec,offset,length)); rq = safe_malloc(sizeof(struct request)); ref_create(&(rq->r)); ref_on_release(&(rq->r),rq_ref_release,rq); ref_on_free(&(rq->r),rq_ref_free,rq); rq->sl = sl; rq->spec = strdup(spec); rq->version = version; rq->out = 0; rq->chunks = 0; rq->failed_errno = 0; rq->offset = offset; rq->length = length; rq->done = done; rq->priv = priv; rq->start = microtime(); sl_acquire(sl); ranges_init(&(rq->desired)); ranges_add(&(rq->desired),rq->offset,rq->offset+rq->length); return rq; }
void rq_found_data(struct request *rq,struct chunk *c) { struct chunk *d; struct ranges r; struct rangei ri; int64_t x,y; while(c) { log_debug(("processing report of data at %"PRId64"+%"PRId64, c->offset,c->length)); /* Help satisfy request */ ranges_init(&r); ranges_add(&r,c->offset,c->offset+c->length); ranges_remove(&r,0,rq->offset); ranges_remove(&r,rq->offset+rq->length,INT64_MAX); ranges_start(&r,&ri); while(ranges_next(&ri,&x,&y)) { log_debug(("copying range %"PRId64"-%"PRId64,x,y)); memcpy(rq->out+x-rq->offset,c->out+x-c->offset,y-x); } ranges_free(&r); ranges_remove(&(rq->desired),c->offset,c->offset+c->length); /* Update desire given knoledge of eof */ if(c->eof) { log_debug(("early eof: rest of file does not exist")); ranges_remove(&(rq->desired),c->offset+c->length,INT64_MAX); } /* Move chunks to request (for later write) */ src_acquire(c->origin); d = c->next; c->next = rq->chunks; rq->chunks = c; c = d; } }
static void used_list_initialize(void) { static int initialized; if (initialized) return; ranges_init(&used); // Add regions depthcharge occupies. ranges_add(&used, (uintptr_t)&_start, (uintptr_t)&_end); // Remove trampoline area if it is non-zero in size. if (&_tramp_start != &_tramp_end) ranges_add(&used, (uintptr_t)&_tramp_start, (uintptr_t)&_tramp_end); initialized = 1; }
int memory_wipe_unused(void) { Ranges ranges; // Process the memory map from coreboot. ranges_init(&ranges); for (int i = 0; i < lib_sysinfo.n_memranges; i++) { struct memrange *range = &lib_sysinfo.memrange[i]; uint64_t start = range->base; uint64_t end = range->base + range->size; switch (range->type) { case CB_MEM_RAM: ranges_add(&ranges, start, end); break; case CB_MEM_RESERVED: case CB_MEM_ACPI: case CB_MEM_NVS: case CB_MEM_UNUSABLE: case CB_MEM_VENDOR_RSVD: case CB_MEM_TABLE: ranges_sub(&ranges, start, end); break; default: printf("Unrecognized memory type %d!\n", range->type); return 1; } } // Exclude memory that's being used. used_list_initialize(); ranges_for_each(&used, &remove_range, &ranges); // Do the wipe. printf("Wipe memory regions:\n"); ranges_for_each(&ranges, &unused_memset, NULL); ranges_teardown(&ranges); return 0; }
void memory_mark_used(uint64_t start, uint64_t end) { used_list_initialize(); ranges_add(&used, start, end); }