@@ -494,8 +494,17 @@ static bool __init append_static_memory_to_bank(struct domain *d,
{
int res;
unsigned int nr_pages = PFN_DOWN(size);
- /* Infer next GFN. */
- gfn_t sgfn = gaddr_to_gfn(bank->start + bank->size);
+ gfn_t sgfn;
+
+ /*
+ * For direct-mapped domain, the GFN match the MFN.
+ * Otherwise, this is inferred on what has already been allocated
+ * in the bank.
+ */
+ if ( !is_domain_direct_mapped(d) )
+ sgfn = gaddr_to_gfn(bank->start + bank->size);
+ else
+ sgfn = gaddr_to_gfn(mfn_to_maddr(smfn));
res = guest_physmap_add_pages(d, sgfn, smfn, nr_pages);
if ( res )
@@ -668,12 +677,92 @@ static void __init allocate_static_memory(struct domain *d,
fail:
panic("Failed to allocate requested static memory for domain %pd.", d);
}
+
+/*
+ * Allocate static memory as RAM for one specific domain d.
+ * The static memory will be directly mapped in the guest(Guest Physical
+ * Address == Physical Address).
+ */
+static void __init assign_static_memory_11(struct domain *d,
+ struct kernel_info *kinfo,
+ const struct dt_device_node *node)
+{
+ u32 addr_cells, size_cells, reg_cells;
+ unsigned int nr_banks, bank = 0;
+ const __be32 *cell;
+ paddr_t pbase, psize;
+ mfn_t smfn;
+ int length;
+
+ if ( parse_static_mem_prop(node, &addr_cells, &size_cells, &length, &cell) )
+ {
+ printk(XENLOG_ERR
+ "%pd: failed to parse \"xen,static-mem\" property.\n", d);
+ goto fail;
+ }
+ reg_cells = addr_cells + size_cells;
+ nr_banks = length / (reg_cells * sizeof(u32));
+
+ if ( nr_banks > NR_MEM_BANKS )
+ {
+ printk(XENLOG_ERR
+ "%pd: exceed max number of supported guest memory banks.\n", d);
+ goto fail;
+ }
+
+ for ( ; bank < nr_banks; bank++ )
+ {
+ smfn = acquire_static_memory_bank(d, &cell, addr_cells, size_cells,
+ &pbase, &psize);
+ if ( mfn_eq(smfn, INVALID_MFN) )
+ goto fail;
+
+ printk(XENLOG_INFO "%pd: STATIC BANK[%u] %#"PRIpaddr"-%#"PRIpaddr"\n",
+ d, bank, pbase, pbase + psize);
+
+ /* One guest memory bank is matched with one physical memory bank. */
+ kinfo->mem.bank[bank].start = pbase;
+ if ( !append_static_memory_to_bank(d, &kinfo->mem.bank[bank],
+ smfn, psize) )
+ goto fail;
+
+ kinfo->unassigned_mem -= psize;
+ }
+
+ kinfo->mem.nr_banks = nr_banks;
+
+ /*
+ * The property 'memory' should match the amount of memory given to
+ * the guest.
+ * Currently, it is only possible to either acquire static memory or
+ * let Xen allocate. *Mixing* is not supported.
+ */
+ if ( kinfo->unassigned_mem != 0 )
+ {
+ printk(XENLOG_ERR
+ "Size of \"memory\" property doesn't match up with the sum-up of \"xen,static-mem\".\n");
+ goto fail;
+ }
+
+ return;
+
+ fail:
+ panic("Failed to assign requested static memory for direct-map domain %pd.",
+ d);
+}
#else
static void __init allocate_static_memory(struct domain *d,
struct kernel_info *kinfo,
const struct dt_device_node *node)
{
}
+
+static void __init assign_static_memory_11(struct domain *d,
+ struct kernel_info *kinfo,
+ const struct dt_device_node *node)
+{
+ ASSERT_UNREACHABLE();
+}
#endif
/*
@@ -3023,8 +3112,10 @@ static int __init construct_domU(struct domain *d,
#endif
if ( !dt_find_property(node, "xen,static-mem", NULL) )
allocate_memory(d, &kinfo);
- else
+ else if ( !is_domain_direct_mapped(d) )
allocate_static_memory(d, &kinfo, node);
+ else
+ assign_static_memory_11(d, &kinfo, node);
rc = prepare_dtb_domU(d, &kinfo);
if ( rc < 0 )