aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-01-19 19:25:21 -0500
committerKevin O'Connor <kevin@koconnor.net>2009-01-19 19:25:21 -0500
commit8b267cb8a739576cd08c82d0ee75d6b14407c09c (patch)
tree3ce86bab73a41627f56d4c658b79fc10a891509b /src
parent79f4118e50ce256994b75b99811ceb0e6a812a13 (diff)
downloadseabios-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.h8
-rw-r--r--src/boot.c2
-rw-r--r--src/disk.c16
-rw-r--r--src/pcibios.c10
-rw-r--r--src/system.c6
-rw-r--r--src/util.c35
-rw-r--r--src/util.h6
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) \
diff --git a/src/boot.c b/src/boot.c
index 142544b..1f0647a 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -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);
diff --git a/src/disk.c b/src/disk.c
index 248c839..03d2d38 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -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
diff --git a/src/util.c b/src/util.c
index 0a60e17..66b3343 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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 *
diff --git a/src/util.h b/src/util.h
index 78812cb..1531ffd 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);