1 #include <xen/bitops.h>
2 #include <xen/init.h>
3 #include <xen/irq.h>
4 #include <xen/pmap.h>
5 
6 #include <asm/pmap.h>
7 #include <asm/fixmap.h>
8 
9 /*
10  * Simple mapping infrastructure to map / unmap pages in fixed map.
11  * This is used to set the page table before the map domain page infrastructure
12  * is initialized.
13  *
14  * This structure is not protected by any locks, so it must not be used after
15  * smp bring-up.
16  */
17 
18 /* Bitmap to track which slot is used */
19 static __initdata DECLARE_BITMAP(inuse, NUM_FIX_PMAP);
20 
pmap_map(mfn_t mfn)21 void *__init pmap_map(mfn_t mfn)
22 {
23     unsigned int idx;
24     unsigned int slot;
25 
26     ASSERT(system_state < SYS_STATE_smp_boot);
27     ASSERT(!in_irq());
28 
29     idx = find_first_zero_bit(inuse, NUM_FIX_PMAP);
30     if ( idx == NUM_FIX_PMAP )
31         panic("Out of PMAP slots\n");
32 
33     __set_bit(idx, inuse);
34 
35     slot = idx + FIX_PMAP_BEGIN;
36     ASSERT(slot >= FIX_PMAP_BEGIN && slot <= FIX_PMAP_END);
37 
38     /*
39      * We cannot use set_fixmap() here. We use PMAP when the domain map
40      * page infrastructure is not yet initialized, so map_pages_to_xen() called
41      * by set_fixmap() needs to map pages on demand, which then calls pmap()
42      * again, resulting in a loop. Modify the PTEs directly instead. The same
43      * is true for pmap_unmap().
44      */
45     arch_pmap_map(slot, mfn);
46 
47     return fix_to_virt(slot);
48 }
49 
pmap_unmap(const void * p)50 void __init pmap_unmap(const void *p)
51 {
52     unsigned int idx;
53     unsigned int slot = virt_to_fix((unsigned long)p);
54 
55     ASSERT(system_state < SYS_STATE_smp_boot);
56     ASSERT(slot >= FIX_PMAP_BEGIN && slot <= FIX_PMAP_END);
57     ASSERT(!in_irq());
58 
59     idx = slot - FIX_PMAP_BEGIN;
60 
61     __clear_bit(idx, inuse);
62     arch_pmap_unmap(slot);
63 }
64 
65 /*
66  * Local variables:
67  * mode: C
68  * c-file-style: "BSD"
69  * c-basic-offset: 4
70  * indent-tabs-mode: nil
71  * End:
72  */
73