aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2008-11-08 13:05:27 -0500
committerKevin O'Connor <kevin@koconnor.net>2008-11-08 13:05:27 -0500
commitd995b3df0189f931325f1630a6e9d17e8e5319db (patch)
tree3c81b80d22912ccdbccbc8eb7ee610e6ad2ef362
parent4a14d75dbec58c5e4e6c4ac178ca13f3b948fa22 (diff)
downloadseabios-hppa-d995b3df0189f931325f1630a6e9d17e8e5319db.zip
seabios-hppa-d995b3df0189f931325f1630a6e9d17e8e5319db.tar.gz
seabios-hppa-d995b3df0189f931325f1630a6e9d17e8e5319db.tar.bz2
Update e820 map in place instead of copying it.
Allocate the e820 map space in the 0xf0000 segment and do all updates in place. This reduces the need to access external memory during post. Also, move e820 pointer and count from ebda to variables in 0xf0000.
-rw-r--r--src/biosvar.h2
-rw-r--r--src/config.h2
-rw-r--r--src/memmap.c25
-rw-r--r--src/memmap.h4
-rw-r--r--src/system.c14
5 files changed, 26 insertions, 21 deletions
diff --git a/src/biosvar.h b/src/biosvar.h
index 7ea038f..6dfcbc7 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -275,8 +275,6 @@ struct extended_bios_data_area_s {
// Physical memory available.
u32 ram_size; // Amount of continuous ram under 4Gig
u64 ram_size_over4G; // Amount of continuous ram >4Gig
- u16 e820_count;
- u32 e820_loc;
u32 pir_loc;
// ATA Driver data
diff --git a/src/config.h b/src/config.h
index fa7ae9e..39a796d 100644
--- a/src/config.h
+++ b/src/config.h
@@ -64,6 +64,8 @@
#define CONFIG_ACPI 1
// Support bios callbacks specific to via vgabios.
#define CONFIG_VGAHOOKS 1
+// Maximum number of map entries in the e820 map
+#define CONFIG_MAX_E820 32
/* define it if the (emulated) hardware supports SMM mode */
#define CONFIG_USE_SMM 1
diff --git a/src/memmap.c b/src/memmap.c
index e02745f..f74f4f2 100644
--- a/src/memmap.c
+++ b/src/memmap.c
@@ -8,10 +8,6 @@
#include "util.h" // dprintf.h
#include "biosvar.h" // SET_EBDA
-// Temporary storage used during map building.
-static struct e820entry e820_list[64];
-static int e820_count;
-
// Remove an entry from the e820_list.
static void
remove_e820(int i)
@@ -25,7 +21,7 @@ remove_e820(int i)
static void
insert_e820(int i, u64 start, u64 size, u32 type)
{
- if (e820_count >= ARRAY_SIZE(e820_list)) {
+ if (e820_count >= CONFIG_MAX_E820) {
dprintf(1, "Overflowed e820 list!\n");
return;
}
@@ -139,6 +135,15 @@ memmap_setup()
bios_table_end_addr = (u32)&freespace2_end;
dprintf(1, "bios_table_addr: 0x%08x end=0x%08x\n",
bios_table_cur_addr, bios_table_end_addr);
+
+ bios_table_cur_addr = ALIGN(bios_table_cur_addr, 4);
+ u32 msize = CONFIG_MAX_E820 * sizeof(e820_list[0]);
+ if (bios_table_cur_addr + msize > bios_table_end_addr) {
+ dprintf(1, "No room for e820 map!\n");
+ return;
+ }
+ e820_list = (void*)bios_table_cur_addr;
+ bios_table_cur_addr += msize;
}
// Copy the temporary e820 map info to its permanent location.
@@ -147,16 +152,6 @@ memmap_finalize()
{
dump_map();
- u32 msize = e820_count * sizeof(e820_list[0]);
- if (bios_table_cur_addr + msize > bios_table_end_addr) {
- dprintf(1, "No room for e820 map!\n");
- return;
- }
- memcpy((void*)bios_table_cur_addr, e820_list, msize);
- SET_EBDA(e820_loc, bios_table_cur_addr);
- SET_EBDA(e820_count, e820_count);
- bios_table_cur_addr += msize;
-
dprintf(1, "final bios_table_addr: 0x%08x (used %d%%)\n"
, bios_table_cur_addr
, (100 * (bios_table_cur_addr - (u32)&freespace2_start)
diff --git a/src/memmap.h b/src/memmap.h
index b5e1d0d..8a6bd79 100644
--- a/src/memmap.h
+++ b/src/memmap.h
@@ -20,6 +20,10 @@ void add_e820(u64 start, u64 size, u32 type);
void memmap_setup();
void memmap_finalize();
+// e820 map storage (defined in system.c)
+extern struct e820entry *e820_list;
+extern int e820_count;
+
// Space for exported bios tables.
extern u32 bios_table_cur_addr, bios_table_end_addr;
diff --git a/src/system.c b/src/system.c
index 04cd6ac..f4e4263 100644
--- a/src/system.c
+++ b/src/system.c
@@ -266,23 +266,29 @@ handle_15e801(struct bregs *regs)
set_success(regs);
}
+#if MODE16
+// Info on e820 map location and size.
+struct e820entry *e820_list VISIBLE16;
+int e820_count VISIBLE16;
+#endif
+
static void
handle_15e820(struct bregs *regs)
{
- int count = GET_EBDA(e820_count);
+ int count = GET_VAR(CS, e820_count);
if (regs->edx != 0x534D4150 || regs->bx >= count) {
set_code_fail(regs, RET_EUNSUPPORTED);
return;
}
- struct e820entry *e = &((struct e820entry *)GET_EBDA(e820_loc))[regs->bx];
- memcpy_far(MAKE_FARPTR(regs->es, regs->di), e, sizeof(*e));
+ struct e820entry *l = GET_VAR(CS, e820_list);
+ memcpy_far(MAKE_FARPTR(regs->es, regs->di), &l[regs->bx], sizeof(l[0]));
if (regs->bx == count-1)
regs->ebx = 0;
else
regs->ebx++;
regs->eax = 0x534D4150;
- regs->ecx = sizeof(*e);
+ regs->ecx = sizeof(l[0]);
set_success(regs);
}