Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8838
-gerrit
commit 7fc66dcd3e85019edde6f11974134d4e5428e172 Author: Aaron Durbin adurbin@chromium.org Date: Fri Mar 20 09:42:05 2015 -0500
program loading: provide one cache maintenance callback
Instead of having 2 different functions to call when a program is loaded provide a single callback with flags parameter. The previous callbacks for cache management routines did this:
for_each_program_segment: arch_program_segment_loaded(start, size); arch_program_loaded();
Now, use one callback instead: for_each_program_segment: arch_segment_loaded(start, size, SEG_FINAL?);
Change-Id: I3811cba92e3355d172f605e4444f053321b07a2a Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/include/program_loading.h | 12 ++++++++---- src/lib/arch_ops.c | 10 +++------- src/lib/cbfs.c | 3 +-- src/lib/rmodule.c | 5 ++--- src/lib/selfboot.c | 17 +++++++++-------- 5 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/src/include/program_loading.h b/src/include/program_loading.h index ca61c16..85ccd3c 100644 --- a/src/include/program_loading.h +++ b/src/include/program_loading.h @@ -23,11 +23,15 @@ #include <stdint.h> #include <stddef.h>
-/* For each segment of a program loaded this function is called*/ -void arch_program_segment_loaded(uintptr_t start, size_t size); +enum { + /* Last segment of program. Can be used to take different actions for + * cache maintenance of a program load. */ + SEG_FINAL = 1 << 0, +};
-/* Upon completion of loading a program this function is called */ -void arch_program_loaded(void); +/* Called for each segment of a program loaded. The PROG_FLAG_FINAL will be + * set on the last segment loaded. */ +void arch_segment_loaded(uintptr_t start, size_t size, int flags);
/************************ * ROMSTAGE LOADING * diff --git a/src/lib/arch_ops.c b/src/lib/arch_ops.c index f02b342..b9f5719 100644 --- a/src/lib/arch_ops.c +++ b/src/lib/arch_ops.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Imagination Technologies + * Copyright 2015 Google Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,14 +21,9 @@ #include <program_loading.h>
/* For each segment of a program loaded this function is called*/ -__attribute__ ((weak)) void arch_program_segment_loaded(uintptr_t start, - size_t size) +void __attribute__ ((weak)) arch_segment_loaded(uintptr_t start, size_t size, + int flags) { /* do nothing */ }
-/* Upon completion of loading a program this function is called */ -__attribute__ ((weak)) void arch_program_loaded(void) -{ - /* do nothing */ -} diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index cc30940..90ddc31 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -112,8 +112,7 @@ void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset) media->unmap(media, data); }
- arch_program_segment_loaded(stage.load, stage.memlen); - arch_program_loaded(); + arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL); DEBUG("stage loaded\n");
return (void *)(uintptr_t)stage.entry; diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c index c2bf33c..791029a 100644 --- a/src/lib/rmodule.c +++ b/src/lib/rmodule.c @@ -200,9 +200,8 @@ int rmodule_load(void *base, struct rmodule *module) return -1; rmodule_clear_bss(module);
- arch_program_segment_loaded((uintptr_t)module->location, - rmodule_memory_size(module)); - arch_program_loaded(); + arch_segment_loaded((uintptr_t)module->location, + rmodule_memory_size(module), SEG_FINAL);
return 0; } diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index fe73c0c..b29a34e 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -314,9 +314,16 @@ static int load_self_segments( struct payload *payload) { struct segment *ptr; + struct segment *last_non_empty; const unsigned long one_meg = (1UL << 20); unsigned long bounce_high = lb_end;
+ /* Determine last non-empty loaded segment. */ + last_non_empty = NULL; + for(ptr = head->next; ptr != head; ptr = ptr->next) + if (ptr->s_filesz != 0) + last_non_empty = ptr; + for(ptr = head->next; ptr != head; ptr = ptr->next) { if (bootmem_region_targets_usable_ram(ptr->s_dstaddr, ptr->s_memsz)) @@ -442,17 +449,11 @@ static int load_self_segments( * Each architecture can perform additonal operations * on the loaded segment */ - arch_program_segment_loaded((uintptr_t)dest, - ptr->s_memsz); + arch_segment_loaded((uintptr_t)dest, ptr->s_memsz, + last_non_empty == ptr ? SEG_FINAL : 0); } }
- /* - * Each architecture can perform additonal operations once the entire - * program is loaded - */ - arch_program_loaded(); - return 1; }