1+ #include <heap.h>
12#include <avz/fbdev_gnt.h>
23#include <avz/domain.h>
34#include <avz/memslot.h>
45#include <avz/sched.h>
56
6- #define MAX_FBDEV_PFN 8
7-
87typedef struct {
98 fbdev_info_t fbdev ;
10- addr_t fake_pfn ;
9+ void * fake_fbdev ;
1110 int current_slotID ;
1211} fbdev_priv_t ;
1312
@@ -24,29 +23,36 @@ static void __map_fbdev(struct domain *d, const fbdev_info_t *pfn_info)
2423 pgtable = (void * )d -> pagetable_vaddr ;
2524 ipa_addr = d -> fbdev_start_pfn << PAGE_SHIFT ;
2625
27- for (i = 0 ; i < pfn_info -> count ; i ++ ) {
28- phys_addr = pfn_info -> pfn [i ] << PAGE_SHIFT ;
29- size = pfn_info -> page_count [i ] << PAGE_SHIFT ;
26+ /* Map all distincts ranges of the framebuffer to the capsule */
27+ for (i = 0 ; i < pfn_info -> pfn_count ; i ++ ) {
28+ phys_addr = pfn_to_phys (pfn_info -> pfn [i ]);
29+ size = pfn_info -> page_count [i ] * PAGE_SIZE ;
3030
3131 __create_mapping (pgtable , ipa_addr , phys_addr , size , true, S2 );
3232
3333 ipa_addr += size ;
3434 }
3535}
3636
37- static void __map_fake_fbdev (struct domain * d , addr_t fake_pfn ,
38- const fbdev_info_t * real_fb )
37+ static void __map_fake_fbdev (struct domain * d , const fbdev_info_t * real_fb )
3938{
4039 size_t i , j ;
4140 addr_t phys_addr ;
4241 addr_t ipa_addr ;
4342 void * pgtable ;
4443
44+ /* One time malloc of fake framebuffer page */
45+ if (priv .fake_fbdev == NULL ) {
46+ priv .fake_fbdev = malloc (PAGE_SIZE );
47+ BUG_ON (!priv .fake_fbdev );
48+ }
49+
4550 pgtable = (void * )d -> pagetable_vaddr ;
46- ipa_addr = d -> fbdev_start_pfn << PAGE_SHIFT ;
47- phys_addr = fake_pfn << PAGE_SHIFT ;
51+ ipa_addr = pfn_to_phys ( d -> fbdev_start_pfn ) ;
52+ phys_addr = __pa ( priv . fake_fbdev ) ;
4853
49- for (i = 0 ; i < real_fb -> count ; i ++ ) {
54+ /* Map the capsule framebuffer to the fake one */
55+ for (i = 0 ; i < real_fb -> pfn_count ; i ++ ) {
5056 for (j = 0 ; j < real_fb -> page_count [i ]; j ++ ) {
5157 __create_mapping (pgtable , ipa_addr , phys_addr , PAGE_SIZE ,
5258 true, S2 );
@@ -58,40 +64,42 @@ static void __map_fake_fbdev(struct domain *d, addr_t fake_pfn,
5864
5965void fbdev_set_pgtable (struct domain * d , int slotID )
6066{
61- if (slotID <= 1 ) {
67+ /* Only capsules have virtual framebuffer */
68+ if ((slotID < MEMSLOT_BASE ) && !memslot [slotID ].busy )
6269 return ;
63- }
6470
65- if (slotID == priv .current_slotID ) {
71+ if (slotID == priv .current_slotID )
6672 __map_fbdev (d , & priv .fbdev );
67- } else {
68- __map_fake_fbdev (d , priv .fake_pfn , & priv .fbdev );
69- }
73+ else
74+ __map_fake_fbdev (d , & priv .fbdev );
7075}
7176
72- void fbdev_set_info (fbdev_info_t * fbdev , addr_t fake_pfn )
77+ void fbdev_set_info (fbdev_info_t * fbdev )
7378{
79+ int slotID ;
80+
7481 memcpy (& priv .fbdev , fbdev , sizeof (* fbdev ));
75- priv .fake_pfn = fake_pfn ;
7682
77- // TODO: check already existing capsule
83+ /* Map framebuffer to all capsules. */
84+ for (slotID = MEMSLOT_BASE ; slotID < MEMSLOT_NR ; slotID ++ )
85+ if (memslot [slotID ].busy )
86+ fbdev_set_pgtable (domains [slotID ], slotID );
7887}
7988
8089void fbdev_change_focus (int new_slotID )
8190{
82- if ((priv .current_slotID > 1 ) && memslot [priv .current_slotID ].busy ) {
83- __map_fake_fbdev (domains [priv .current_slotID ], priv .fake_pfn ,
84- & priv .fbdev );
85- }
91+ /* Remap old capsule to fake framebuffer */
92+ if ((priv .current_slotID >= MEMSLOT_BASE ) && memslot [priv .current_slotID ].busy )
93+ __map_fake_fbdev (domains [priv .current_slotID ], & priv .fbdev );
8694
87- if ((new_slotID > 1 ) && memslot [new_slotID ].busy ) {
95+ /* Map the new capsule to the framebuffer */
96+ if ((new_slotID >= MEMSLOT_BASE ) && memslot [new_slotID ].busy )
8897 __map_fbdev (domains [new_slotID ], & priv .fbdev );
89- }
9098
9199 priv .current_slotID = new_slotID ;
92100}
93101
94102addr_t fbdev_get_addr (void )
95103{
96- return current_domain -> fbdev_start_pfn << PAGE_SHIFT ;
104+ return pfn_to_phys ( current_domain -> fbdev_start_pfn ) ;
97105}
0 commit comments