}
}
+static void
+qemu_cfg_write(void *buf, int len)
+{
+ if (len == 0) {
+ return;
+ }
+
+ if (qemu_cfg_dma_enabled()) {
+ qemu_cfg_dma_transfer(buf, len, QEMU_CFG_DMA_CTL_WRITE);
+ } else {
+ warn_internalerror();
+ }
+}
+
static void
qemu_cfg_skip(int len)
{
}
}
+static void
+qemu_cfg_write_entry(void *buf, int e, int len)
+{
+ if (qemu_cfg_dma_enabled()) {
+ u32 control = (e << 16) | QEMU_CFG_DMA_CTL_SELECT
+ | QEMU_CFG_DMA_CTL_WRITE;
+ qemu_cfg_dma_transfer(buf, len, control);
+ } else {
+ warn_internalerror();
+ }
+}
+
struct qemu_romfile_s {
struct romfile_s file;
int select, skip;
return file->size;
}
+int
+qemu_cfg_write_file(void *src, struct romfile_s *file, u32 offset, u32 len)
+{
+ if ((offset + len) > file->size)
+ return -1;
+
+ if (!qemu_cfg_dma_enabled() || (file->copy != qemu_cfg_read_file)) {
+ warn_internalerror();
+ return -1;
+ }
+ struct qemu_romfile_s *qfile;
+ qfile = container_of(file, struct qemu_romfile_s, file);
+ if (offset == 0) {
+ /* Do it in one transfer */
+ qemu_cfg_write_entry(src, qfile->select, len);
+ } else {
+ qemu_cfg_select(qfile->select);
+ qemu_cfg_skip(offset);
+ qemu_cfg_write(src, len);
+ }
+ return len;
+}
+
static void
qemu_romfile_add(char *name, int select, int skip, int size)
{
#include "config.h" // CONFIG_*
#include "biosvar.h" // GET_GLOBAL
+#include "romfile.h" // struct romfile_s
// Types of paravirtualized platforms.
#define PF_QEMU (1<<0)
#define QEMU_CFG_DMA_CTL_READ 0x02
#define QEMU_CFG_DMA_CTL_SKIP 0x04
#define QEMU_CFG_DMA_CTL_SELECT 0x08
+#define QEMU_CFG_DMA_CTL_WRITE 0x10
// QEMU_CFG_DMA ID bit
#define QEMU_CFG_VERSION_DMA 2
void qemu_cfg_init(void);
u16 qemu_get_present_cpus_count(void);
+int qemu_cfg_write_file(void *src, struct romfile_s *file, u32 offset, u32 len);
#endif