u32 size = ntohl(file->len);
void *src = (void*)file + ntohl(file->offset);
- if (cbfs_iscomp(file))
- // Compressed.
- return ulzma(dst, maxlen, src, size);
+ if (cbfs_iscomp(file)) {
+ // Compressed - copy to temp ram and uncompress it.
+ u32 asize = ALIGN(size, 4);
+ void *temp = malloc_tmphigh(asize);
+ if (!temp)
+ return -1;
+ iomemcpy(temp, src, asize);
+ int ret = ulzma(dst, maxlen, temp, size);
+ yield();
+ free(temp);
+ return ret;
+ }
// Not compressed.
dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst);
dprintf(1, "File too big to copy\n");
return -1;
}
- memcpy(dst, src, size);
+ iomemcpy(dst, src, size);
return size;
}
}
dprintf(4, "Copying option rom (size %d) from %p to %x\n"
, romsize, rom, RomEnd);
- memcpy((void*)RomEnd, rom, romsize);
+ iomemcpy((void*)RomEnd, rom, romsize);
return (void*)RomEnd;
}
return d1;
}
+// Copy from memory mapped IO. IO mem is very slow, so yield
+// periodically. 'len' must be 4 byte aligned.
+void
+iomemcpy(void *d, const void *s, u32 len)
+{
+ yield();
+ while (len) {
+ u32 copylen = len;
+ if (copylen > 1024)
+ copylen = 1024;
+ len -= copylen;
+ copylen /= 4;
+ asm volatile(
+ "rep movsl (%%esi),%%es:(%%edi)"
+ : "+c"(copylen), "+S"(s), "+D"(d)
+ : : "cc", "memory");
+ yield();
+ }
+}
+
void *
memmove(void *d, const void *s, size_t len)
{
#endif
inline void memcpy_far(u16 d_seg, void *d_far
, u16 s_seg, const void *s_far, size_t len);
+void iomemcpy(void *d, const void *s, u32 len);
void *memmove(void *d, const void *s, size_t len);
char *strtcpy(char *dest, const char *src, size_t len);
struct bregs;