aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-01-06 16:02:10 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-01-06 16:02:10 +0000
commit872a09d26274c57b608add17b9a5cabc49f241c6 (patch)
tree5e3794759d968548379eb5edf8f31abc9acbf940
parent15c5bb9f9236380bb689e3073e18290e9783cea3 (diff)
downloadxen-872a09d26274c57b608add17b9a5cabc49f241c6.tar.gz
xen-872a09d26274c57b608add17b9a5cabc49f241c6.tar.bz2
xen-872a09d26274c57b608add17b9a5cabc49f241c6.zip
rombios: Allow option ROMs to extend up to 0xEA000.
Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r--tools/firmware/hvmloader/config.h11
-rw-r--r--tools/firmware/hvmloader/e820.h4
-rw-r--r--tools/firmware/hvmloader/hvmloader.c30
-rw-r--r--tools/firmware/hvmloader/smbios.c4
-rw-r--r--tools/firmware/hvmloader/util.c18
-rw-r--r--tools/firmware/rombios/rombios.c44
6 files changed, 66 insertions, 45 deletions
diff --git a/tools/firmware/hvmloader/config.h b/tools/firmware/hvmloader/config.h
index ea0c435ae4..35edf1930e 100644
--- a/tools/firmware/hvmloader/config.h
+++ b/tools/firmware/hvmloader/config.h
@@ -23,12 +23,19 @@
/* Memory map. */
#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
-#define SMBIOS_PHYSICAL_ADDRESS 0x000E9000
-#define SMBIOS_MAXIMUM_SIZE 0x00001000
+#define OPTIONROM_PHYSICAL_ADDRESS 0x000C8000
+#define OPTIONROM_PHYSICAL_END 0x000EA000
#define ACPI_PHYSICAL_ADDRESS 0x000EA000
+#define E820_PHYSICAL_ADDRESS 0x000EA100
+#define SMBIOS_PHYSICAL_ADDRESS 0x000EB000
+#define SMBIOS_MAXIMUM_SIZE 0x00005000
#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
#define SCRATCH_PHYSICAL_ADDRESS 0x00010000
+/* Offsets from E820_PHYSICAL_ADDRESS. */
+#define E820_NR_OFFSET 0x0
+#define E820_OFFSET 0x8
+
/* Xen Platform Device */
#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
diff --git a/tools/firmware/hvmloader/e820.h b/tools/firmware/hvmloader/e820.h
index f59f70cbae..940c8ed394 100644
--- a/tools/firmware/hvmloader/e820.h
+++ b/tools/firmware/hvmloader/e820.h
@@ -17,7 +17,7 @@ struct e820entry {
uint32_t type;
} __attribute__((packed));
-#define HVM_E820_NR ((unsigned char *)HVM_E820_PAGE + HVM_E820_NR_OFFSET)
-#define HVM_E820 ((struct e820entry *)(HVM_E820_PAGE + HVM_E820_OFFSET))
+#define E820_NR ((uint16_t *)(E820_PHYSICAL_ADDRESS + E820_NR_OFFSET))
+#define E820 ((struct e820entry *)(E820_PHYSICAL_ADDRESS + E820_OFFSET))
#endif /* __HVMLOADER_E820_H__ */
diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c
index 9723306f8e..54fa9196b6 100644
--- a/tools/firmware/hvmloader/hvmloader.c
+++ b/tools/firmware/hvmloader/hvmloader.c
@@ -330,7 +330,7 @@ static void pci_setup(void)
* Scan the list of Option ROMs at @roms for one which supports
* PCI (@vendor_id, @device_id) found at slot @devfn. If one is found,
* copy it to @dest and return its size rounded up to a multiple 2kB. This
- * function will not copy ROMs beyond address 0xE0000.
+ * function will not copy ROMs beyond address OPTIONROM_PHYSICAL_END.
*/
#define round_option_rom(x) (((x) + 2047) & ~2047)
static int scan_option_rom(
@@ -401,7 +401,7 @@ static int scan_option_rom(
printf(" - Product name: %s\n",
(char *)rom + pnph->product_name_offset);
- if ( (dest + rom->rom_size * 512 + 1) > 0xe0000u )
+ if ( (dest + rom->rom_size * 512 + 1) > OPTIONROM_PHYSICAL_END )
{
printf("Option ROM size %x exceeds available space\n",
rom->rom_size * 512);
@@ -488,8 +488,8 @@ static int pci_load_option_roms(uint32_t rom_base_addr)
/* Replace possibly erroneous memory-size CMOS fields with correct values. */
static void cmos_write_memory_size(void)
{
- struct e820entry *map = HVM_E820;
- int i, nr = *HVM_E820_NR;
+ struct e820entry *map = E820;
+ int i, nr = *E820_NR;
uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0;
for ( i = 0; i < nr; i++ )
@@ -541,9 +541,11 @@ static uint16_t init_xen_platform_io_base(void)
return bios_info->xen_pfiob;
}
-/* Set up an empty TSS area for virtual 8086 mode to use.
+/*
+ * Set up an empty TSS area for virtual 8086 mode to use.
* The only important thing is that it musn't have any bits set
- * in the interrupt redirection bitmap, so all zeros will do. */
+ * in the interrupt redirection bitmap, so all zeros will do.
+ */
static void init_vm86_tss(void)
{
uint32_t tss;
@@ -558,6 +560,18 @@ static void init_vm86_tss(void)
printf("vm86 TSS at %08x\n", tss);
}
+/*
+ * Copy the E820 table provided by the HVM domain builder into the correct
+ * place in the memory map we share with the rombios.
+ */
+static void copy_e820_table(void)
+{
+ uint8_t nr = *(uint8_t *)(HVM_E820_PAGE + HVM_E820_NR_OFFSET);
+ BUG_ON(nr > 16);
+ memcpy(E820, (char *)HVM_E820_PAGE + HVM_E820_OFFSET, nr * sizeof(*E820));
+ *E820_NR = nr;
+}
+
int main(void)
{
int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0;
@@ -567,6 +581,8 @@ int main(void)
printf("HVM Loader\n");
+ copy_e820_table();
+
init_hypercalls();
printf("CPU speed is %u MHz\n", get_cpu_mhz());
@@ -617,6 +633,8 @@ int main(void)
}
etherboot_phys_addr = VGABIOS_PHYSICAL_ADDRESS + vgabios_sz;
+ if ( etherboot_phys_addr < OPTIONROM_PHYSICAL_ADDRESS )
+ etherboot_phys_addr = OPTIONROM_PHYSICAL_ADDRESS;
etherboot_sz = scan_etherboot_nic(etherboot_phys_addr);
option_rom_phys_addr = etherboot_phys_addr + etherboot_sz;
diff --git a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c
index e1464220d0..f68a7b4475 100644
--- a/tools/firmware/hvmloader/smbios.c
+++ b/tools/firmware/hvmloader/smbios.c
@@ -143,8 +143,8 @@ write_smbios_tables(void *start,
static uint64_t
get_memsize(void)
{
- struct e820entry *map = HVM_E820;
- uint8_t num_entries = *HVM_E820_NR;
+ struct e820entry *map = E820;
+ uint8_t num_entries = *E820_NR;
uint64_t memsize = 0;
int i;
diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c
index fe33b0f124..6a1d47a61b 100644
--- a/tools/firmware/hvmloader/util.c
+++ b/tools/firmware/hvmloader/util.c
@@ -307,16 +307,16 @@ uuid_to_string(char *dest, uint8_t *uuid)
static void e820_collapse(void)
{
int i = 0;
- struct e820entry *ent = (struct e820entry *)HVM_E820;
+ struct e820entry *ent = E820;
- while ( i < (*HVM_E820_NR-1) )
+ while ( i < (*E820_NR-1) )
{
if ( (ent[i].type == ent[i+1].type) &&
((ent[i].addr + ent[i].size) == ent[i+1].addr) )
{
ent[i].size += ent[i+1].size;
- memcpy(&ent[i+1], &ent[i+2], (*HVM_E820_NR-i-2) * sizeof(*ent));
- (*HVM_E820_NR)--;
+ memcpy(&ent[i+1], &ent[i+2], (*E820_NR-i-2) * sizeof(*ent));
+ (*E820_NR)--;
}
else
{
@@ -329,13 +329,13 @@ uint32_t e820_malloc(uint32_t size, uint32_t align)
{
uint32_t addr;
int i;
- struct e820entry *ent = (struct e820entry *)HVM_E820;
+ struct e820entry *ent = E820;
- /* Align to at leats one kilobyte. */
+ /* Align to at least one kilobyte. */
if ( align < 1024 )
align = 1024;
- for ( i = *HVM_E820_NR - 1; i >= 0; i-- )
+ for ( i = *E820_NR - 1; i >= 0; i-- )
{
addr = (ent[i].addr + ent[i].size - size) & ~(align-1);
if ( (ent[i].type != E820_RAM) || /* not ram? */
@@ -345,8 +345,8 @@ uint32_t e820_malloc(uint32_t size, uint32_t align)
if ( addr != ent[i].addr )
{
- memmove(&ent[i+1], &ent[i], (*HVM_E820_NR-i) * sizeof(*ent));
- (*HVM_E820_NR)++;
+ memmove(&ent[i+1], &ent[i], (*E820_NR-i) * sizeof(*ent));
+ (*E820_NR)++;
ent[i].size = addr - ent[i].addr;
ent[i+1].addr = addr;
ent[i+1].size -= ent[i].size;
diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c
index 3ff3f22b70..04c18ba118 100644
--- a/tools/firmware/rombios/rombios.c
+++ b/tools/firmware/rombios/rombios.c
@@ -177,6 +177,8 @@
# define BIOS_BUILD_DATE "06/23/99"
#endif
+#define E820_SEG (Bit16u)(E820_PHYSICAL_ADDRESS >> 4)
+
// 1K of base memory used for Extended Bios Data Area (EBDA)
// EBDA is used for PS/2 mouse support, and IDE BIOS, etc.
#define EBDA_SEG 0x9FC0
@@ -883,7 +885,6 @@ static Bit16u read_word();
static void write_byte();
static void write_word();
static void bios_printf();
-static void copy_e820_table();
static Bit8u inhibit_mouse_int_and_events();
static void enable_mouse_int_and_events();
@@ -1405,19 +1406,13 @@ ASM_END
#ifdef HVMASSIST
void
-copy_e820_table()
+fixup_base_mem_in_k()
{
- Bit8u nr_entries = read_byte(0x9000, 0x1e8);
- Bit32u base_mem;
- if (nr_entries > 32)
- nr_entries = 32;
- write_word(0xe000, 0x8, nr_entries);
- memcpyb(0xe000, 0x10, 0x9000, 0x2d0, nr_entries * 0x14);
/* Report the proper base memory size at address 0x0413: otherwise
* non-e820 code will clobber things if BASE_MEM_IN_K is bigger than
* the first e820 entry. Get the size by reading the second 64bit
* field of the first e820 slot. */
- base_mem = read_dword(0x9000, 0x2d0 + 8);
+ Bit32u base_mem = read_dword(E820_SEG, E820_OFFSET + 8);
write_word(0x40, 0x13, base_mem >> 10);
}
@@ -4669,7 +4664,8 @@ ASM_END
{
#ifdef HVMASSIST
case 0x20: {
- Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
+ Bit16u e820_table_size =
+ read_word(E820_SEG, E820_NR_OFFSET) * 0x14;
if (regs.u.r32.edx != 0x534D4150) /* SMAP */
goto int15_unimplemented;
@@ -4677,7 +4673,7 @@ ASM_END
if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
if (regs.u.r16.bx + 0x14 <= e820_table_size)
memcpyb(ES, regs.u.r16.di,
- 0xe000, 0x10 + regs.u.r16.bx, 0x14);
+ E820_SEG, E820_OFFSET + regs.u.r16.bx, 0x14);
regs.u.r32.ebx += 0x14;
if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
regs.u.r32.ebx = 0;
@@ -4685,8 +4681,8 @@ ASM_END
Bit32u base, type;
Bit16u off;
for (off = 0; off < e820_table_size; off += 0x14) {
- base = read_dword(0xe000, 0x10 + off);
- type = read_dword(0xe000, 0x20 + off);
+ base = read_dword(E820_SEG, E820_OFFSET + off);
+ type = read_dword(E820_SEG, E820_OFFSET + 0x10 + off);
if ((base >= 0x100000) && (type == 1))
break;
}
@@ -4694,7 +4690,7 @@ ASM_END
SET_CF();
break;
}
- memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14);
+ memcpyb(ES, regs.u.r16.di, E820_SEG, E820_OFFSET + off, 0x14);
regs.u.r32.ebx = 0;
} else { /* AX=E820, DX=534D4150, BX unrecognized */
goto int15_unimplemented;
@@ -4707,7 +4703,8 @@ ASM_END
}
case 0x01: {
- Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14;
+ Bit16u off, e820_table_size =
+ read_word(E820_SEG, E820_NR_OFFSET) * 0x14;
Bit32u base, type, size;
// do we have any reason to fail here ?
@@ -4723,8 +4720,8 @@ ASM_END
// Find first RAM E820 entry >= 1MB.
for (off = 0; off < e820_table_size; off += 0x14) {
- base = read_dword(0xe000, 0x10 + off);
- type = read_dword(0xe000, 0x20 + off);
+ base = read_dword(E820_SEG, E820_OFFSET + off);
+ type = read_dword(E820_SEG, E820_OFFSET + 0x10 + off);
if ((base >= 0x100000) && (type == 1))
break;
}
@@ -4732,7 +4729,7 @@ ASM_END
// If there is RAM above 16MB, return amount in 64kB chunks.
regs.u.r16.dx = 0;
if (off != e820_table_size) {
- size = base + read_dword(0xe000, 0x18 + off);
+ size = base + read_dword(E820_SEG, E820_OFFSET + 0x8 + off);
if (size > 0x1000000) {
size -= 0x1000000;
regs.u.r16.dx = (Bit16u)(size >> 16);
@@ -10441,8 +10438,8 @@ pnp_string:
rom_scan:
;; Scan for existence of valid expansion ROMS.
;; Video ROM: from 0xC0000..0xC7FFF in 2k increments
- ;; General ROM: from 0xC8000..0xDFFFF in 2k increments
- ;; System ROM: only 0xE0000
+ ;; General ROM: from 0xC8000..0xE9FFF in 2k increments
+ ;; System ROM: only 0xF0000
;;
;; Header:
;; Offset Value
@@ -10814,7 +10811,6 @@ post_default_ints:
mov ax, #BASE_MEM_IN_K
mov 0x0413, ax
-
;; Manufacturing Test 40:12
;; zerod out above
@@ -11008,14 +11004,14 @@ post_default_ints:
#ifdef HVMASSIST
call _enable_rom_write_access
call _clobber_entry_point
- call _copy_e820_table
+ call _fixup_base_mem_in_k
call smbios_init
#endif
call _init_boot_vectors
- mov cx, #0xc800 ;; init option roms
- mov ax, #0xe000
+ mov cx, #(OPTIONROM_PHYSICAL_ADDRESS >> 4) ;; init option roms
+ mov ax, #(OPTIONROM_PHYSICAL_END >> 4)
call rom_scan
#ifdef HVMASSIST