diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-01-19 19:25:21 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-01-19 19:25:21 -0500 |
commit | 8b267cb8a739576cd08c82d0ee75d6b14407c09c (patch) | |
tree | 3ce86bab73a41627f56d4c658b79fc10a891509b /src | |
parent | 79f4118e50ce256994b75b99811ceb0e6a812a13 (diff) | |
download | seabios-hppa-8b267cb8a739576cd08c82d0ee75d6b14407c09c.zip seabios-hppa-8b267cb8a739576cd08c82d0ee75d6b14407c09c.tar.gz seabios-hppa-8b267cb8a739576cd08c82d0ee75d6b14407c09c.tar.bz2 |
Implement memcpy_far and checksum_far, and replace _fl variants.
The "flat" mode variants work in real mode, but will not work in
protected mode. So, replace with versions that take explicit
segments.
Diffstat (limited to 'src')
-rw-r--r-- | src/biosvar.h | 8 | ||||
-rw-r--r-- | src/boot.c | 2 | ||||
-rw-r--r-- | src/disk.c | 16 | ||||
-rw-r--r-- | src/pcibios.c | 10 | ||||
-rw-r--r-- | src/system.c | 6 | ||||
-rw-r--r-- | src/util.c | 35 | ||||
-rw-r--r-- | src/util.h | 6 |
7 files changed, 48 insertions, 35 deletions
diff --git a/src/biosvar.h b/src/biosvar.h index 4d3b3f0..28f956f 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -258,8 +258,12 @@ get_ebda_ptr() * Global variables ****************************************************************/ -#define GET_GLOBAL(var) \ - GET_VAR(CS, (var)) +#define GLOBAL_SEGREG CS +static inline u16 get_global_seg() { + return GET_SEG(GLOBAL_SEGREG); +} +#define GET_GLOBAL(var) \ + GET_VAR(GLOBAL_SEGREG, (var)) #define SET_GLOBAL(var, val) do { \ extern void __force_link_error__set_global_only_in_32bit(); \ if (MODE16) \ @@ -40,7 +40,7 @@ printf_bootdev(u16 bootdev) if (type == 4 && description_fl != 0) { char description[33]; /* first 32 bytes are significant */ - memcpy_fl(MAKE_FLATPTR(GET_SEG(SS), description), description_fl, 32); + memcpy(description, description_fl, 32); /* terminate string */ description[32] = 0; printf(" [%.s]", description); @@ -41,12 +41,12 @@ __disk_stub(struct bregs *regs, int lineno, const char *fname) __disk_stub((regs), __LINE__, __func__) static int -__send_disk_op(struct disk_op_s *op_p, u16 op_s) +__send_disk_op(struct disk_op_s *op_far, u16 op_seg) { struct disk_op_s dop; - memcpy_fl(MAKE_FLATPTR(GET_SEG(SS), &dop) - , MAKE_FLATPTR(op_s, op_p) - , sizeof(dop)); + memcpy_far(GET_SEG(SS), &dop + , op_seg, op_far + , sizeof(dop)); dprintf(DEBUG_HDL_13, "disk_op d=%d lba=%d buf=%p count=%d cmd=%d\n" , dop.driveid, (u32)dop.lba, dop.buf_fl @@ -486,9 +486,9 @@ disk_1348(struct bregs *regs, u8 device) SET_EBDA2(ebda_seg, dpte.reserved, 0); SET_EBDA2(ebda_seg, dpte.revision, 0x11); - u8 *p = MAKE_FLATPTR(ebda_seg - , offsetof(struct extended_bios_data_area_s, dpte)); - SET_EBDA2(ebda_seg, dpte.checksum, -checksum(p, 15)); + u8 sum = checksum_far( + ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); + SET_EBDA2(ebda_seg, dpte.checksum, -sum); if (size < 66) { disk_ret(regs, DISK_RET_SUCCESS); @@ -522,7 +522,7 @@ disk_1348(struct bregs *regs, u8 device) SET_INT13DPT(regs, device_path, slave); - SET_INT13DPT(regs, checksum, -checksum(MAKE_FLATPTR(regs->ds, 30), 35)); + SET_INT13DPT(regs, checksum, -checksum_far(regs->ds, (void*)30, 35)); disk_ret(regs, DISK_RET_SUCCESS); } diff --git a/src/pcibios.c b/src/pcibios.c index 950871c..cfcb25e 100644 --- a/src/pcibios.c +++ b/src/pcibios.c @@ -144,13 +144,13 @@ handle_1ab10e(struct bregs *regs) } // Get dest buffer. - u16 d = (GET_FARVAR(regs->es, *(u16*)(regs->di+2)) + 0); - u16 destseg = GET_FARVAR(regs->es, *(u16*)(regs->di+4)); + void *d_far = (void*)(GET_FARVAR(regs->es, *(u16*)(regs->di+2)) + 0); + u16 d_seg = GET_FARVAR(regs->es, *(u16*)(regs->di+4)); // Memcpy pir table slots to dest buffer. - memcpy_fl(MAKE_FLATPTR(destseg, d) - , MAKE_FLATPTR(SEG_BIOS, pirtable_g->slots) - , pirsize); + memcpy_far(d_seg, d_far + , get_global_seg(), pirtable_g->slots + , pirsize); // XXX - bochs bios sets bx to (1 << 9) | (1 << 11) regs->bx = GET_GLOBAL(pirtable_g->exclusive_irqs); diff --git a/src/system.c b/src/system.c index 5f39a98..798dc25 100644 --- a/src/system.c +++ b/src/system.c @@ -279,9 +279,9 @@ handle_15e820(struct bregs *regs) return; } - memcpy_fl(MAKE_FLATPTR(regs->es, regs->di) - , MAKE_FLATPTR(SEG_BIOS, &e820_list[regs->bx]) - , sizeof(e820_list[0])); + memcpy_far(regs->es, (void*)(regs->di+0) + , get_global_seg(), &e820_list[regs->bx] + , sizeof(e820_list[0])); if (regs->bx == count-1) regs->ebx = 0; else @@ -99,15 +99,22 @@ stack_hop(u32 eax, u32 edx, u32 ecx, void *func) // Sum the bytes in the specified area. u8 -checksum(u8 *buf_fl, u32 len) +checksum_far(u16 buf_seg, u8 *buf_far, u32 len) { + SET_SEG(ES, buf_seg); u32 i; u8 sum = 0; for (i=0; i<len; i++) - sum += GET_FLATPTR(buf_fl[i]); + sum += GET_VAR(ES, buf_far[i]); return sum; } +u8 +checksum(u8 *buf, u32 len) +{ + return checksum_far(GET_SEG(SS), buf, len); +} + void * memset(void *s, int c, size_t n) { @@ -116,19 +123,19 @@ memset(void *s, int c, size_t n) return s; } -void * -memcpy_fl(void *d_fl, const void *s_fl, size_t len) +inline void +memcpy_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len) { - u8 *d = d_fl; - u8 *s = (u8*)s_fl; - - while (len--) { - SET_FLATPTR(*d, GET_FLATPTR(*s)); - d++; - s++; - } - - return d_fl; + SET_SEG(ES, d_seg); + u16 bkup_ds; + asm volatile( + "movw %%ds, %w0\n" + "movw %w4, %%ds\n" + "rep movsb (%%si),%%es:(%%di)\n" + "movw %w0, %%ds\n" + : "=&r"(bkup_ds), "+c"(len), "+S"(s_far), "+D"(d_far) + : "r"(s_seg) + : "cc", "memory"); } void * @@ -67,10 +67,12 @@ static inline u64 rdtscll(void) // util.c inline u32 stack_hop(u32 eax, u32 edx, u32 ecx, void *func); -u8 checksum(u8 *buf_fl, u32 len); +u8 checksum_far(u16 buf_seg, u8 *buf_far, u32 len); +u8 checksum(u8 *buf, u32 len); void *memset(void *s, int c, size_t n); void *memcpy(void *d1, const void *s1, size_t len); -void *memcpy_fl(void *d_fl, const void *s_fl, size_t len); +inline void memcpy_far(u16 d_seg, void *d_far + , u16 s_seg, const void *s_far, size_t len); void *memmove(void *d, const void *s, size_t len); struct bregs; inline void call16(struct bregs *callregs); |