aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2014-05-28 13:33:50 -0400
committerKevin O'Connor <kevin@koconnor.net>2014-06-04 11:06:58 -0400
commit31bcda20eff45de7fdd2aad30d42f28165ccd69a (patch)
tree7a5737412a82419ea676bbac43a7cd72f7b089ed /src
parentf4c511cd7a5a475d542389341a320cb1c946fe25 (diff)
downloadseabios-hppa-31bcda20eff45de7fdd2aad30d42f28165ccd69a.zip
seabios-hppa-31bcda20eff45de7fdd2aad30d42f28165ccd69a.tar.gz
seabios-hppa-31bcda20eff45de7fdd2aad30d42f28165ccd69a.tar.bz2
smm: Use a C struct to define the layout of the SMM area.
Describe the memory layout using a struct instead of hard coded offsets. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r--src/config.h5
-rw-r--r--src/fw/smm.c64
-rw-r--r--src/romlayout.S2
3 files changed, 55 insertions, 16 deletions
diff --git a/src/config.h b/src/config.h
index 269a022..6f1a5b9 100644
--- a/src/config.h
+++ b/src/config.h
@@ -39,9 +39,8 @@
#define BUILD_EXTRA_STACK_SIZE 0x800
// 32KB for shadow ram copying (works around emulator deficiencies)
#define BUILD_BIOS_TMP_ADDR 0x30000
-#define BUILD_SMM_INIT_ADDR 0x38000
-#define BUILD_SMM_ADDR 0xa8000
-#define BUILD_SMM_SIZE 0x8000
+#define BUILD_SMM_INIT_ADDR 0x30000
+#define BUILD_SMM_ADDR 0xa0000
#define BUILD_PCIMEM_START 0xe0000000
#define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */
diff --git a/src/fw/smm.c b/src/fw/smm.c
index 3d0caa1..c2ce5c3 100644
--- a/src/fw/smm.c
+++ b/src/fw/smm.c
@@ -17,20 +17,54 @@
#include "util.h" // smm_setup
#include "x86.h" // wbinvd
+#define SMM_REV_I32 0x00020000
+#define SMM_REV_I64 0x00020064
+
+struct smm_state {
+ union {
+ struct {
+ u8 pad_000[0xf8];
+ u32 smm_base;
+ u32 smm_rev;
+ u8 pad_100[0xd0];
+ u32 eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags;
+ u8 pad_1f8[0x08];
+ } i32;
+ struct {
+ u8 pad_000[0xfc];
+ u32 smm_rev;
+ u32 smm_base;
+ u8 pad_104[0x6c];
+ u64 rflags, rip, r15, r14, r13, r12, r11, r10, r9, r8;
+ u64 rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax;
+ } i64;
+ };
+};
+
+struct smm_layout {
+ u8 stack[0x8000];
+ u64 codeentry;
+ u8 pad_8008[0x7df8];
+ struct smm_state cpu;
+};
+
void VISIBLE32FLAT
handle_smi(u16 cs)
{
u8 cmd = inb(PORT_SMI_CMD);
- dprintf(DEBUG_HDL_smi, "handle_smi cmd=%x cs=%x\n", cmd, cs);
+ struct smm_layout *smm = MAKE_FLATPTR(cs, 0);
+ dprintf(DEBUG_HDL_smi, "handle_smi cmd=%x smbase=%p\n", cmd, smm);
- void *smbase = MAKE_FLATPTR(cs, 0) + 0x8000;
- if (smbase == (void*)BUILD_SMM_INIT_ADDR) {
+ if (smm == (void*)BUILD_SMM_INIT_ADDR) {
// relocate SMBASE to 0xa0000
- u8 *smrev = smbase + 0x7efc;
- u32 *newbase = smbase + 0x7ef8;
- if (*smrev == 0x64)
- newbase = smbase + 0x7f00;
- *newbase = BUILD_SMM_ADDR - 0x8000;
+ if (smm->cpu.i32.smm_rev == SMM_REV_I32) {
+ smm->cpu.i32.smm_base = BUILD_SMM_ADDR;
+ } else if (smm->cpu.i64.smm_rev == SMM_REV_I64) {
+ smm->cpu.i64.smm_base = BUILD_SMM_ADDR;
+ } else {
+ warn_internalerror();
+ return;
+ }
// indicate to smm_relocate_and_restore() that the SMM code was executed
outb(0x00, PORT_SMI_STATUS);
return;
@@ -46,10 +80,13 @@ static void
smm_save_and_copy(void)
{
// save original memory content
- memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE);
+ struct smm_layout *initsmm = (void*)BUILD_SMM_INIT_ADDR;
+ struct smm_layout *smm = (void*)BUILD_SMM_ADDR;
+ memcpy(&smm->cpu, &initsmm->cpu, sizeof(smm->cpu));
+ memcpy(&smm->codeentry, &initsmm->codeentry, sizeof(smm->codeentry));
// Setup code entry point.
- *(u64*)BUILD_SMM_INIT_ADDR = SMI_INSN;
+ initsmm->codeentry = SMI_INSN;
}
static void
@@ -66,10 +103,13 @@ smm_relocate_and_restore(void)
;
/* restore original memory content */
- memcpy((void *)BUILD_SMM_INIT_ADDR, (void *)BUILD_SMM_ADDR, BUILD_SMM_SIZE);
+ struct smm_layout *initsmm = (void*)BUILD_SMM_INIT_ADDR;
+ struct smm_layout *smm = (void*)BUILD_SMM_ADDR;
+ memcpy(&initsmm->cpu, &smm->cpu, sizeof(initsmm->cpu));
+ memcpy(&initsmm->codeentry, &smm->codeentry, sizeof(initsmm->codeentry));
// Setup code entry point.
- *(u64*)BUILD_SMM_ADDR = SMI_INSN;
+ smm->codeentry = SMI_INSN;
wbinvd();
}
diff --git a/src/romlayout.S b/src/romlayout.S
index 5b48062..0d6af39 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -269,7 +269,7 @@ entry_smi:
movl $1f + BUILD_BIOS_ADDR, %edx
jmp transition32_for_smi
.code32
-1: movl $BUILD_SMM_ADDR, %esp
+1: movl $BUILD_SMM_ADDR + 0x8000, %esp
calll _cfunc32flat_handle_smi - BUILD_BIOS_ADDR
rsm
.code16gcc