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> Reviewed-on: http://review.coreboot.org/8838 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
committed by
Aaron Durbin
parent
ebf2ed4621
commit
6e76fff969
@ -23,11 +23,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* For each segment of a program loaded this function is called*/
|
enum {
|
||||||
void arch_program_segment_loaded(uintptr_t start, size_t size);
|
/* 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 */
|
/* Called for each segment of a program loaded. The PROG_FLAG_FINAL will be
|
||||||
void arch_program_loaded(void);
|
* set on the last segment loaded. */
|
||||||
|
void arch_segment_loaded(uintptr_t start, size_t size, int flags);
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
* ROMSTAGE LOADING *
|
* ROMSTAGE LOADING *
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Imagination Technologies
|
* Copyright (C) 2014 Imagination Technologies
|
||||||
|
* Copyright 2015 Google Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -20,14 +21,9 @@
|
|||||||
#include <program_loading.h>
|
#include <program_loading.h>
|
||||||
|
|
||||||
/* For each segment of a program loaded this function is called*/
|
/* For each segment of a program loaded this function is called*/
|
||||||
__attribute__ ((weak)) void arch_program_segment_loaded(uintptr_t start,
|
void __attribute__ ((weak)) arch_segment_loaded(uintptr_t start, size_t size,
|
||||||
size_t size)
|
int flags)
|
||||||
{
|
{
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Upon completion of loading a program this function is called */
|
|
||||||
__attribute__ ((weak)) void arch_program_loaded(void)
|
|
||||||
{
|
|
||||||
/* do nothing */
|
|
||||||
}
|
|
||||||
|
@ -112,8 +112,7 @@ void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset)
|
|||||||
media->unmap(media, data);
|
media->unmap(media, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
arch_program_segment_loaded(stage.load, stage.memlen);
|
arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL);
|
||||||
arch_program_loaded();
|
|
||||||
DEBUG("stage loaded\n");
|
DEBUG("stage loaded\n");
|
||||||
|
|
||||||
return (void *)(uintptr_t)stage.entry;
|
return (void *)(uintptr_t)stage.entry;
|
||||||
|
@ -200,9 +200,8 @@ int rmodule_load(void *base, struct rmodule *module)
|
|||||||
return -1;
|
return -1;
|
||||||
rmodule_clear_bss(module);
|
rmodule_clear_bss(module);
|
||||||
|
|
||||||
arch_program_segment_loaded((uintptr_t)module->location,
|
arch_segment_loaded((uintptr_t)module->location,
|
||||||
rmodule_memory_size(module));
|
rmodule_memory_size(module), SEG_FINAL);
|
||||||
arch_program_loaded();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -314,9 +314,16 @@ static int load_self_segments(
|
|||||||
struct payload *payload)
|
struct payload *payload)
|
||||||
{
|
{
|
||||||
struct segment *ptr;
|
struct segment *ptr;
|
||||||
|
struct segment *last_non_empty;
|
||||||
const unsigned long one_meg = (1UL << 20);
|
const unsigned long one_meg = (1UL << 20);
|
||||||
unsigned long bounce_high = lb_end;
|
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) {
|
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
||||||
if (bootmem_region_targets_usable_ram(ptr->s_dstaddr,
|
if (bootmem_region_targets_usable_ram(ptr->s_dstaddr,
|
||||||
ptr->s_memsz))
|
ptr->s_memsz))
|
||||||
@ -442,17 +449,11 @@ static int load_self_segments(
|
|||||||
* Each architecture can perform additonal operations
|
* Each architecture can perform additonal operations
|
||||||
* on the loaded segment
|
* on the loaded segment
|
||||||
*/
|
*/
|
||||||
arch_program_segment_loaded((uintptr_t)dest,
|
arch_segment_loaded((uintptr_t)dest, ptr->s_memsz,
|
||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user