diff options
| author | Keir Fraser <Keir.Fraser@cl.cam.ac.uk> | 2005-03-30 16:17:04 -0500 |
|---|---|---|
| committer | Dave Jones <davej@redhat.com> | 2005-06-07 15:35:43 -0400 |
| commit | 07eee78ea8ba2d0b7b20551c35a3e7dd158d50bb (patch) | |
| tree | a11d2e705253faaa9779cfd83bb8ca9de311b195 | |
| parent | e29b545cb153f230fbd8ff4c19bc98ab950f9f5c (diff) | |
[PATCH] AGP fix for Xen VMM
When Linux is running on the Xen virtual machine monitor, physical
addresses are virtualised and cannot be directly referenced by the AGP
GART. This patch fixes the GART driver for Xen by adding a layer of
abstraction between physical addresses and 'GART addresses'.
Architecture-specific functions are also defined for allocating and freeing
the GATT. Xen requires this to ensure that table really is contiguous from
the point of view of the GART.
These extra interface functions are defined as 'no-ops' for all existing
architectures that use the GART driver.
Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Dave Jones <davej@redhat.com>
| -rw-r--r-- | drivers/char/agp/agp.h | 2 | ||||
| -rw-r--r-- | drivers/char/agp/ali-agp.c | 4 | ||||
| -rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 6 | ||||
| -rw-r--r-- | drivers/char/agp/amd64-agp.c | 4 | ||||
| -rw-r--r-- | drivers/char/agp/ati-agp.c | 6 | ||||
| -rw-r--r-- | drivers/char/agp/backend.c | 6 | ||||
| -rw-r--r-- | drivers/char/agp/efficeon-agp.c | 2 | ||||
| -rw-r--r-- | drivers/char/agp/generic.c | 17 | ||||
| -rw-r--r-- | drivers/char/agp/hp-agp.c | 4 | ||||
| -rw-r--r-- | drivers/char/agp/i460-agp.c | 4 | ||||
| -rw-r--r-- | drivers/char/agp/intel-agp.c | 6 | ||||
| -rw-r--r-- | drivers/char/agp/sworks-agp.c | 8 | ||||
| -rw-r--r-- | drivers/char/agp/uninorth-agp.c | 2 | ||||
| -rw-r--r-- | include/asm-alpha/agp.h | 10 | ||||
| -rw-r--r-- | include/asm-i386/agp.h | 10 | ||||
| -rw-r--r-- | include/asm-ia64/agp.h | 10 | ||||
| -rw-r--r-- | include/asm-ppc/agp.h | 10 | ||||
| -rw-r--r-- | include/asm-ppc64/agp.h | 10 | ||||
| -rw-r--r-- | include/asm-sparc64/agp.h | 10 | ||||
| -rw-r--r-- | include/asm-x86_64/agp.h | 10 |
20 files changed, 106 insertions, 35 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index ad9c11391d81..c1fe013c64f3 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
| @@ -278,6 +278,8 @@ void agp3_generic_cleanup(void); | |||
| 278 | #define AGP_GENERIC_SIZES_ENTRIES 11 | 278 | #define AGP_GENERIC_SIZES_ENTRIES 11 |
| 279 | extern struct aper_size_info_16 agp3_generic_sizes[]; | 279 | extern struct aper_size_info_16 agp3_generic_sizes[]; |
| 280 | 280 | ||
| 281 | #define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) | ||
| 282 | #define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) | ||
| 281 | 283 | ||
| 282 | extern int agp_off; | 284 | extern int agp_off; |
| 283 | extern int agp_try_unsupported_boot; | 285 | extern int agp_try_unsupported_boot; |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 0212febda654..9c9c9c2247ce 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
| @@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) | |||
| 150 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 150 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
| 151 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 151 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
| 152 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 152 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
| 153 | virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); | 153 | virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); |
| 154 | return addr; | 154 | return addr; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| @@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr) | |||
| 174 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 174 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
| 175 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 175 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
| 176 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 176 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
| 177 | virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); | 177 | virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); |
| 178 | agp_generic_destroy_page(addr); | 178 | agp_generic_destroy_page(addr); |
| 179 | } | 179 | } |
| 180 | 180 | ||
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index e62a3c2c44a9..3a41672e4d66 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
| @@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) | |||
| 43 | 43 | ||
| 44 | SetPageReserved(virt_to_page(page_map->real)); | 44 | SetPageReserved(virt_to_page(page_map->real)); |
| 45 | global_cache_flush(); | 45 | global_cache_flush(); |
| 46 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), | 46 | page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), |
| 47 | PAGE_SIZE); | 47 | PAGE_SIZE); |
| 48 | if (page_map->remapped == NULL) { | 48 | if (page_map->remapped == NULL) { |
| 49 | ClearPageReserved(virt_to_page(page_map->real)); | 49 | ClearPageReserved(virt_to_page(page_map->real)); |
| @@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
| 154 | 154 | ||
| 155 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 155 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
| 156 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; | 156 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; |
| 157 | agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); | 157 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); |
| 158 | 158 | ||
| 159 | /* Get the address for the gart region. | 159 | /* Get the address for the gart region. |
| 160 | * This is a bus address even on the alpha, b/c its | 160 | * This is a bus address even on the alpha, b/c its |
| @@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
| 167 | 167 | ||
| 168 | /* Calculate the agp offset */ | 168 | /* Calculate the agp offset */ |
| 169 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { | 169 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { |
| 170 | writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, | 170 | writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, |
| 171 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); | 171 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); |
| 172 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 172 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
| 173 | } | 173 | } |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 399c042f68f0..1407945a5892 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
| @@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] = | |||
| 219 | 219 | ||
| 220 | static int amd_8151_configure(void) | 220 | static int amd_8151_configure(void) |
| 221 | { | 221 | { |
| 222 | unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); | 222 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); |
| 223 | 223 | ||
| 224 | /* Configure AGP regs in each x86-64 host bridge. */ | 224 | /* Configure AGP regs in each x86-64 host bridge. */ |
| 225 | for_each_nb() { | 225 | for_each_nb() { |
| @@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) | |||
| 591 | { | 591 | { |
| 592 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 592 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
| 593 | 593 | ||
| 594 | release_mem_region(virt_to_phys(bridge->gatt_table_real), | 594 | release_mem_region(virt_to_gart(bridge->gatt_table_real), |
| 595 | amd64_aperture_sizes[bridge->aperture_size_idx].size); | 595 | amd64_aperture_sizes[bridge->aperture_size_idx].size); |
| 596 | agp_remove_bridge(bridge); | 596 | agp_remove_bridge(bridge); |
| 597 | agp_put_bridge(bridge); | 597 | agp_put_bridge(bridge); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index a65f8827c283..e572ced9100a 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
| @@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map) | |||
| 61 | 61 | ||
| 62 | SetPageReserved(virt_to_page(page_map->real)); | 62 | SetPageReserved(virt_to_page(page_map->real)); |
| 63 | err = map_page_into_agp(virt_to_page(page_map->real)); | 63 | err = map_page_into_agp(virt_to_page(page_map->real)); |
| 64 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), | 64 | page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), |
| 65 | PAGE_SIZE); | 65 | PAGE_SIZE); |
| 66 | if (page_map->remapped == NULL || err) { | 66 | if (page_map->remapped == NULL || err) { |
| 67 | ClearPageReserved(virt_to_page(page_map->real)); | 67 | ClearPageReserved(virt_to_page(page_map->real)); |
| @@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
| 343 | 343 | ||
| 344 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 344 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
| 345 | agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; | 345 | agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; |
| 346 | agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); | 346 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); |
| 347 | 347 | ||
| 348 | /* Write out the size register */ | 348 | /* Write out the size register */ |
| 349 | current_size = A_SIZE_LVL2(agp_bridge->current_size); | 349 | current_size = A_SIZE_LVL2(agp_bridge->current_size); |
| @@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
| 373 | 373 | ||
| 374 | /* Calculate the agp offset */ | 374 | /* Calculate the agp offset */ |
| 375 | for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { | 375 | for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { |
| 376 | writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1, | 376 | writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1, |
| 377 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); | 377 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); |
| 378 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 378 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
| 379 | } | 379 | } |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2f3dfb63bdc6..4d4e602fdc7e 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
| @@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
| 148 | return -ENOMEM; | 148 | return -ENOMEM; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | bridge->scratch_page_real = virt_to_phys(addr); | 151 | bridge->scratch_page_real = virt_to_gart(addr); |
| 152 | bridge->scratch_page = | 152 | bridge->scratch_page = |
| 153 | bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); | 153 | bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); |
| 154 | } | 154 | } |
| @@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
| 189 | err_out: | 189 | err_out: |
| 190 | if (bridge->driver->needs_scratch_page) | 190 | if (bridge->driver->needs_scratch_page) |
| 191 | bridge->driver->agp_destroy_page( | 191 | bridge->driver->agp_destroy_page( |
| 192 | |||
