Author: mcayland Date: Mon May 3 13:29:38 2010 New Revision: 771 URL: http://tracker.coreboot.org/trac/openbios/changeset/771
Log: Move the retained magic block to the top of physical RAM and implement code that should do the right thing. Probably needs more testing though.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk
Modified: trunk/openbios-devel/arch/ppc/qemu/ofmem.c trunk/openbios-devel/arch/sparc64/ofmem_sparc64.c trunk/openbios-devel/include/libopenbios/ofmem.h trunk/openbios-devel/libopenbios/ofmem_common.c
Modified: trunk/openbios-devel/arch/ppc/qemu/ofmem.c ============================================================================== --- trunk/openbios-devel/arch/ppc/qemu/ofmem.c Mon May 3 08:56:57 2010 (r770) +++ trunk/openbios-devel/arch/ppc/qemu/ofmem.c Mon May 3 13:29:38 2010 (r771) @@ -135,6 +135,12 @@ /* none yet */ }
+retain_t *ofmem_arch_get_retained(void) +{ + /* not implemented */ + return NULL; +} + /************************************************************************/ /* OF private allocations */ /************************************************************************/
Modified: trunk/openbios-devel/arch/sparc64/ofmem_sparc64.c ============================================================================== --- trunk/openbios-devel/arch/sparc64/ofmem_sparc64.c Mon May 3 08:56:57 2010 (r770) +++ trunk/openbios-devel/arch/sparc64/ofmem_sparc64.c Mon May 3 13:29:38 2010 (r771) @@ -31,6 +31,8 @@
translation_t **g_ofmem_translations = &s_ofmem_data.ofmem.trans;
+extern uint64_t qemu_mem_size; + static inline size_t ALIGN_SIZE(size_t x, size_t a) { return (x + a - 1) & ~(a-1); @@ -61,6 +63,12 @@ return (ucell)TOP_OF_RAM; }
+retain_t *ofmem_arch_get_retained(void) +{ + /* Retained area is at the top of physical RAM */ + return (retain_t *)(qemu_mem_size - sizeof(retain_t)); +} + /************************************************************************/ /* misc */ /************************************************************************/ @@ -79,8 +87,6 @@ /* init / cleanup */ /************************************************************************/
-extern uint64_t qemu_mem_size; - static int remap_page_range( ucell phys, ucell virt, ucell size, ucell mode ) { ofmem_claim_phys(phys, size, 0); @@ -95,32 +101,37 @@ return 0; }
-#define RETAIN_OFMEM (TOP_OF_RAM - ALIGN_SIZE(sizeof(retain_t), 8)) #define RETAIN_MAGIC 0x1100220033004400
void ofmem_init( void ) { - retain_t *retained = (retain_t *)RETAIN_OFMEM; - - /* Clear all memory except any retained areas */ - if (!(retained->magic == RETAIN_MAGIC)) { - memset(&s_ofmem_data, 0, sizeof(s_ofmem_data)); - s_ofmem_data.ofmem.ramsize = qemu_mem_size; - - retained->magic = RETAIN_MAGIC; - } else { - /* TODO: walk retain_phys_range and add entries to phys_range to prevent - them being reused */ - OFMEM_TRACE("ofmem_init has detected retained magic but currently not implemented"); + retain_t *retained = ofmem_arch_get_retained(); + int i;
- memset(&s_ofmem_data, 0, sizeof(s_ofmem_data)); - s_ofmem_data.ofmem.ramsize = qemu_mem_size; - } + memset(&s_ofmem_data, 0, sizeof(s_ofmem_data)); + s_ofmem_data.ofmem.ramsize = qemu_mem_size;
/* inherit translations set up by entry.S */ ofmem_walk_boot_map(remap_page_range);
/* Map the memory */ ofmem_map_page_range(0, 0, qemu_mem_size, 0x36); -}
+ if (!(retained->magic == RETAIN_MAGIC)) { + OFMEM_TRACE("ofmem_init: no retained magic found, creating\n"); + retained->magic = RETAIN_MAGIC; + retained->numentries = 0; + } else { + OFMEM_TRACE("ofmem_init: retained magic found, total %lld mappings\n", retained->numentries); + + /* Mark physical addresses as used so they are not reallocated */ + for (i = 0; i < retained->numentries; i++) { + ofmem_claim_phys(retained->retain_phys_range[i].start, + retained->retain_phys_range[i].size, 0); + } + + /* Reset retained area for next reset */ + retained->magic = RETAIN_MAGIC; + retained->numentries = 0; + } +}
Modified: trunk/openbios-devel/include/libopenbios/ofmem.h ============================================================================== --- trunk/openbios-devel/include/libopenbios/ofmem.h Mon May 3 08:56:57 2010 (r770) +++ trunk/openbios-devel/include/libopenbios/ofmem.h Mon May 3 13:29:38 2010 (r771) @@ -46,28 +46,29 @@
range_t *phys_range; range_t *virt_range; - range_t *retain_phys_range; /* physical memory that should survive a warm reset */
translation_t *trans; /* this is really a translation_t */ } ofmem_t;
-/* structure for retained data at the top of the heap */ +/* structure for retained data */ typedef struct { ucell magic; - range_t *retain_phys_range; + ucell numentries; + range_t retain_phys_range[8]; /* physical memory that should survive a warm reset */ } retain_t;
/* TODO: temporary migration interface */ -extern ofmem_t* ofmem_arch_get_private(void); -extern void* ofmem_arch_get_malloc_base(void); -extern ucell ofmem_arch_get_heap_top(void); -extern ucell ofmem_arch_get_virt_top(void); -extern ucell ofmem_arch_default_translation_mode( ucell phys ); -extern void ofmem_arch_early_map_pages(ucell phys, ucell virt, ucell size, +extern ofmem_t* ofmem_arch_get_private(void); +extern void* ofmem_arch_get_malloc_base(void); +extern ucell ofmem_arch_get_heap_top(void); +extern ucell ofmem_arch_get_virt_top(void); +extern retain_t* ofmem_arch_get_retained(void); +extern ucell ofmem_arch_default_translation_mode( ucell phys ); +extern void ofmem_arch_early_map_pages(ucell phys, ucell virt, ucell size, ucell mode); -extern void ofmem_arch_unmap_pages(ucell virt, ucell size); +extern void ofmem_arch_unmap_pages(ucell virt, ucell size); /* sparc64 uses this method */ -extern int ofmem_map_page_range( ucell phys, ucell virt, ucell size, +extern int ofmem_map_page_range( ucell phys, ucell virt, ucell size, ucell mode );
/* malloc interface */
Modified: trunk/openbios-devel/libopenbios/ofmem_common.c ============================================================================== --- trunk/openbios-devel/libopenbios/ofmem_common.c Mon May 3 08:56:57 2010 (r770) +++ trunk/openbios-devel/libopenbios/ofmem_common.c Mon May 3 13:29:38 2010 (r771) @@ -452,7 +452,7 @@ /* if align != 0, phys is ignored. Returns -1 on error */ ucell ofmem_retain( ucell phys, ucell size, ucell align ) { - ofmem_t *ofmem = ofmem_arch_get_private(); + retain_t *retained = ofmem_arch_get_retained(); ucell retain_phys;
OFMEM_TRACE("ofmem_retain phys=" FMT_ucellx " size=" FMT_ucellx @@ -461,8 +461,11 @@
retain_phys = ofmem_claim_phys_( phys, size, align, 0, get_ram_size(), 0 );
- /* Also add to the retain_phys_range list */ - add_entry( phys, size, &ofmem->retain_phys_range ); + /* Add to the retain_phys_range list */ + retained->retain_phys_range[retained->numentries].next = NULL; + retained->retain_phys_range[retained->numentries].start = retain_phys; + retained->retain_phys_range[retained->numentries].size = size; + retained->numentries++;
return retain_phys; }