mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
Clean up physmap, fix unaligned mapping problems
Convert all physmaps in dmi.c to use aligned readonly maps. Convert all physmaps in cbtable.c to use unaligned readonly maps. Make physunmap() a generic architecture-independent wrapper. Add physunmap_unaligned() to complement physmap*_unaligned(). Corresponding to flashrom svn r1765. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
parent
309dd2c7c2
commit
43eac03945
@ -261,7 +261,7 @@ int cb_parse_table(const char **vendor, const char **model)
|
|||||||
#else
|
#else
|
||||||
start = 0x0;
|
start = 0x0;
|
||||||
#endif
|
#endif
|
||||||
table_area = physmap_ro("low megabyte", start, BYTES_TO_MAP - start);
|
table_area = physmap_ro_unaligned("low megabyte", start, BYTES_TO_MAP - start);
|
||||||
if (ERROR_PTR == table_area) {
|
if (ERROR_PTR == table_area) {
|
||||||
msg_perr("Failed getting access to coreboot low tables.\n");
|
msg_perr("Failed getting access to coreboot low tables.\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -276,8 +276,9 @@ int cb_parse_table(const char **vendor, const char **model)
|
|||||||
if (forward->tag == LB_TAG_FORWARD) {
|
if (forward->tag == LB_TAG_FORWARD) {
|
||||||
start = forward->forward;
|
start = forward->forward;
|
||||||
start &= ~(getpagesize() - 1);
|
start &= ~(getpagesize() - 1);
|
||||||
physunmap(table_area, BYTES_TO_MAP);
|
physunmap_unaligned(table_area, BYTES_TO_MAP);
|
||||||
table_area = physmap_ro("high tables", start, BYTES_TO_MAP);
|
// FIXME: table_area is never unmapped below, nor is it unmapped above in the no-forward case
|
||||||
|
table_area = physmap_ro_unaligned("high tables", start, BYTES_TO_MAP);
|
||||||
if (ERROR_PTR == table_area) {
|
if (ERROR_PTR == table_area) {
|
||||||
msg_perr("Failed getting access to coreboot high tables.\n");
|
msg_perr("Failed getting access to coreboot high tables.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
2
dmi.c
2
dmi.c
@ -153,7 +153,7 @@ static void dmi_table(uint32_t base, uint16_t len, uint16_t num)
|
|||||||
{
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
uint8_t *dmi_table_mem = physmap_round("DMI Table", base, len);
|
uint8_t *dmi_table_mem = physmap_ro("DMI Table", base, len);
|
||||||
if (dmi_table_mem == NULL) {
|
if (dmi_table_mem == NULL) {
|
||||||
msg_perr("Unable to access DMI Table\n");
|
msg_perr("Unable to access DMI Table\n");
|
||||||
return;
|
return;
|
||||||
|
60
physmap.c
60
physmap.c
@ -27,6 +27,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
|
#include "programmer.h"
|
||||||
#include "hwaccess.h"
|
#include "hwaccess.h"
|
||||||
|
|
||||||
#if !defined(__DJGPP__) && !defined(__LIBPAYLOAD__)
|
#if !defined(__DJGPP__) && !defined(__LIBPAYLOAD__)
|
||||||
@ -89,7 +90,7 @@ static void *sys_physmap(uintptr_t phys_addr, size_t len)
|
|||||||
#define sys_physmap_rw_uncached sys_physmap
|
#define sys_physmap_rw_uncached sys_physmap
|
||||||
#define sys_physmap_ro_cached sys_physmap
|
#define sys_physmap_ro_cached sys_physmap
|
||||||
|
|
||||||
void physunmap(void *virt_addr, size_t len)
|
void sys_physunmap_unaligned(void *virt_addr, size_t len)
|
||||||
{
|
{
|
||||||
__dpmi_meminfo mi;
|
__dpmi_meminfo mi;
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ void *sys_physmap(uintptr_t phys_addr, size_t len)
|
|||||||
#define sys_physmap_rw_uncached sys_physmap
|
#define sys_physmap_rw_uncached sys_physmap
|
||||||
#define sys_physmap_ro_cached sys_physmap
|
#define sys_physmap_ro_cached sys_physmap
|
||||||
|
|
||||||
void physunmap(void *virt_addr, size_t len)
|
void sys_physunmap_unaligned(void *virt_addr, size_t len)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#elif defined(__MACH__) && defined(__APPLE__)
|
#elif defined(__MACH__) && defined(__APPLE__)
|
||||||
@ -139,7 +140,7 @@ static void *sys_physmap(uintptr_t phys_addr, size_t len)
|
|||||||
#define sys_physmap_rw_uncached sys_physmap
|
#define sys_physmap_rw_uncached sys_physmap
|
||||||
#define sys_physmap_ro_cached sys_physmap
|
#define sys_physmap_ro_cached sys_physmap
|
||||||
|
|
||||||
void physunmap(void *virt_addr, size_t len)
|
void sys_physunmap_unaligned(void *virt_addr, size_t len)
|
||||||
{
|
{
|
||||||
unmap_physical(virt_addr, len);
|
unmap_physical(virt_addr, len);
|
||||||
}
|
}
|
||||||
@ -192,13 +193,8 @@ static void *sys_physmap_ro_cached(uintptr_t phys_addr, size_t len)
|
|||||||
return MAP_FAILED == virt_addr ? ERROR_PTR : virt_addr;
|
return MAP_FAILED == virt_addr ? ERROR_PTR : virt_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void physunmap(void *virt_addr, size_t len)
|
void sys_physunmap_unaligned(void *virt_addr, size_t len)
|
||||||
{
|
{
|
||||||
if (len == 0) {
|
|
||||||
msg_pspew("Not unmapping zero size at %p\n", virt_addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
munmap(virt_addr, len);
|
munmap(virt_addr, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -242,7 +238,7 @@ static int undo_physmap(void *data)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
struct undo_physmap_data *d = data;
|
struct undo_physmap_data *d = data;
|
||||||
physunmap(d->virt_addr, d->len);
|
physunmap_unaligned(d->virt_addr, d->len);
|
||||||
free(data);
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -292,7 +288,7 @@ static void *physmap_common(const char *descr, uintptr_t phys_addr, size_t len,
|
|||||||
struct undo_physmap_data *d = malloc(sizeof(struct undo_physmap_data));
|
struct undo_physmap_data *d = malloc(sizeof(struct undo_physmap_data));
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
msg_perr("%s: Out of memory!\n", __func__);
|
msg_perr("%s: Out of memory!\n", __func__);
|
||||||
physunmap(virt_addr, len);
|
physunmap_unaligned(virt_addr, len);
|
||||||
return ERROR_PTR;
|
return ERROR_PTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +296,7 @@ static void *physmap_common(const char *descr, uintptr_t phys_addr, size_t len,
|
|||||||
d->len = len;
|
d->len = len;
|
||||||
if (register_shutdown(undo_physmap, d) != 0) {
|
if (register_shutdown(undo_physmap, d) != 0) {
|
||||||
msg_perr("%s: Could not register shutdown function!\n", __func__);
|
msg_perr("%s: Could not register shutdown function!\n", __func__);
|
||||||
physunmap(virt_addr, len);
|
physunmap_unaligned(virt_addr, len);
|
||||||
return ERROR_PTR;
|
return ERROR_PTR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,9 +304,41 @@ static void *physmap_common(const char *descr, uintptr_t phys_addr, size_t len,
|
|||||||
return virt_addr + offset;
|
return virt_addr + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void physunmap_unaligned(void *virt_addr, size_t len)
|
||||||
|
{
|
||||||
|
/* No need to check for zero size, such mappings would have yielded ERROR_PTR. */
|
||||||
|
if (virt_addr == ERROR_PTR) {
|
||||||
|
msg_perr("Trying to unmap a nonexisting mapping!\n"
|
||||||
|
"Please report a bug at flashrom@flashrom.org\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_physunmap_unaligned(virt_addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void physunmap(void *virt_addr, size_t len)
|
||||||
|
{
|
||||||
|
uintptr_t tmp;
|
||||||
|
|
||||||
|
/* No need to check for zero size, such mappings would have yielded ERROR_PTR. */
|
||||||
|
if (virt_addr == ERROR_PTR) {
|
||||||
|
msg_perr("Trying to unmap a nonexisting mapping!\n"
|
||||||
|
"Please report a bug at flashrom@flashrom.org\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tmp = (uintptr_t)virt_addr;
|
||||||
|
/* We assume that the virtual address of a page-aligned physical address is page-aligned as well. By
|
||||||
|
* extension, rounding a virtual unaligned address as returned by physmap should yield the same offset
|
||||||
|
* between rounded and original virtual address as between rounded and original physical address.
|
||||||
|
*/
|
||||||
|
round_to_page_boundaries(&tmp, &len);
|
||||||
|
virt_addr = (void *)tmp;
|
||||||
|
physunmap_unaligned(virt_addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
void *physmap(const char *descr, uintptr_t phys_addr, size_t len)
|
void *physmap(const char *descr, uintptr_t phys_addr, size_t len)
|
||||||
{
|
{
|
||||||
return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_NOCLEANUP, PHYSM_EXACT);
|
return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_NOCLEANUP, PHYSM_ROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len)
|
void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len)
|
||||||
@ -318,12 +346,12 @@ void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len)
|
|||||||
return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_CLEANUP, PHYSM_ROUND);
|
return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_CLEANUP, PHYSM_ROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *physmap_round(const char *descr, uintptr_t phys_addr, size_t len)
|
void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len)
|
||||||
{
|
{
|
||||||
return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_NOCLEANUP, PHYSM_ROUND);
|
return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_ROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len)
|
void *physmap_ro_unaligned(const char *descr, uintptr_t phys_addr, size_t len)
|
||||||
{
|
{
|
||||||
return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_EXACT);
|
return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_EXACT);
|
||||||
}
|
}
|
||||||
|
@ -277,9 +277,10 @@ int processor_flash_enable(void);
|
|||||||
/* physmap.c */
|
/* physmap.c */
|
||||||
void *physmap(const char *descr, uintptr_t phys_addr, size_t len);
|
void *physmap(const char *descr, uintptr_t phys_addr, size_t len);
|
||||||
void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len);
|
void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len);
|
||||||
void *physmap_round(const char *descr, uintptr_t phys_addr, size_t len);
|
|
||||||
void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len);
|
void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len);
|
||||||
|
void *physmap_ro_unaligned(const char *descr, uintptr_t phys_addr, size_t len);
|
||||||
void physunmap(void *virt_addr, size_t len);
|
void physunmap(void *virt_addr, size_t len);
|
||||||
|
void physunmap_unaligned(void *virt_addr, size_t len);
|
||||||
#if CONFIG_INTERNAL == 1
|
#if CONFIG_INTERNAL == 1
|
||||||
int setup_cpu_msr(int cpu);
|
int setup_cpu_msr(int cpu);
|
||||||
void cleanup_cpu_msr(void);
|
void cleanup_cpu_msr(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user