diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2014-05-28 13:33:50 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2014-06-04 11:06:58 -0400 |
commit | 31bcda20eff45de7fdd2aad30d42f28165ccd69a (patch) | |
tree | 7a5737412a82419ea676bbac43a7cd72f7b089ed /src | |
parent | f4c511cd7a5a475d542389341a320cb1c946fe25 (diff) | |
download | seabios-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.h | 5 | ||||
-rw-r--r-- | src/fw/smm.c | 64 | ||||
-rw-r--r-- | src/romlayout.S | 2 |
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 |