From 3adccb193554387468ad669ac36453e888b1732d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Axel=20D=C3=B6rfler?=
Date: Sat, 26 Jan 2008 22:18:52 +0000
Subject: [PATCH] * More or less completely rewrote the AGP bus manager. * It
now also serves as a generic GART manager and accepts bus modules as well
as custom modules of graphics drivers if they want to (could be used for the
Radeon PCI GART stuff, for example). * Implemented GART support module for
Intel i965 and G33 chipsets (the other Intel chips will come later). *
Renamed agp bus manager to agp_gart to reflect its new functionality (even
though the AGP functionality is already outdated (due to PCIe), the GART
stuff remains current). * Adapted existing users of the AGP bus manager to
the API changes. * Not very well tested yet...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23754 a95241bf-73f2-0310-859d-f6bbb57e9c96
---
build/jam/HaikuImage | 4 +-
headers/private/graphics/AGP.h | 185 +-
.../accelerants/nvidia/engine/nv_agp.c | 102 +-
src/add-ons/accelerants/via/engine/agp.c | 144 +-
src/add-ons/kernel/bus_managers/agp/Jamfile | 22 +-
.../kernel/bus_managers/agp/README.html | 89 -
.../kernel/bus_managers/agp/UPDATE.html | 22 -
src/add-ons/kernel/bus_managers/agp/agp.cpp | 1553 ++++++++++++-----
src/add-ons/kernel/bus_managers/agp/agp.h | 23 -
.../kernel/bus_managers/agp/agp.settings | 12 -
.../kernel/bus_managers/agp/module.cpp | 66 -
src/add-ons/kernel/busses/Jamfile | 1 +
src/add-ons/kernel/busses/agp_gart/Jamfile | 20 +
.../kernel/busses/agp_gart/intel_gart.cpp | 486 ++++++
.../drivers/graphics/intel_extreme/driver.cpp | 8 +-
.../kernel/drivers/graphics/nvidia/driver.c | 8 +-
.../kernel/drivers/graphics/radeon/agp.c | 110 +-
.../kernel/drivers/graphics/radeon/driver.c | 146 +-
.../drivers/graphics/radeon/global_data.c | 4 +-
.../drivers/graphics/radeon/radeon_driver.h | 2 +-
.../kernel/drivers/graphics/via/driver.c | 11 +-
21 files changed, 1906 insertions(+), 1112 deletions(-)
delete mode 100644 src/add-ons/kernel/bus_managers/agp/README.html
delete mode 100644 src/add-ons/kernel/bus_managers/agp/UPDATE.html
delete mode 100644 src/add-ons/kernel/bus_managers/agp/agp.h
delete mode 100644 src/add-ons/kernel/bus_managers/agp/agp.settings
delete mode 100644 src/add-ons/kernel/bus_managers/agp/module.cpp
create mode 100644 src/add-ons/kernel/busses/agp_gart/Jamfile
create mode 100644 src/add-ons/kernel/busses/agp_gart/intel_gart.cpp
diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage
index 74277d2969..d5a5172fc6 100644
--- a/build/jam/HaikuImage
+++ b/build/jam/HaikuImage
@@ -125,7 +125,7 @@ BEOS_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com etherpci $(X86_ONLY)ipro1000
;
#BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button ;
BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
- config_manager $(X86_ONLY)agp usb firewire
+ config_manager agp_gart usb firewire
;
BEOS_ADD_ONS_FILE_SYSTEMS = bfs cdda fat googlefs iso9660 nfs ;
@@ -133,6 +133,8 @@ BEOS_ADD_ONS_FILE_SYSTEMS = bfs cdda fat googlefs iso9660 nfs ;
# modules
AddFilesToHaikuImage beos system add-ons kernel bus_managers
: $(BEOS_ADD_ONS_BUS_MANAGERS) ;
+AddFilesToHaikuImage beos system add-ons kernel busses agp_gart
+ : intel ;
AddFilesToHaikuImage beos system add-ons kernel busses ide
: generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata ;
AddFilesToHaikuImage beos system add-ons kernel busses scsi
diff --git a/headers/private/graphics/AGP.h b/headers/private/graphics/AGP.h
index 48ec232b84..b78b301f3e 100644
--- a/headers/private/graphics/AGP.h
+++ b/headers/private/graphics/AGP.h
@@ -1,108 +1,123 @@
-/*******************************************************************************
-/
-/ File: AGP.h
-/
-/ Description: Interface to the AGP bus and driver.
-/ For more information, see "AGP interface specification", Revision 2.0 and 3.0,
-/ Intel Corporation, 1998-2002.
-/
-/ Rudolf Cornelissen 6/2004-7/2004.
-/
-*******************************************************************************/
-
-#if !defined(_AGP_H_)
+/*
+ * Copyright 2004-2008, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _AGP_H_
#define _AGP_H_
+
#include
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* -----
- agp device info
------ */
typedef struct agp_info {
- ushort vendor_id; /* vendor id */
- ushort device_id; /* device id */
- uchar bus; /* bus number */
- uchar device; /* device number on bus */
- uchar function; /* function number in device */
- uchar class_sub; /* specific device function */
- uchar class_base; /* device type (display vs host bridge) */
- struct
- {
- uint32 agp_cap_id; /* AGP capability register as defined in the AGP standard */
- uint32 agp_stat; /* AGP STATUS register as defined in the AGP standard */
- uint32 agp_cmd; /* AGP COMMAND register as defined in the AGP standard */
+ ushort vendor_id; /* vendor id */
+ ushort device_id; /* device id */
+ uchar bus; /* bus number */
+ uchar device; /* device number on bus */
+ uchar function; /* function number in device */
+ uchar class_sub; /* specific device function */
+ uchar class_base; /* device type (display vs host bridge) */
+ struct {
+ uint32 capability_id; /* AGP capability register as defined in the AGP standard */
+ uint32 status; /* AGP STATUS register as defined in the AGP standard */
+ uint32 command; /* AGP COMMAND register as defined in the AGP standard */
} interface;
- status_t status; /* B_OK if usable, B_ERROR if device did not respond
- * according to the AGP standard */
} agp_info;
-typedef struct agp_module_info agp_module_info;
+typedef struct aperture_info {
+ addr_t physical_base;
+ addr_t base;
+ size_t size;
+ size_t reserved_size;
+} aperture_info;
-struct agp_module_info {
- bus_manager_info binfo;
-
- long (*get_nth_agp_info) (
- long index, /* index into agp device table */
- agp_info *info /* caller-supplied buffer for info */
- );
- void (*enable_agp) (
- uint32 *command /* max. mode to set */
- );
- //fixme: GART and APERTURE stuff is lacking for now, add here...
+/* flags for allocate_memory */
+enum {
+ B_APERTURE_NON_RESERVED = 0x01,
+ B_APERTURE_NEED_PHYSICAL = 0x02,
};
-#define B_AGP_MODULE_NAME "bus_managers/agp/v0"
+typedef int32 aperture_id;
+typedef struct gart_bus_module_info gart_bus_module_info;
+typedef struct agp_gart_module_info {
+ bus_manager_info info;
-/* ---
- value for the AGP_id field in the agp_cap_id register
---- */
-#define AGP_id 0x02 /* AGP device identification */
+ // AGP functionality
+ status_t (*get_nth_agp_info)(uint32 index, agp_info *info);
+ status_t (*acquire_agp)(void);
+ void (*release_agp)(void);
+ uint32 (*set_agp_mode)(uint32 command);
+ // GART functionality
+ aperture_id (*map_aperture)(uint8 bus, uint8 device, uint8 function,
+ size_t size, addr_t *_apertureBase);
+ aperture_id (*map_custom_aperture)(gart_bus_module_info *module,
+ addr_t *_apertureBase);
+ status_t (*unmap_aperture)(aperture_id id);
+ status_t (*get_aperture_info)(aperture_id id, aperture_info *info);
-/* ---
- masks for capability ID register bits
---- */
-#define AGP_id_mask 0x000000ff /* AGP capability identification, contains value 0x02 for AGP device */
-#define AGP_next_ptr 0x0000ff00 /* pointer to next item in PCI capabilities list, contains 0x00 if this is last item */
-#define AGP_next_ptr_shift 8
-#define AGP_rev_minor 0x000f0000 /* AGP Revision minor number reported */
-#define AGP_rev_minor_shift 16
-#define AGP_rev_major 0x00f00000 /* AGP Revision major number reported */
-#define AGP_rev_major_shift 20
+ status_t (*allocate_memory)(aperture_id id, size_t size,
+ size_t alignment, uint32 flags, addr_t *_apertureBase,
+ addr_t *_physicalBase);
+ status_t (*deallocate_memory)(aperture_id id, addr_t apertureBase);
+ status_t (*reserve_aperture)(aperture_id id, size_t size,
+ addr_t *_apertureBase);
+ status_t (*unreserve_aperture)(aperture_id id, addr_t apertureBase);
+ status_t (*bind_aperture)(aperture_id id, area_id area, addr_t base,
+ size_t size, size_t alignment, bool physical,
+ addr_t reservedBase, addr_t *_apertureBase);
+ status_t (*unbind_aperture)(aperture_id id, addr_t apertureBase);
+} agp_gart_module_info;
+#define B_AGP_GART_MODULE_NAME "bus_managers/agp_gart/v0"
-/* ---
- masks for status and command register bits
---- */
-#define AGP_2_1x 0x00000001 /* AGP Revision 2.0 1x speed transfer mode */
-#define AGP_2_2x 0x00000002 /* AGP Revision 2.0 2x speed transfer mode */
-#define AGP_2_4x 0x00000004 /* AGP Revision 2.0 4x speed transfer mode */
-#define AGP_3_4x 0x00000001 /* AGP Revision 3.0 4x speed transfer mode */
-#define AGP_3_8x 0x00000002 /* AGP Revision 3.0 8x speed transfer mode */
-#define AGP_rates 0x00000007 /* mask for supported rates info */
-#define AGP_rate_rev 0x00000008 /* 0 if AGP Revision 2.0 or earlier rate scheme, 1 if AGP Revision 3.0 rate scheme */
-#define AGP_FW 0x00000010 /* 1 if fastwrite transfers supported */
-#define AGP_4G 0x00000020 /* 1 if adresses above 4G bytes supported */
-#define AGP_SBA 0x00000200 /* 1 if sideband adressing supported */
-#define AGP_RQ 0xff000000 /* max. number of enqueued AGP command requests supported, minus one */
-#define AGP_RQ_shift 24
+struct agp_gart_for_bus_module_info {
+ module_info info;
+};
+#define B_AGP_GART_FOR_BUS_MODULE_NAME "bus_managers/agp_gart/bus/v0"
-/* ---
- masks for command register bits
---- */
-#define AGP_enable 0x00000100 /* set to 1 if AGP should be enabled */
+struct agp_gart_bus_module_info {
+ module_info info;
+ // TODO: add some stuff for non-generic AGP support as well
-#ifdef __cplusplus
-}
-#endif
+ status_t (*create_aperture)(uint8 bus, uint8 device, uint8 function,
+ size_t size, void **_aperture);
+ void (*delete_aperture)(void *aperture);
-#endif
+ status_t (*get_aperture_info)(void *aperture, aperture_info *info);
+ status_t (*set_aperture_size)(void *aperture, size_t size);
+ status_t (*bind_page)(void *aperture, uint32 offset,
+ addr_t physicalAddress);
+ status_t (*unbind_page)(void *aperture, uint32 offset);
+ void (*flush_tlbs)(void *aperture);
+};
+
+/* defines for capability ID register bits */
+#define AGP_REV_MINOR 0x000f0000 /* AGP Revision minor number reported */
+#define AGP_REV_MINOR_SHIFT 16
+#define AGP_REV_MAJOR 0x00f00000 /* AGP Revision major number reported */
+#define AGP_REV_MAJOR_SHIFT 20
+
+/* defines for status and command register bits */
+#define AGP_2_1x 0x00000001 /* AGP Revision 2.0 1x speed transfer mode */
+#define AGP_2_2x 0x00000002 /* AGP Revision 2.0 2x speed transfer mode */
+#define AGP_2_4x 0x00000004 /* AGP Revision 2.0 4x speed transfer mode */
+#define AGP_3_4x 0x00000001 /* AGP Revision 3.0 4x speed transfer mode */
+#define AGP_3_8x 0x00000002 /* AGP Revision 3.0 8x speed transfer mode */
+#define AGP_RATE_MASK 0x00000007 /* mask for supported rates info */
+#define AGP_3_MODE 0x00000008 /* 0 if AGP Revision 2.0 or earlier rate scheme,
+ * 1 if AGP Revision 3.0 rate scheme */
+#define AGP_FAST_WRITE 0x00000010 /* 1 if fast write transfers supported */
+#define AGP_ABOVE_4G 0x00000020 /* 1 if adresses above 4G bytes supported */
+#define AGP_SBA 0x00000200 /* 1 if side band adressing supported */
+#define AGP_REQUEST 0xff000000 /* max. number of enqueued AGP command requests
+ * supported, minus one */
+#define AGP_REQUEST_SHIFT 24
+
+/* masks for command register bits */
+#define AGP_ENABLE 0x00000100 /* set to 1 if AGP should be enabled */
+
+#endif /* _AGP_H_ */
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_agp.c b/src/add-ons/accelerants/nvidia/engine/nv_agp.c
index f2b4219146..3f6d0abd92 100644
--- a/src/add-ons/accelerants/nvidia/engine/nv_agp.c
+++ b/src/add-ons/accelerants/nvidia/engine/nv_agp.c
@@ -10,7 +10,9 @@
static void nv_agp_list_info(agp_info ai);
static void nv_agp_list_active(uint32 cmd);
-status_t nv_agp_setup(bool enable_agp)
+
+status_t
+nv_agp_setup(bool enable_agp)
{
nv_nth_agp_info nai;
nv_cmd_agp nca;
@@ -24,8 +26,7 @@ status_t nv_agp_setup(bool enable_agp)
/* first try to enable FW support on our card if user requested this
* ('unsupported' tweak!)
* This has no effect on PCI cards. */
- if (si->settings.unhide_fw)
- {
+ if (si->settings.unhide_fw) {
uint32 reg;
LOG(4, ("AGP: STRAPINFO2 contains $%08x\n", NV_REG32(NV32_NVSTRAPINFO2)));
@@ -43,15 +44,13 @@ status_t nv_agp_setup(bool enable_agp)
nca.magic = nai.magic = NV_PRIVATE_DATA_MAGIC;
/* contact driver and get a pointer to the registers and shared data */
- for (index = 0; index < 8; index++)
- {
+ for (index = 0; index < 8; index++) {
/* get nth AGP device info */
nai.index = index;
ioctl(fd, NV_GET_NTH_AGP_INFO, &nai, sizeof(nai));
/* abort if no agp busmanager found */
- if (!nai.agp_bus)
- {
+ if (!nai.agp_bus) {
LOG(4,("AGP: no AGP busmanager found.\n"));
/* don't touch AGP command register, we don't know what has been setup:
* touching it anyway might 'hang' the graphics card! */
@@ -60,8 +59,7 @@ status_t nv_agp_setup(bool enable_agp)
}
/* exit if we didn't get device info for this index */
- if (!nai.exist)
- {
+ if (!nai.exist) {
if (index != 0)
LOG(4,("AGP: end of AGP capable devices list.\n"));
else
@@ -72,12 +70,11 @@ status_t nv_agp_setup(bool enable_agp)
LOG(4,("AGP: AGP capable device #%d:\n", (index + 1)));
/* see if we are this one */
- if ((nai.agpi.device_id == si->device_id) &&
- (nai.agpi.vendor_id == si->vendor_id) &&
- (nai.agpi.bus == si->bus) &&
- (nai.agpi.device == si->device) &&
- (nai.agpi.function == si->function))
- {
+ if (nai.agpi.device_id == si->device_id
+ && nai.agpi.vendor_id == si->vendor_id
+ && nai.agpi.bus == si->bus
+ && nai.agpi.device == si->device
+ && nai.agpi.function == si->function) {
LOG(4,("AGP: (this is the device this accelerant controls)\n"));
agp = true;
/* remember our info */
@@ -95,8 +92,7 @@ status_t nv_agp_setup(bool enable_agp)
* AGP type cards as nVidia PCI cards still have AGP registers that pretend to
* support AGP.
* We rely on the AGP busmanager to iterate trough this list for us. */
- if (!agp)
- {
+ if (!agp) {
LOG(4,("AGP: the graphicscard this accelerant controls is PCI type.\n"));
/* make sure card is set for PCI access */
@@ -105,8 +101,7 @@ status_t nv_agp_setup(bool enable_agp)
return B_ERROR;
}
- if (si->settings.force_pci || !enable_agp)
- {
+ if (si->settings.force_pci || !enable_agp) {
/* set PCI mode if specified by user in nv.settings */
if (enable_agp)
LOG(4,("AGP: forcing PCI mode (specified in nv.settings)\n"));
@@ -117,31 +112,33 @@ status_t nv_agp_setup(bool enable_agp)
* (the AGP speed scheme is of no consequence now) */
nca.cmd = 0x00000000;
ioctl(fd, NV_ENABLE_AGP, &nca, sizeof(nca));
- }
- else
- {
+ } else {
/* activate AGP mode */
LOG(4,("AGP: activating AGP mode...\n"));
/* let the AGP busmanager worry about what mode to set.. */
nca.cmd = 0xfffffff7;
/* ..but we do need to select the right speed scheme fetched from our card */
- if (nv_ai.interface.agp_stat & AGP_rate_rev) nca.cmd |= AGP_rate_rev;
+ if (nv_ai.interface.status & AGP_3_MODE)
+ nca.cmd |= AGP_3_MODE;
ioctl(fd, NV_ENABLE_AGP, &nca, sizeof(nca));
/* tell the engine in may use AGP transfers if AGP is up and running */
- if (nca.cmd & AGP_enable) si->engine.agp_mode = true;
+ if (nca.cmd & AGP_ENABLE)
+ si->engine.agp_mode = true;
}
/* list mode now activated,
* make sure we have the correct speed scheme for logging */
- nv_agp_list_active(nca.cmd | (nv_ai.interface.agp_stat & AGP_rate_rev));
+ nv_agp_list_active(nca.cmd | (nv_ai.interface.status & AGP_3_MODE));
/* extra check */
LOG(4,("AGP: graphics card AGPCMD register readback $%08x\n", CFGR(AGPCMD)));
return B_OK;
}
-static void nv_agp_list_info(agp_info ai)
+
+static void
+nv_agp_list_info(agp_info ai)
{
/*
list device
@@ -158,45 +155,46 @@ static void nv_agp_list_info(agp_info ai)
list capabilities
*/
LOG(4,("AGP: this device supports AGP specification %d.%d;\n",
- ((ai.interface.agp_cap_id & AGP_rev_major) >> AGP_rev_major_shift),
- ((ai.interface.agp_cap_id & AGP_rev_minor) >> AGP_rev_minor_shift)));
+ ((ai.interface.capability_id & AGP_REV_MAJOR) >> AGP_REV_MAJOR_SHIFT),
+ ((ai.interface.capability_id & AGP_REV_MINOR) >> AGP_REV_MINOR_SHIFT)));
/* the AGP devices determine AGP speed scheme version used on power-up/reset */
- if (!(ai.interface.agp_stat & AGP_rate_rev))
- {
+ if (!(ai.interface.status & AGP_3_MODE)) {
/* AGP 2.0 scheme applies */
- if (ai.interface.agp_stat & AGP_2_1x)
+ if (ai.interface.status & AGP_2_1x)
LOG(4,("AGP: AGP 2.0 1x mode is available\n"));
- if (ai.interface.agp_stat & AGP_2_2x)
+ if (ai.interface.status & AGP_2_2x)
LOG(4,("AGP: AGP 2.0 2x mode is available\n"));
- if (ai.interface.agp_stat & AGP_2_4x)
+ if (ai.interface.status & AGP_2_4x)
LOG(4,("AGP: AGP 2.0 4x mode is available\n"));
- }
- else
- {
+ } else {
/* AGP 3.0 scheme applies */
- if (ai.interface.agp_stat & AGP_3_4x)
+ if (ai.interface.status & AGP_3_4x)
LOG(4,("AGP: AGP 3.0 4x mode is available\n"));
- if (ai.interface.agp_stat & AGP_3_8x)
+ if (ai.interface.status & AGP_3_8x)
LOG(4,("AGP: AGP 3.0 8x mode is available\n"));
}
- if (ai.interface.agp_stat & AGP_FW) LOG(4,("AGP: fastwrite transfers are supported\n"));
- if (ai.interface.agp_stat & AGP_SBA) LOG(4,("AGP: sideband adressing is supported\n"));
+ if (ai.interface.status & AGP_FAST_WRITE)
+ LOG(4,("AGP: fastwrite transfers are supported\n"));
+ if (ai.interface.status & AGP_SBA)
+ LOG(4,("AGP: sideband adressing is supported\n"));
LOG(4,("AGP: %d queued AGP requests can be handled.\n",
- (((ai.interface.agp_stat & AGP_RQ) >> AGP_RQ_shift) + 1)));
+ (((ai.interface.status & AGP_REQUEST) >> AGP_REQUEST_SHIFT) + 1)));
/*
list current settings,
make sure we have the correct speed scheme for logging
*/
- nv_agp_list_active(ai.interface.agp_cmd | (ai.interface.agp_stat & AGP_rate_rev));
+ nv_agp_list_active(ai.interface.command
+ | (ai.interface.status & AGP_3_MODE));
}
-static void nv_agp_list_active(uint32 cmd)
+
+static void
+nv_agp_list_active(uint32 cmd)
{
LOG(4,("AGP: listing settings now in use:\n"));
- if (!(cmd & AGP_rate_rev))
- {
+ if (!(cmd & AGP_3_MODE)) {
/* AGP 2.0 scheme applies */
if (cmd & AGP_2_1x)
LOG(4,("AGP: AGP 2.0 1x mode is set\n"));
@@ -204,20 +202,20 @@ static void nv_agp_list_active(uint32 cmd)
LOG(4,("AGP: AGP 2.0 2x mode is set\n"));
if (cmd & AGP_2_4x)
LOG(4,("AGP: AGP 2.0 4x mode is set\n"));
- }
- else
- {
+ } else {
/* AGP 3.0 scheme applies */
if (cmd & AGP_3_4x)
LOG(4,("AGP: AGP 3.0 4x mode is set\n"));
if (cmd & AGP_3_8x)
LOG(4,("AGP: AGP 3.0 8x mode is set\n"));
}
- if (cmd & AGP_FW) LOG(4,("AGP: fastwrite transfers are enabled\n"));
- if (cmd & AGP_SBA) LOG(4,("AGP: sideband adressing is enabled\n"));
+ if (cmd & AGP_FAST_WRITE)
+ LOG(4,("AGP: fastwrite transfers are enabled\n"));
+ if (cmd & AGP_SBA)
+ LOG(4,("AGP: sideband adressing is enabled\n"));
LOG(4,("AGP: max. AGP queued request depth is set to %d\n",
- (((cmd & AGP_RQ) >> AGP_RQ_shift) + 1)));
- if (cmd & AGP_enable)
+ (((cmd & AGP_REQUEST) >> AGP_REQUEST_SHIFT) + 1)));
+ if (cmd & AGP_ENABLE)
LOG(4,("AGP: the AGP interface is enabled.\n"));
else
LOG(4,("AGP: the AGP interface is disabled.\n"));
diff --git a/src/add-ons/accelerants/via/engine/agp.c b/src/add-ons/accelerants/via/engine/agp.c
index a10be3f6c4..34d4afd67f 100644
--- a/src/add-ons/accelerants/via/engine/agp.c
+++ b/src/add-ons/accelerants/via/engine/agp.c
@@ -7,10 +7,9 @@
#include
#include "std.h"
-static void eng_agp_list_info(agp_info ai);
-static void eng_agp_list_active(uint32 cmd);
-status_t eng_agp_setup(void)
+status_t
+eng_agp_setup(void)
{
eng_nth_agp_info nai;
eng_cmd_agp nca;
@@ -18,37 +17,17 @@ status_t eng_agp_setup(void)
agp_info eng_ai;
bool agp = false;
- /* first try to enable FW support on our card if user requested this
- * ('unsupported' tweak!)
- * This has no effect on PCI cards. */
-// if (si->settings.unhide_fw)
-// {
-// uint32 reg;
-
-// LOG(4, ("AGP: STRAPINFO2 contains $%08x\n", ENG_REG32(RG32_NVSTRAPINFO2)));
-
-// LOG(4, ("AGP: attempting to enable fastwrite support..\n"));
- /* 'force' FW support */
-// reg = (ENG_REG32(RG32_NVSTRAPINFO2) & ~0x00000800);
- /* enable strapinfo overwrite */
-// ENG_REG32(RG32_NVSTRAPINFO2) = (reg | 0x80000000);
-
-// LOG(4, ("AGP: STRAPINFO2 now contains $%08x\n", ENG_REG32(RG32_NVSTRAPINFO2)));
-// }
-
/* set the magic number so the via kerneldriver knows we're for real */
nca.magic = nai.magic = VIA_PRIVATE_DATA_MAGIC;
/* contact driver and get a pointer to the registers and shared data */
- for (index = 0; index < 8; index++)
- {
+ for (index = 0; index < 8; index++) {
/* get nth AGP device info */
nai.index = index;
ioctl(fd, ENG_GET_NTH_AGP_INFO, &nai, sizeof(nai));
/* abort if no agp busmanager found */
- if (!nai.agp_bus)
- {
+ if (!nai.agp_bus) {
LOG(4,("AGP: no AGP busmanager found.\n"));
/* don't touch AGP command register, we don't know what has been setup:
* touching it anyway might 'hang' the graphics card! */
@@ -57,8 +36,7 @@ status_t eng_agp_setup(void)
}
/* exit if we didn't get device info for this index */
- if (!nai.exist)
- {
+ if (!nai.exist) {
if (index != 0)
LOG(4,("AGP: end of AGP capable devices list.\n"));
else
@@ -69,20 +47,16 @@ status_t eng_agp_setup(void)
LOG(4,("AGP: AGP capable device #%d:\n", (index + 1)));
/* see if we are this one */
- if ((nai.agpi.device_id == si->device_id) &&
- (nai.agpi.vendor_id == si->vendor_id) &&
- (nai.agpi.bus == si->bus) &&
- (nai.agpi.device == si->device) &&
- (nai.agpi.function == si->function))
- {
+ if (nai.agpi.device_id == si->device_id
+ && nai.agpi.vendor_id == si->vendor_id
+ && nai.agpi.bus == si->bus
+ && nai.agpi.device == si->device
+ && nai.agpi.function == si->function) {
LOG(4,("AGP: (this is the device this accelerant controls)\n"));
agp = true;
/* remember our info */
eng_ai = nai.agpi;
}
-
- /* log capabilities */
- eng_agp_list_info(nai.agpi);
}
/* if our card is not an AGP type, abort here */
@@ -92,8 +66,7 @@ status_t eng_agp_setup(void)
* AGP type cards as PCI cards still might have AGP registers that pretend to
* support AGP.
* We rely on the AGP busmanager to iterate trough this list for us. */
- if (!agp)
- {
+ if (!agp) {
LOG(4,("AGP: the graphicscard this accelerant controls is PCI type.\n"));
/* make sure card is set for PCI access */
@@ -102,8 +75,7 @@ status_t eng_agp_setup(void)
return B_ERROR;
}
- if (si->settings.force_pci)
- {
+ if (si->settings.force_pci) {
/* set PCI mode if specified by user in skel.settings */
LOG(4,("AGP: forcing PCI mode (specified in via.settings)\n"));
@@ -111,106 +83,20 @@ status_t eng_agp_setup(void)
* (the AGP speed scheme is of no consequence now) */
nca.cmd = 0x00000000;
ioctl(fd, ENG_ENABLE_AGP, &nca, sizeof(nca));
- }
- else
- {
+ } else {
/* activate AGP mode */
LOG(4,("AGP: activating AGP mode...\n"));
/* let the AGP busmanager worry about what mode to set.. */
nca.cmd = 0xfffffff7;
/* ..but we do need to select the right speed scheme fetched from our card */
- if (eng_ai.interface.agp_stat & AGP_rate_rev) nca.cmd |= AGP_rate_rev;
+ if (eng_ai.interface.status & AGP_3_MODE)
+ nca.cmd |= AGP_3_MODE;
ioctl(fd, ENG_ENABLE_AGP, &nca, sizeof(nca));
}
- /* list mode now activated,
- * make sure we have the correct speed scheme for logging */
- eng_agp_list_active(nca.cmd | (eng_ai.interface.agp_stat & AGP_rate_rev));
-
/* extra check */
// LOG(4,("AGP: graphics card AGPCMD register readback $%08x\n", CFGR(AGPCMD)));
return B_OK;
}
-static void eng_agp_list_info(agp_info ai)
-{
- /*
- list device
- */
- if (ai.class_base == PCI_display)
- LOG(4,("AGP: device is a graphicscard, subclass ID is $%02x\n", ai.class_sub));
- else
- LOG(4,("AGP: device is a hostbridge, subclass ID is $%02x\n", ai.class_sub));
- LOG(4,("AGP: vendor ID $%04x\n", ai.vendor_id));
- LOG(4,("AGP: device ID $%04x\n", ai.device_id));
- LOG(4,("AGP: bus %d, device %d, function %d\n", ai.bus, ai.device, ai.function));
-
- /*
- list capabilities
- */
- LOG(4,("AGP: this device supports AGP specification %d.%d;\n",
- ((ai.interface.agp_cap_id & AGP_rev_major) >> AGP_rev_major_shift),
- ((ai.interface.agp_cap_id & AGP_rev_minor) >> AGP_rev_minor_shift)));
-
- /* the AGP devices determine AGP speed scheme version used on power-up/reset */
- if (!(ai.interface.agp_stat & AGP_rate_rev))
- {
- /* AGP 2.0 scheme applies */
- if (ai.interface.agp_stat & AGP_2_1x)
- LOG(4,("AGP: AGP 2.0 1x mode is available\n"));
- if (ai.interface.agp_stat & AGP_2_2x)
- LOG(4,("AGP: AGP 2.0 2x mode is available\n"));
- if (ai.interface.agp_stat & AGP_2_4x)
- LOG(4,("AGP: AGP 2.0 4x mode is available\n"));
- }
- else
- {
- /* AGP 3.0 scheme applies */
- if (ai.interface.agp_stat & AGP_3_4x)
- LOG(4,("AGP: AGP 3.0 4x mode is available\n"));
- if (ai.interface.agp_stat & AGP_3_8x)
- LOG(4,("AGP: AGP 3.0 8x mode is available\n"));
- }
- if (ai.interface.agp_stat & AGP_FW) LOG(4,("AGP: fastwrite transfers are supported\n"));
- if (ai.interface.agp_stat & AGP_SBA) LOG(4,("AGP: sideband adressing is supported\n"));
- LOG(4,("AGP: %d queued AGP requests can be handled.\n",
- (((ai.interface.agp_stat & AGP_RQ) >> AGP_RQ_shift) + 1)));
-
- /*
- list current settings,
- make sure we have the correct speed scheme for logging
- */
- eng_agp_list_active(ai.interface.agp_cmd | (ai.interface.agp_stat & AGP_rate_rev));
-}
-
-static void eng_agp_list_active(uint32 cmd)
-{
- LOG(4,("AGP: listing settings now in use:\n"));
- if (!(cmd & AGP_rate_rev))
- {
- /* AGP 2.0 scheme applies */
- if (cmd & AGP_2_1x)
- LOG(4,("AGP: AGP 2.0 1x mode is set\n"));
- if (cmd & AGP_2_2x)
- LOG(4,("AGP: AGP 2.0 2x mode is set\n"));
- if (cmd & AGP_2_4x)
- LOG(4,("AGP: AGP 2.0 4x mode is set\n"));
- }
- else
- {
- /* AGP 3.0 scheme applies */
- if (cmd & AGP_3_4x)
- LOG(4,("AGP: AGP 3.0 4x mode is set\n"));
- if (cmd & AGP_3_8x)
- LOG(4,("AGP: AGP 3.0 8x mode is set\n"));
- }
- if (cmd & AGP_FW) LOG(4,("AGP: fastwrite transfers are enabled\n"));
- if (cmd & AGP_SBA) LOG(4,("AGP: sideband adressing is enabled\n"));
- LOG(4,("AGP: max. AGP queued request depth is set to %d\n",
- (((cmd & AGP_RQ) >> AGP_RQ_shift) + 1)));
- if (cmd & AGP_enable)
- LOG(4,("AGP: the AGP interface is enabled.\n"));
- else
- LOG(4,("AGP: the AGP interface is disabled.\n"));
-}
diff --git a/src/add-ons/kernel/bus_managers/agp/Jamfile b/src/add-ons/kernel/bus_managers/agp/Jamfile
index bbb2a97f3e..5a85f7717d 100644
--- a/src/add-ons/kernel/bus_managers/agp/Jamfile
+++ b/src/add-ons/kernel/bus_managers/agp/Jamfile
@@ -1,23 +1,13 @@
SubDir HAIKU_TOP src add-ons kernel bus_managers agp ;
SetSubDirSupportedPlatformsBeOSCompatible ;
+SubDirC++Flags -fno-rtti ;
-UsePrivateHeaders graphics ;
+UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ;
+UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ;
+UsePrivateHeaders [ FDirName graphics intel_extreme ] ;
+UsePrivateHeaders graphics kernel ;
-Package haiku-agp :
- README.html
- UPDATE.html
- ;
-
-Package haiku-agp :
- agp :
- boot home config add-ons kernel bus_managers ;
-
-Package haiku-agp :
- agp.settings :
- boot home config settings kernel drivers ;
-
-KernelAddon agp :
+KernelAddon agp_gart :
agp.cpp
- module.cpp
;
diff --git a/src/add-ons/kernel/bus_managers/agp/README.html b/src/add-ons/kernel/bus_managers/agp/README.html
deleted file mode 100644
index 297b168cf8..0000000000
--- a/src/add-ons/kernel/bus_managers/agp/README.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
- Readme for the AGP busmanager module
-
-
-AGP busmanager module
-
-NOTE PLEASE:
-You use this software at your own risk! Although I don't expect it to damage your PC, videocard or Monitor, I cannot guarantee this!
-
-Supported devices:
-
- - all 'PCI-class' host bridges with AGP interface;
-
- all 'PCI-class' graphics cards with AGP interface.
-
-
-
-Features:
-
- - Can enable AGP transfers including SBA (sideband adressing);
-
- Sets up AGP maximum request depth.
-
- Can enable PCI FW (fastwrites);
-
-Known limitations:
-
- - No GART and AGP aperture support (yet);
-
- No AGP3.0 specific feature support (yet), such as 'asynchronous request size', 'calibration cycle' and 'isochronous transfers'. The registers and register-fields for these features are currently programmed to default 'safe' modes or disabled on power-up.
-
-
-
-Installation:
-This module will install in the user part of the BeOS, so not in the system part where the official modules are.
-BeOS first checks (during boot) if there are 'user-addons' that should be loaded for a device. If not, it loads it's own add-ons (if any). You can select if this module should be loaded by hitting the spacebar as soon as the BeOS 'icons' screen appears. If you select disable user addons the system will not load it or other 'user-addons'. If you don't do anything, the system will load the AGP busmanager module if requested by a driver.
-
-Note: This might turn out to be handy if you run into trouble upon testing the module, or if you are 'tweaking' the agp.settings file...
-
-actual INSTALLATION:
-
-Doubleclick on the install.sh file and follow the instructions. You have to reboot in order to use the AGP busmanager module. Make sure you read the Settings information below before you do that...
-
-
-alternate INSTALLATION method:
-
-Unzip the zip file that contains the module to the root folder. Now reboot and you should be using it if requested by a driver.
-
-
-DE-INSTALLATION:
-
-Currently there's no uninstall script included. Just do it manually:
-
-Delete the agp file in home/config/add-ons/kernel/bus_managers/
-Delete the agp.settings file in home/config/settings/kernel/drivers/
-
-You have to reboot in order to apply the original configuration.
-
-
-
-Settings:
-Please read this information carefully *before* installing and using the AGP busmanager module. It might spare you some trouble afterwards..
-The module uses a file named agp.settings to determine how to setup your AGP bus(es). After installation this file will be located at home/config/settings/kernel/drivers/. You shouldn't touch this file unless your system becomes unstable with the AGP mode active. It has a default configuration for maximum effect, but you might have to scale back a little if your system gives trouble... Anyway, read the nifty details below.
-
-Note: The module only reads this file during it's initialisation. This means that you have to reboot in order to let changes take effect.
-Note also: A graphicsdriver may or may not further reduce the mode that gets setup by the AGP busmanager. See the graphicsdriver documentation for more info on this.
-
-
-
-agp.settings module configuration:
-
- - max_speed: (disabled by default)
- This option enables you to set a maximum speed that may be setup by the module, instead of the maximum your system reports being capable of. Valid values are 1,2,4 and 8. If a value makes no sense (because the settings file contains an illegal value, or the hardware uses a speed-scheme that's not capable of setting a specific requested max. speed) the module will take the next logical lower one: PCI mode being the lowest speed setting (which is what you were using before you installed this module).
-This option is disabled by default (preceded by a '#').
- - block_agp: (set to 'false' by default)
- If set to 'true' this option blocks use of AGP transfers entirely including PCI fastwrites: so fallback to standard 'old-fashioned' PCI mode.
- - block_sba: (set to 'false' by default)
- If set to 'true' this option blocks use of sideband adressing if at least one of the devices on the bus is pre-AGP3.0. Sideband adressing speeds up AGP transfers a bit because it's a seperate (low-speed) communications 'channel' that's used alongside the main transfer channel concurrently. So this enables 'full-duplex' communications, while disabling SBA forces the hardware to use 'half-duplex' communications. SBA is a requirement for AGP3 compliance, so if AGP3 is in effect, this setting is ignored.
- - block_fw: (set to 'true' by default)
- If set to 'true' this option blocks use of PCI fastwrites. PCI fastwrites work in the same speed AGP transfers work. This means PCI fastwrites are faster in AGP4x mode than they are in AGP2x mode (for instance). PCI fastwrites are used whenever the system (CPU) initiates transfers to the graphicscard, while 'standard PCI' or AGP transfers are used if the graphicscard's acceleration engine (GPU) initiates transfers to or from the system respectively.
-This means that PCI FW is the only AGP 'feature' that has an effect on the graphics speed on BeOS as it is currently, except for users of the nVidia driver(s). The use of AGP transfers require graphicsdriver support, which is built-in inside the 2D and 3D nVidia drivers. Note please that PCI fastwrites might still be used for texture loading for accelerated 3D...
-Note:
-PCI FW support was first introduced with the AGP2.0 specification: that is, devices that support upto and including AGP4X mode are candidates to have this feature.
-
-
-
-Rudolf Cornelissen.
-(Page last updated on April 11, 2006)
-
-
diff --git a/src/add-ons/kernel/bus_managers/agp/UPDATE.html b/src/add-ons/kernel/bus_managers/agp/UPDATE.html
deleted file mode 100644
index 71a6c000a1..0000000000
--- a/src/add-ons/kernel/bus_managers/agp/UPDATE.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-Changes
-
-
-Changes done for each module version:
-agp_module 0.02 (Rudolf)
-
- - Reversed order of programming devices when AGP mode is requested to be disabled. The order of programming devices now adheres to the official AGP specification (missed this item before). This fixes potential coldstart trouble on nVidia cards at least (confirmed a GeForce 4 MX4000);
-
- Modified agp.setting for blocking PCI fastwrites (block_fw) to be set to true by default: Fastwrites tend to create trouble on some systems outthere (most notably systems with ATI graphics cards).
-
-agp_module 0.01 (Rudolf)
-
-Still todo:
-
- - a lot, in due time ;-)
-
-
-
-
diff --git a/src/add-ons/kernel/bus_managers/agp/agp.cpp b/src/add-ons/kernel/bus_managers/agp/agp.cpp
index 226fdf321b..87d1e6e70f 100644
--- a/src/add-ons/kernel/bus_managers/agp/agp.cpp
+++ b/src/add-ons/kernel/bus_managers/agp/agp.cpp
@@ -1,538 +1,1149 @@
/*
- written by Rudolf Cornelissen 7/2004-4/2006
-*/
+ * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
+ * Copyright 2004-2006, Rudolf Cornelissen. All rights reserved.
+ *
+ * Distributed under the terms of the MIT License.
+ */
+
+// TODO: rethink the AGP interface for more than one bridge/device!
+// (should be done with the new driver API then)
/*
Notes:
- -currently we just setup all found devices with AGP interface to the same highest common mode,
- we don't distinquish different AGP buses.
+ - currently we just setup all found devices with AGP interface to the same
+ highest common mode, we don't distinquish different AGP busses.
+ TODO: it might be a better idea to just setup one instead.
- -no aperture and GART support, just enabling AGP transfer mode. Aperture and GART support are
- probably easiest to setup for AGP3, as this version of the standard defines all registers needed
- so we can probably program in the same universal way as we are doing right now. AGP2 requires
- specific 'drivers' for each chipset outthere, as the registers are implemented in a lot of
- different ways here.
- Aperture and GART support is only usefull, once we setup hardware 3D acceleration.
+ - AGP3 defines 'asynchronous request size' and 'calibration cycle' fields
+ in the status and command registers. Currently programming zero's which will
+ make it work, although further optimisation is possible.
- -AGP3 defines 'asynchronous request size' and 'calibration cycle' fields in the status and command
- registers. Currently programming zero's which will make it work, although further optimisation
- is possible.
-
- -AGP3.5 also defines isochronous transfers which are not implemented here: the hardware keeps them
- disabled by default.
+ - AGP3.5 also defines isochronous transfers which are not implemented here:
+ the hardware keeps them disabled by default.
*/
-#include
-#include
-#include // for strtoXX
-#include "agp.h"
-typedef struct {
- sem_id sem;
- int32 ben;
-} benaphore;
+#include
+
+#include
+
+#include
+#include
+
+#include
+#ifdef __HAIKU__
+# include
+# include
+# include
+#endif
+
+#include
+
+#ifndef __HAIKU__
+# define PCI_capabilities_ptr 0x34
+# define PCI_status_capabilities 0x0010
+# define PCI_cap_id_agp 0x02
+# define B_NOT_SUPPORTED B_ERROR
+#endif
+
+#define TRACE_AGP
+#ifdef TRACE_AGP
+# define TRACE(x...) dprintf("\33[36mAGP:\33[0m " x)
+#else
+# define TRACE(x...) ;
+#endif
-#define INIT_BEN(x) x.sem = create_sem(0, "AGP "#x" benaphore"); x.ben = 0;
-#define AQUIRE_BEN(x) if((atomic_add(&(x.ben), 1)) >= 1) acquire_sem(x.sem);
-#define RELEASE_BEN(x) if((atomic_add(&(x.ben), -1)) > 1) release_sem(x.sem);
-#define DELETE_BEN(x) delete_sem(x.sem);
#define MAX_DEVICES 8
+#define AGP_ID(address) (address)
+#define AGP_STATUS(address) (address + 4)
+#define AGP_COMMAND(address) (address + 8)
+
+#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
+
/* read and write to PCI config space */
-#define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s))
-#define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v))
+#define get_pci_config(info, offset, size) \
+ (sPCI->read_pci_config((info).bus, (info).device, (info).function, \
+ (offset), (size)))
+#define set_pci_config(info, offset, size, value) \
+ (sPCI->write_pci_config((info).bus, (info).device, (info).function, \
+ (offset), (size), (value)))
-/* these structures are private to the module */
-typedef struct device_info device_info;
+#define RESERVED_APERTURE 0x80000000
+#define ALLOCATED_APERTURE 0x40000000
+#define BIND_APERTURE 0x20000000
+#define APERTURE_PUBLIC_FLAGS_MASK 0x0000ffff
-struct device_info {
- uint8 agp_adress; /* location of AGP interface in PCI capabilities list */
- agp_info agpi; /* agp info for this device */
- pci_info pcii; /* pci info for this device */
+struct aperture_memory : HashTableLink {
+ aperture_memory *next;
+ addr_t base;
+ size_t size;
+ uint32 flags;
+#ifdef __HAIKU__
+ union {
+ vm_page **pages;
+ vm_page *page;
+ };
+#else
+ area_id area;
+#endif
};
-typedef struct {
- long count; /* number of devices actually found */
- benaphore kernel; /* for serializing access */
- device_info di[MAX_DEVICES]; /* device specific stuff */
-} DeviceData;
+class Aperture;
-typedef struct settings { //see comments in agp.settings
- uint32 max_speed;
- bool block_agp;
- bool block_sba;
- bool block_fw;
-} settings;
+class MemoryHashDefinition {
+public:
+ typedef addr_t KeyType;
+ typedef aperture_memory ValueType;
-/* prototypes for our private functions */
-static bool has_AGP_interface(pci_info *pcii, uint8 *adress);
-static status_t probe_devices(void);
-static void read_settings(void);
-static void check_settings(uint32 *command);
-static void check_capabilities(uint32 agp_stat, uint32 *command);
+ MemoryHashDefinition(aperture_info &info) : fInfo(info) {}
+ size_t HashKey(const KeyType &base) const
+ { return (base - fInfo.base) / B_PAGE_SIZE; }
+ size_t Hash(aperture_memory *memory) const
+ { return (memory->base - fInfo.base) / B_PAGE_SIZE; }
+ bool Compare(const KeyType &base, aperture_memory *memory) const
+ { return base == memory->base; }
+ HashTableLink *GetLink(aperture_memory *memory) const
+ { return memory; }
-static DeviceData *pd;
-static pci_module_info *pci_bus;
-
-static settings current_settings = { //see comments in agp.settings
- 0, // max_speed
- false, // block_agp
- false, // block_sba
- true, // block_fw
+private:
+ aperture_info &fInfo;
};
+typedef OpenHashTable MemoryHashTable;
-status_t init(void)
+struct agp_device_info {
+ uint8 address; /* location of AGP interface in PCI capabilities */
+ agp_info info;
+};
+
+class Aperture : public HashTableLink {
+public:
+ Aperture(agp_gart_bus_module_info *module, void *aperture);
+ ~Aperture();
+
+ status_t InitCheck() const { return fLock.sem >= B_OK ? B_OK : fLock.sem; }
+
+ void DeleteMemory(aperture_memory *memory);
+ aperture_memory *CreateMemory(size_t size, size_t alignment, uint32 flags);
+
+ status_t AllocateMemory(aperture_memory *memory, uint32 flags);
+
+ status_t UnbindMemory(aperture_memory *memory);
+ status_t BindMemory(aperture_memory *memory, addr_t base, size_t size,
+ bool physical);
+
+ status_t GetInfo(aperture_info *info);
+
+ aperture_memory *GetMemory(addr_t base) { return fHashTable.Lookup(base); }
+
+ addr_t Base() const { return fInfo.base; }
+ addr_t Size() const { return fInfo.size; }
+ int32 ID() const { return fID; }
+ struct lock &Lock() { return fLock; }
+
+private:
+ void _Free(aperture_memory *memory);
+
+ void _Remove(aperture_memory *memory);
+ status_t _Insert(aperture_memory *memory, size_t size, size_t alignment,
+ uint32 flags);
+
+ struct lock fLock;
+ agp_gart_bus_module_info *fModule;
+ int32 fID;
+ aperture_info fInfo;
+ MemoryHashTable fHashTable;
+ aperture_memory *fFirstMemory;
+ void *fPrivateAperture;
+};
+
+class ApertureHashDefinition {
+public:
+ typedef int32 KeyType;
+ typedef Aperture ValueType;
+
+ size_t HashKey(const KeyType &id) const
+ { return id; }
+ size_t Hash(Aperture *aperture) const
+ { return aperture->ID(); }
+ bool Compare(const KeyType &id, Aperture *aperture) const
+ { return id == aperture->ID(); }
+ HashTableLink *GetLink(Aperture *aperture) const
+ { return aperture; }
+};
+
+typedef OpenHashTable ApertureHashTable;
+
+
+static agp_device_info sDeviceInfos[MAX_DEVICES];
+static uint32 sDeviceCount;
+static pci_module_info *sPCI;
+static int32 sAcquired;
+static ApertureHashTable sApertureHashTable;
+static int32 sNextApertureID;
+static struct lock sLock;
+
+
+// #pragma mark - private support functions
+
+
+/*! Makes sure that all bits lower than the maximum supported rate is set. */
+static uint32
+fix_rate_support(uint32 command)
{
- /* get a handle for the pci bus */
- if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK)
- return B_ERROR;
+ if ((command & AGP_3_MODE) != 0) {
+ if ((command & AGP_3_8x) != 0)
+ command |= AGP_3_4x;
- /* private data */
- pd = (DeviceData *)calloc(1, sizeof(DeviceData));
- if (!pd)
- {
- put_module(B_PCI_MODULE_NAME);
- return B_ERROR;
- }
- /* initialize the benaphore */
- INIT_BEN(pd->kernel);
-
- /* find all of our supported devices, if any */
- if (probe_devices() != B_OK)
- {
- /* free the driver data */
- DELETE_BEN(pd->kernel);
- free(pd);
- pd = NULL;
-
- put_module(B_PCI_MODULE_NAME);
- return B_ERROR;
+ command &= ~AGP_RATE_MASK | AGP_3_8x | AGP_3_4x;
+ command |= AGP_SBA;
+ // SBA is required for AGP3
+ } else {
+ /* AGP 2.0 scheme applies */
+ if ((command & AGP_2_4x) != 0)
+ command |= AGP_2_2x;
+ if ((command & AGP_2_2x) != 0)
+ command |= AGP_2_1x;
}
- /* parse settings file if there */
- read_settings();
+ return command;
+}
+
+/*! Makes sure that only the highest rate bit is set. */
+static uint32
+fix_rate_command(uint32 command)
+{
+ if ((command & AGP_3_MODE) != 0) {
+ if ((command & AGP_3_8x) != 0)
+ command &= ~AGP_3_4x;
+ } else {
+ /* AGP 2.0 scheme applies */
+ if ((command & AGP_2_4x) != 0)
+ command &= ~(AGP_2_2x | AGP_2_1x);
+ if ((command & AGP_2_2x) != 0)
+ command &= ~AGP_2_1x;
+ }
+
+ return command;
+}
+
+
+/*! Checks the capabilities of the device, and removes everything from
+ \a command that the device does not support.
+*/
+static void
+check_capabilities(agp_device_info &deviceInfo, uint32 &command)
+{
+ uint32 agpStatus = deviceInfo.info.interface.status;
+ if (deviceInfo.info.class_base == PCI_bridge) {
+ // make sure the AGP rate support mask is correct
+ // (ie. has the lower bits set)
+ agpStatus = fix_rate_support(agpStatus);
+ }
+
+ // block non-supported AGP modes
+ command &= (agpStatus & (AGP_3_MODE | AGP_RATE_MASK))
+ | ~(AGP_3_MODE | AGP_RATE_MASK);
+
+ // If no AGP mode is supported at all, nothing remains:
+ // devices exist that have the AGP style connector with AGP style registers,
+ // but not the features!
+ // (confirmed Matrox Millenium II AGP for instance)
+ if ((agpStatus & AGP_RATE_MASK) == 0)
+ command = 0;
+
+ // block side band adressing if not supported
+ if ((agpStatus & AGP_SBA) == 0)
+ command &= ~AGP_SBA;
+
+ // block fast writes if not supported
+ if ((agpStatus & AGP_FAST_WRITE) == 0)
+ command &= ~AGP_FAST_WRITE;
+
+ // adjust maximum request depth to least depth supported
+ // note: this is writable only in the graphics card
+ uint8 requestDepth = ((agpStatus & AGP_REQUEST) >> AGP_REQUEST_SHIFT);
+ if (requestDepth < ((command & AGP_REQUEST) >> AGP_REQUEST_SHIFT)) {
+ command &= ~AGP_REQUEST;
+ command |= (requestDepth << AGP_REQUEST_SHIFT);
+ }
+}
+
+
+/*! Checks the PCI capabilities if the device is an AGP device
+*/
+static bool
+is_agp_device(pci_info &info, uint8 *_address)
+{
+ // Check if device implements a list of capabilities
+ if ((get_pci_config(info, PCI_status, 2) & PCI_status_capabilities) == 0)
+ return false;
+
+ // Get pointer to PCI capabilities list
+ // (AGP devices only, no need to take cardbus into account)
+ uint8 address = get_pci_config(info, PCI_capabilities_ptr, 1);
+
+ while (true) {
+ uint8 id = get_pci_config(info, address, 1);
+ uint8 next = get_pci_config(info, address + 1, 1) & ~0x3;
+
+ if (id == PCI_cap_id_agp) {
+ // is an AGP device
+ if (_address != NULL)
+ *_address = address;
+ return true;
+ }
+ if (next == 0) {
+ // end of list
+ break;
+ }
+
+ address = next;
+ }
+
+ return false;
+}
+
+
+static status_t
+get_next_agp_device(uint32 *_cookie, pci_info &info, agp_device_info &device)
+{
+ uint32 index = *_cookie;
+
+ // find devices
+
+ for (; sPCI->get_nth_pci_info(index, &info) == B_OK; index++) {
+ // is it a bridge or a graphics card?
+ if ((info.class_base != PCI_bridge || info.class_sub != PCI_host)
+ && info.class_base != PCI_display)
+ continue;
+
+ if (is_agp_device(info, &device.address)) {
+ device.info.vendor_id = info.vendor_id;
+ device.info.device_id = info.device_id;
+ device.info.bus = info.bus;
+ device.info.device = info.device;
+ device.info.function = info.function;
+ device.info.class_sub = info.class_sub;
+ device.info.class_base = info.class_base;
+
+ /* get the contents of the AGP registers from this device */
+ device.info.interface.capability_id = get_pci_config(info,
+ AGP_ID(device.address), 4);
+ device.info.interface.status = get_pci_config(info,
+ AGP_STATUS(device.address), 4);
+ device.info.interface.command = get_pci_config(info,
+ AGP_COMMAND(device.address), 4);
+
+ *_cookie = index + 1;
+ return B_OK;
+ }
+ }
+
+ return B_ENTRY_NOT_FOUND;
+}
+
+
+static void
+set_agp_command(agp_device_info &deviceInfo, uint32 command)
+{
+ set_pci_config(deviceInfo.info, AGP_COMMAND(deviceInfo.address), 4, command);
+ deviceInfo.info.interface.command = get_pci_config(deviceInfo.info,
+ AGP_COMMAND(deviceInfo.address), 4);
+}
+
+
+static void
+set_pci_mode()
+{
+ // First program all graphics cards
+
+ for (uint32 index = 0; index < sDeviceCount; index++) {
+ agp_device_info &deviceInfo = sDeviceInfos[index];
+ if (deviceInfo.info.class_base != PCI_display)
+ continue;
+
+ set_agp_command(deviceInfo, 0);
+ }
+
+ // Then program all bridges - it's the other around for AGP mode
+
+ for (uint32 index = 0; index < sDeviceCount; index++) {
+ agp_device_info &deviceInfo = sDeviceInfos[index];
+ if (deviceInfo.info.class_base != PCI_bridge)
+ continue;
+
+ set_agp_command(deviceInfo, 0);
+ }
+
+ // Wait 10mS for the bridges to recover (failsafe!)
+ // Note: some SiS bridge chipsets apparantly require 5mS to recover
+ // or the master (graphics card) cannot be initialized correctly!
+ snooze(10000);
+}
+
+
+Aperture *
+get_aperture(aperture_id id)
+{
+ Autolock _(sLock);
+ return sApertureHashTable.Lookup(id);
+}
+
+
+// #pragma mark - Aperture
+
+
+Aperture::Aperture(agp_gart_bus_module_info *module, void *aperture)
+ :
+ fModule(module),
+ fHashTable(fInfo),
+ fPrivateAperture(aperture)
+{
+ fModule->get_aperture_info(fPrivateAperture, &fInfo);
+ fID = atomic_add(&sNextApertureID, 1);
+ init_lock(&fLock, "aperture");
+}
+
+
+Aperture::~Aperture()
+{
+ fModule->delete_aperture(fPrivateAperture);
+ put_module(fModule->info.name);
+}
+
+
+status_t
+Aperture::GetInfo(aperture_info *info)
+{
+ if (info == NULL)
+ return B_BAD_VALUE;
+
+ *info = fInfo;
return B_OK;
}
-static status_t probe_devices(void)
+
+void
+Aperture::DeleteMemory(aperture_memory *memory)
{
- uint32 pci_index = 0;
- long count = 0;
- device_info *di = pd->di;
- pci_info *pcii;
- uint8 adress;
+ UnbindMemory(memory);
+ _Free(memory);
+ _Remove(memory);
+ fHashTable.Remove(memory);
+ delete memory;
+}
- /* while there are more pci devices */
- while ((count < MAX_DEVICES) && ((*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) == B_NO_ERROR))
- {
- /* if the device is a hostbridge or a graphicscard */
- if (((di->pcii.class_base == PCI_bridge) && (di->pcii.class_sub == PCI_host)) ||
- (di->pcii.class_base == PCI_display))
- {
- pcii = &(di->pcii);
- /* if the device has an AGP interface */
- if (has_AGP_interface(pcii, &adress))
- {
- /* fill out the agp_info struct */
- pd->di[count].agpi.vendor_id = di->pcii.vendor_id;
- pd->di[count].agpi.device_id = di->pcii.device_id;
- pd->di[count].agpi.bus = di->pcii.bus;
- pd->di[count].agpi.device = di->pcii.device;
- pd->di[count].agpi.function = di->pcii.function;
- pd->di[count].agpi.class_sub = di->pcii.class_sub;
- pd->di[count].agpi.class_base = di->pcii.class_base;
- /* get the contents of the AGP registers from this device */
- pd->di[count].agpi.interface.agp_cap_id = get_pci(adress, 4);
- pd->di[count].agpi.interface.agp_stat = get_pci(adress + 4, 4);
- pd->di[count].agpi.interface.agp_cmd = get_pci(adress + 8, 4);
+aperture_memory *
+Aperture::CreateMemory(size_t size, size_t alignment, uint32 flags)
+{
+ aperture_memory *memory = new(std::nothrow) aperture_memory;
+ if (memory == NULL)
+ return NULL;
- /* remember the AGP interface location in this device */
- pd->di[count].agp_adress = adress;
-
- /* set OK status */
- pd->di[count].agpi.status = B_OK;
-
- /* inc pointer to device info */
- di++;
- /* inc count */
- count++;
- /* break out of these while loops */
- goto next_device;
- }
- }
-next_device:
- /* next pci_info struct, please */
- pci_index++;
+ status_t status = _Insert(memory, size, alignment, flags);
+ if (status < B_OK) {
+ // did not find a free space large for this memory object
+ delete memory;
+ return NULL;
}
- /* note actual number of AGP devices found */
- pd->count = count;
- TRACE("agp_man: found %d AGP capable device(s)\n", (uint16)count);
+ memory->flags = flags;
+#ifdef __HAIKU__
+ memory->pages = NULL;
+#else
+ memory->area = -1;
+#endif
- /* if we didn't find any devices no AGP bus exists */
- if (!count) return B_ERROR;
+ fHashTable.Insert(memory);
+ return memory;
+}
- /* check if all devices are set to a compatible mode (all AGP1/2 or all AGP3 style rates scheme) */
- if (count > 1)
- {
- for (count = 1; count < pd->count; count++)
- {
- if ((pd->di[count - 1].agpi.interface.agp_stat & AGP_rate_rev) !=
- (pd->di[count].agpi.interface.agp_stat & AGP_rate_rev))
- {
- TRACE("agp_man: compatibility problem detected, aborting\n");
- return B_ERROR;
+
+status_t
+Aperture::AllocateMemory(aperture_memory *memory, uint32 flags)
+{
+ // We don't need to allocate stolen memory - it's
+ // already there for us to use
+ addr_t reservedEnd = fInfo.base + fInfo.reserved_size;
+ size_t size = memory->size;
+ if (reservedEnd > memory->base) {
+ if (reservedEnd >= memory->base + memory->size)
+ return B_OK;
+
+ memset((void *)memory->base, 0, reservedEnd - memory->base);
+ // TODO: this requires the aperture to be mapped!
+ size -= reservedEnd - memory->base;
+ }
+
+#ifdef __HAIKU__
+ uint32 count = size / B_PAGE_SIZE;
+
+ if ((flags & B_APERTURE_NEED_PHYSICAL) != 0) {
+ memory->page = vm_page_allocate_page_run(PAGE_STATE_CLEAR, count);
+ if (memory->page == NULL)
+ return B_NO_MEMORY;
+ } else {
+ // Allocate table to hold the pages
+ memory->pages = (vm_page **)malloc(count * sizeof(vm_page *));
+ if (memory->pages == NULL)
+ return B_NO_MEMORY;
+
+ for (uint32 i = 0; i < count; i++) {
+ memory->pages[i] = vm_page_allocate_page(PAGE_STATE_CLEAR, false);
+ if (memory->pages[i] == NULL) {
+ // Free pages we already allocated
+ while (i-- > 0) {
+ vm_page_set_state(memory->pages[i], PAGE_STATE_CLEAR);
+ }
+ free(memory->pages);
+ memory->pages = NULL;
+ return B_NO_MEMORY;
}
}
}
+#else
+ void *address;
+ memory->area = create_area("GART memory", &address, B_ANY_KERNEL_ADDRESS,
+ size, B_FULL_LOCK | ((flags & B_APERTURE_NEED_PHYSICAL) != 0
+ ? B_CONTIGUOUS : 0), 0);
+ if (memory->area < B_OK)
+ return B_NO_MEMORY;
+#endif
+
+ memory->flags |= ALLOCATED_APERTURE;
+ return B_OK;
+}
+
+
+status_t
+Aperture::UnbindMemory(aperture_memory *memory)
+{
+ if ((memory->flags & BIND_APERTURE) == 0)
+ return B_BAD_VALUE;
+
+ addr_t start = memory->base - Base();
+
+ for (addr_t offset = 0; offset < memory->size; offset += B_PAGE_SIZE) {
+ status_t status = fModule->unbind_page(fPrivateAperture, start + offset);
+ if (status < B_OK)
+ return status;
+ }
+
+ memory->flags &= ~BIND_APERTURE;
+ return B_OK;
+}
+
+
+status_t
+Aperture::BindMemory(aperture_memory *memory, addr_t base, size_t size,
+ bool physical)
+{
+ addr_t start = memory->base - Base();
+
+ for (addr_t offset = 0; offset < size; offset += B_PAGE_SIZE) {
+ status_t status;
+ addr_t address;
+
+ if (!physical) {
+ physical_entry entry;
+ address = (addr_t)entry.address;
+ status = get_memory_map((void *)(base + offset), B_PAGE_SIZE,
+ &entry, 1);
+ if (status < B_OK)
+ return status;
+ } else
+ address = base + offset;
+
+ status = fModule->bind_page(fPrivateAperture, start + offset, address);
+ if (status < B_OK)
+ return status;
+ }
+
+ memory->flags |= BIND_APERTURE;
+ return B_OK;
+}
+
+
+void
+Aperture::_Free(aperture_memory *memory)
+{
+ if ((memory->flags & ALLOCATED_APERTURE) == 0)
+ return;
+
+#ifdef __HAIKU__
+ // Remove the stolen area from the allocation
+ size_t size = memory->size;
+ addr_t reservedEnd = fInfo.base + fInfo.reserved_size;
+ if (memory->base < reservedEnd)
+ size -= reservedEnd - memory->base;
+
+ // Free previously allocated pages and page table
+ uint32 count = size / B_PAGE_SIZE;
+
+ if ((memory->flags & B_APERTURE_NEED_PHYSICAL) != 0) {
+ vm_page *page = memory->page;
+ for (uint32 i = 0; i < count; i++, page++) {
+ vm_page_set_state(page, PAGE_STATE_FREE);
+ }
+ } else {
+ for (uint32 i = 0; i < count; i++) {
+ vm_page_set_state(memory->pages[i], PAGE_STATE_FREE);
+ }
+ }
+
+ free(memory->pages);
+ memory->pages = NULL;
+#else
+ delete_area(memory->area);
+ memory->area = -1;
+#endif
+
+ memory->flags &= ~ALLOCATED_APERTURE;
+}
+
+
+void
+Aperture::_Remove(aperture_memory *memory)
+{
+ aperture_memory *current = fFirstMemory, *last = NULL;
+
+ while (current != NULL) {
+ if (memory == current) {
+ if (last != NULL) {
+ last->next = current->next;
+ } else {
+ fFirstMemory = current->next;
+ }
+ break;
+ }
+
+ last = current;
+ current = current->next;
+ }
+}
+
+
+status_t
+Aperture::_Insert(aperture_memory *memory, size_t size, size_t alignment,
+ uint32 flags)
+{
+ aperture_memory *last = NULL;
+ aperture_memory *next;
+ bool foundSpot = false;
+
+ // do some sanity checking
+ if (size == 0 || size > fInfo.size)
+ return B_BAD_VALUE;
+
+ addr_t start = fInfo.base;
+ if ((flags & (B_APERTURE_NON_RESERVED | B_APERTURE_NEED_PHYSICAL)) != 0)
+ start += fInfo.reserved_size;
+
+ start = ROUNDUP(start, alignment);
+ if (start > fInfo.base - 1 + fInfo.size || start < fInfo.base)
+ return B_NO_MEMORY;
+
+ // walk up to the spot where we should start searching
+
+ next = fFirstMemory;
+ while (next) {
+ if (next->base >= start + size) {
+ // we have a winner
+ break;
+ }
+ last = next;
+ next = next->next;
+ }
+
+ // find a big enough hole
+ if (last == NULL) {
+ // see if we can build it at the beginning of the virtual map
+ if (next == NULL || (next->base >= ROUNDUP(start, alignment) + size)) {
+ memory->base = ROUNDUP(start, alignment);
+ foundSpot = true;
+ } else {
+ last = next;
+ next = next->next;
+ }
+ }
+
+ if (!foundSpot) {
+ // keep walking
+ while (next != NULL) {
+ if (next->base >= ROUNDUP(last->base + last->size, alignment) + size) {
+ // we found a spot (it'll be filled up below)
+ break;
+ }
+ last = next;
+ next = next->next;
+ }
+
+ if ((fInfo.base + (fInfo.size - 1)) >= (ROUNDUP(last->base + last->size,
+ alignment) + (size - 1))) {
+ // got a spot
+ foundSpot = true;
+ memory->base = ROUNDUP(last->base + last->size, alignment);
+ }
+
+ if (!foundSpot)
+ return B_NO_MEMORY;
+ }
+
+ memory->size = size;
+ if (last) {
+ memory->next = last->next;
+ last->next = memory;
+ } else {
+ memory->next = fFirstMemory;
+ fFirstMemory = memory;
+ }
return B_OK;
}
-static void read_settings(void)
+
+// #pragma mark - AGP module interface
+
+
+status_t
+get_nth_agp_info(uint32 index, agp_info *info)
{
- void *settings_handle;
+ TRACE("get_nth_agp_info(index %lu)\n", index);
- settings_handle = load_driver_settings ("agp.settings");
- if (settings_handle != NULL) {
- const char *item;
- char *end;
- uint32 value;
+ if (index >= sDeviceCount)
+ return B_BAD_VALUE;
- item = get_driver_parameter (settings_handle, "max_speed", "0", "0");
- value = strtoul (item, &end, 0);
- if (*end == '\0') current_settings.max_speed = value;
+ // refresh from the contents of the AGP registers from this device
+ sDeviceInfos[index].info.interface.status = get_pci_config(
+ sDeviceInfos[index].info, AGP_STATUS(sDeviceInfos[index].address), 4);
+ sDeviceInfos[index].info.interface.command = get_pci_config(
+ sDeviceInfos[index].info, AGP_COMMAND(sDeviceInfos[index].address), 4);
- current_settings.block_agp = get_driver_boolean_parameter (settings_handle, "block_agp", false, false);
- current_settings.block_sba = get_driver_boolean_parameter (settings_handle, "block_sba", false, false);
- current_settings.block_fw = get_driver_boolean_parameter (settings_handle, "block_fw", false, false);
-
- unload_driver_settings (settings_handle);
- }
+ *info = sDeviceInfos[index].info;
+ return B_OK;
}
-void uninit(void)
-{
- /* free the driver data */
- DELETE_BEN(pd->kernel);
- free(pd);
- pd = NULL;
- /* put the pci module away */
+status_t
+acquire_agp(void)
+{
+ if (atomic_or(&sAcquired, 1) == 1)
+ return B_BUSY;
+
+ return B_OK;
+}
+
+
+void
+release_agp(void)
+{
+ atomic_and(&sAcquired, 0);
+}
+
+
+uint32
+set_agp_mode(uint32 command)
+{
+ TRACE("set_agp_mode(command %lx)\n", command);
+
+ if ((command & AGP_ENABLE) == 0) {
+ set_pci_mode();
+ return 0;
+ }
+
+ // Make sure we accept all modes lower than requested one and we
+ // reset reserved bits
+ command = fix_rate_support(command);
+
+ // iterate through our device list to find the common capabilities supported
+ for (uint32 index = 0; index < sDeviceCount; index++) {
+ agp_device_info &deviceInfo = sDeviceInfos[index];
+
+ // Refresh from the contents of the AGP capability registers
+ // (note: some graphics driver may have been tweaking, like nvidia)
+ deviceInfo.info.interface.status = get_pci_config(deviceInfo.info,
+ AGP_STATUS(deviceInfo.address), 4);
+
+ check_capabilities(deviceInfo, command);
+ }
+
+ command = fix_rate_command(command);
+
+ // The order of programming differs for enabling/disabling AGP mode
+ // (see AGP specification)
+
+ // First program all bridges (master)
+
+ for (uint32 index = 0; index < sDeviceCount; index++) {
+ agp_device_info &deviceInfo = sDeviceInfos[index];
+ if (deviceInfo.info.class_base != PCI_bridge)
+ continue;
+
+ set_agp_command(deviceInfo, command);
+ }
+
+ // Wait 10mS for the bridges to recover (failsafe, see set_pci_mode()!)
+ snooze(10000);
+
+ // Then all graphics cards (target)
+
+ for (uint32 index = 0; index < sDeviceCount; index++) {
+ agp_device_info &deviceInfo = sDeviceInfos[index];
+ if (deviceInfo.info.class_base != PCI_display)
+ continue;
+
+ set_agp_command(deviceInfo, command);
+ }
+
+ return command;
+}
+
+
+// #pragma mark - GART module interface
+
+
+static aperture_id
+map_aperture(uint8 bus, uint8 device, uint8 function, size_t size,
+ addr_t *_apertureBase)
+{
+ void *iterator = open_module_list("busses/agp_gart");
+ status_t status = B_ENTRY_NOT_FOUND;
+ Aperture *aperture = NULL;
+
+ Autolock _(sLock);
+
+ while (true) {
+ char name[256];
+ size_t nameLength = sizeof(name);
+ if (read_next_module_name(iterator, name, &nameLength) != B_OK)
+ break;
+
+ agp_gart_bus_module_info *module;
+ if (get_module(name, (module_info **)&module) == B_OK) {
+ void *privateAperture;
+ status = module->create_aperture(bus, device, function, size,
+ &privateAperture);
+ if (status < B_OK) {
+ put_module(name);
+ continue;
+ }
+
+ aperture = new(std::nothrow) Aperture(module, privateAperture);
+ status = aperture->InitCheck();
+ if (status == B_OK) {
+ if (_apertureBase != NULL)
+ *_apertureBase = aperture->Base();
+
+ sApertureHashTable.Insert(aperture);
+ } else {
+ delete aperture;
+ aperture = NULL;
+ }
+ break;
+ }
+ }
+
+ close_module_list(iterator);
+ return aperture != NULL ? aperture->ID() : status;
+}
+
+
+static aperture_id
+map_custom_aperture(gart_bus_module_info *module, addr_t *_apertureBase)
+{
+ return B_ERROR;
+}
+
+
+static status_t
+unmap_aperture(aperture_id id)
+{
+ Autolock _(sLock);
+ Aperture *aperture = sApertureHashTable.Lookup(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ sApertureHashTable.Remove(aperture);
+ delete aperture;
+ return B_OK;
+}
+
+
+static status_t
+get_aperture_info(aperture_id id, aperture_info *info)
+{
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ Autolock _(aperture->Lock());
+ return aperture->GetInfo(info);
+}
+
+
+static status_t
+allocate_memory(aperture_id id, size_t size, size_t alignment, uint32 flags,
+ addr_t *_apertureBase, addr_t *_physicalBase)
+{
+ if ((flags & ~APERTURE_PUBLIC_FLAGS_MASK) != 0 || _apertureBase == NULL)
+ return B_BAD_VALUE;
+
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ Autolock _(aperture->Lock());
+
+ size = ROUNDUP(size, B_PAGE_SIZE);
+
+ aperture_memory *memory = aperture->CreateMemory(size, alignment, flags);
+ if (memory == NULL)
+ return B_NO_MEMORY;
+
+ status_t status = aperture->AllocateMemory(memory, flags);
+ if (status == B_OK)
+ status = aperture->BindMemory(memory, memory->base, memory->size, false);
+ if (status < B_OK) {
+ aperture->DeleteMemory(memory);
+ return status;
+ }
+
+ if (_physicalBase != NULL && (flags & B_APERTURE_NEED_PHYSICAL) != 0) {
+#ifdef __HAIKU__
+ *_physicalBase = memory->page->physical_page_number * B_PAGE_SIZE;
+#else
+ physical_entry entry;
+ status = get_memory_map((void *)memory->base, B_PAGE_SIZE, &entry, 1);
+ if (status < B_OK) {
+ aperture->DeleteMemory(memory);
+ return status;
+ }
+
+ *_physicalBase = (addr_t)entry.address;
+#endif
+ }
+
+ *_apertureBase = memory->base;
+ return B_OK;
+}
+
+
+static status_t
+deallocate_memory(aperture_id id, addr_t base)
+{
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ Autolock _(aperture->Lock());
+ aperture_memory *memory = aperture->GetMemory(base);
+ if (memory == NULL)
+ return B_BAD_VALUE;
+
+ aperture->DeleteMemory(memory);
+ return B_OK;
+}
+
+
+static status_t
+reserve_aperture(aperture_id id, size_t size, addr_t *_apertureBase)
+{
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ return B_ERROR;
+}
+
+
+static status_t
+unreserve_aperture(aperture_id id, addr_t apertureBase)
+{
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ return B_ERROR;
+}
+
+
+static status_t
+bind_aperture(aperture_id id, area_id area, addr_t base, size_t size,
+ size_t alignment, bool physical, addr_t reservedBase, addr_t *_apertureBase)
+{
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ if (size == 0 || size > aperture->Size()
+ || (area < 0 && (base & (B_PAGE_SIZE - 1)) != 0)
+ || (area < 0 && base == 0))
+ return B_BAD_VALUE;
+
+ size = ROUNDUP(size, B_PAGE_SIZE);
+
+ if (area >= 0) {
+ // get base and size from area
+ area_info info;
+ status_t status = get_area_info(area, &info);
+ if (status < B_OK)
+ return status;
+
+ base = (addr_t)info.address;
+ size = info.size;
+ physical = false;
+ }
+
+ Autolock _(aperture->Lock());
+ aperture_memory *memory = NULL;
+ if (reservedBase != 0) {
+ // use reserved aperture to bind the pages
+ memory = aperture->GetMemory(reservedBase);
+ if (memory == NULL)
+ return B_BAD_VALUE;
+ } else {
+ // create new memory object
+ memory = aperture->CreateMemory(size, alignment, 0);
+ if (memory == NULL)
+ return B_NO_MEMORY;
+ }
+
+ // just bind the physical pages backing the memory into the GART
+
+ status_t status = aperture->BindMemory(memory, base, size, physical);
+ if (status < B_OK) {
+ if (reservedBase < 0)
+ aperture->DeleteMemory(memory);
+
+ return status;
+ }
+
+ if (_apertureBase != NULL)
+ *_apertureBase = memory->base;
+
+ return B_OK;
+}
+
+
+static status_t
+unbind_aperture(aperture_id id, addr_t base)
+{
+ Aperture *aperture = get_aperture(id);
+ if (aperture == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ Autolock _(aperture->Lock());
+ aperture_memory *memory = aperture->GetMemory(base);
+ if (memory == NULL || (memory->flags & BIND_APERTURE) == 0)
+ return B_BAD_VALUE;
+
+ if ((memory->flags & ALLOCATED_APERTURE) != 0)
+ panic("unbind memory %lx (%p) allocated by agp_gart.", base, memory);
+
+ status_t status = aperture->UnbindMemory(memory);
+ if (status < B_OK)
+ return status;
+
+ if ((memory->flags & RESERVED_APERTURE) == 0)
+ aperture->DeleteMemory(memory);
+
+ return B_OK;
+}
+
+
+// #pragma mark -
+
+
+static status_t
+agp_init(void)
+{
+ TRACE("bus manager init\n");
+
+ if (get_module(B_PCI_MODULE_NAME, (module_info **)&sPCI) != B_OK)
+ return B_ERROR;
+
+ uint32 cookie = 0;
+ sDeviceCount = 0;
+ pci_info info;
+ while (get_next_agp_device(&cookie, info, sDeviceInfos[sDeviceCount])
+ == B_OK) {
+ sDeviceCount++;
+ }
+
+ TRACE("found %ld AGP devices\n", sDeviceCount);
+
+ // Since there can be custom aperture modules (for memory management only),
+ // we always succeed if we could get the resources we need.
+
+ new(&sApertureHashTable) ApertureHashTable();
+ return init_lock(&sLock, "agp_gart");
+}
+
+
+void
+agp_uninit(void)
+{
+ TRACE("bus manager uninit\n");
+
+ ApertureHashTable::Iterator iterator = sApertureHashTable.GetIterator();
+ while (iterator.HasNext()) {
+ Aperture *aperture = iterator.Next();
+ sApertureHashTable.Remove(aperture);
+ delete aperture;
+ }
+
put_module(B_PCI_MODULE_NAME);
}
-static bool has_AGP_interface(pci_info *pcii, uint8 *adress)
+
+static int32
+agp_std_ops(int32 op, ...)
{
- bool has_AGP = false;
-
- /* check if device implements a list of capabilities */
- /* (PCI config space 'devctrl' register) */
- if (get_pci(PCI_status, 2) & 0x0010)
- {
- uint32 item;
- uint8 item_adress;
-
- /* get pointer to PCI capabilities list */
- item_adress = get_pci(0x34, 1);
- /* read first item from list */
- item = get_pci(item_adress, 4);
- while ((item & AGP_next_ptr) && ((item & AGP_id_mask) != AGP_id))
- {
- /* read next item from list */
- item_adress = ((item & AGP_next_ptr) >> AGP_next_ptr_shift);
- item = get_pci(item_adress, 4);
- }
- if ((item & AGP_id_mask) == AGP_id)
- {
- /* we found the AGP interface! */
- has_AGP = true;
- /* return the adress if the interface */
- *adress = item_adress;
- }
+ switch (op) {
+ case B_MODULE_INIT:
+ return agp_init();
+ case B_MODULE_UNINIT:
+ agp_uninit();
+ return B_OK;
}
- return has_AGP;
+
+ return B_BAD_VALUE;
}
-long get_nth_agp_info (long index, agp_info *info)
-{
- pci_info *pcii;
- TRACE("agp_man: get_nth_agp_info called with index %d\n", (uint16)index);
-
- /* check if we have a device here */
- if (index >= pd->count) return B_ERROR;
-
- /* refresh from the contents of the AGP registers from this device */
- /* (note: also get agp_stat as some graphicsdriver may have been tweaking, like nvidia) */
- pcii = &(pd->di[index].pcii);
- pd->di[index].agpi.interface.agp_stat = get_pci(pd->di[index].agp_adress + 4, 4);
- pd->di[index].agpi.interface.agp_cmd = get_pci(pd->di[index].agp_adress + 8, 4);
-
- /* return requested info */
- *info = pd->di[index].agpi;
-
- return B_NO_ERROR;
-}
-
-void enable_agp (uint32 *command)
-{
- long count;
- pci_info *pcii;
-
- TRACE("agp_man: enable_agp called\n");
-
- /* validate the given command: */
- /* if we should set PCI mode, reset all options */
- if (!(*command & AGP_enable)) *command = 0x00000000;
- /* make sure we accept all modes lower than requested one and we reset reserved bits */
- if (!(*command & AGP_rate_rev))
+static struct agp_gart_module_info sAGPModuleInfo = {
{
- /* AGP 2.0 scheme applies */
- if (*command & AGP_2_4x) *command |= AGP_2_2x;
- if (*command & AGP_2_2x) *command |= AGP_2_1x;
- }
- else
- {
- /* AGP 3.0 scheme applies */
- if (*command & AGP_3_8x) *command |= AGP_3_4x;
- *command &= ~0x00000004;
- /* SBA is required for AGP3 */
- *command |= AGP_SBA;
- }
- /* reset all other reserved and currently unused bits */
- *command &= ~0x00fffce0;
- /* block features if requested by user in agp.settings file */
- check_settings(command);
-
- /* iterate through our device list to find the common capabilities supported */
- for (count = 0; count < pd->count; count++)
- {
- pcii = &(pd->di[count].pcii);
-
- /* refresh from the contents of the AGP capability registers */
- /* (note: some graphicsdriver may have been tweaking, like nvidia) */
- pd->di[count].agpi.interface.agp_stat = get_pci(pd->di[count].agp_adress + 4, 4);
-
- check_capabilities(pd->di[count].agpi.interface.agp_stat, command);
- }
-
- /* select only the highest remaining possible mode-bits */
- if (!(*command & AGP_rate_rev))
- {
- /* AGP 2.0 scheme applies */
- if (*command & AGP_2_4x) *command &= ~(AGP_2_2x | AGP_2_1x);
- if (*command & AGP_2_2x) *command &= ~AGP_2_1x;
- }
- else
- {
- /* AGP 3.0 scheme applies */
- if (*command & AGP_3_8x) *command &= ~AGP_3_4x;
- }
-
- /* note:
- * we are not setting the enable AGP bits ourselves, as the user should have specified that
- * in 'command' if we should be enabling AGP mode here (otherwise we set PCI mode). */
- /* note also:
- * the AGP standard defines that this bit may be written to the AGPCMD
- * registers simultanously with the other bits if a single 32bit write
- * to each register is used. */
-
- /* the order of programming differs for enabling/disabling AGP mode (see AGP specification) */
- if (*command & AGP_enable)
- {
- /* first program all bridges */
- for (count = 0; count < pd->count; count++)
{
- if (pd->di[count].agpi.class_base == PCI_bridge)
- {
- pcii = &(pd->di[count].pcii);
- /* program bridge, making sure not-implemented bits are written as zeros */
- set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~(AGP_rate_rev | AGP_RQ)));
- /* update our agp_cmd info with read back setting from register just programmed */
- pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
- }
- }
+ B_AGP_GART_MODULE_NAME,
+ B_KEEP_LOADED, // Keep loaded, even if no driver requires it
+ agp_std_ops
+ },
+ NULL // the rescan function
+ },
+ get_nth_agp_info,
+ acquire_agp,
+ release_agp,
+ set_agp_mode,
- /* wait 10mS for the bridges to recover (failsafe!) */
- /* note:
- * some SiS bridge chipsets apparantly require 5mS to recover or the
- * master (graphics card) cannot be initialized correctly! */
- snooze(10000);
+ map_aperture,
+ map_custom_aperture,
+ unmap_aperture,
+ get_aperture_info,
+ allocate_memory,
+ deallocate_memory,
+ reserve_aperture,
+ unreserve_aperture,
+ bind_aperture,
+ unbind_aperture,
+};
- /* _now_ program all graphicscards */
- for (count = 0; count < pd->count; count++)
- {
- if (pd->di[count].agpi.class_base == PCI_display)
- {
- pci_info *pcii = &(pd->di[count].pcii);
- /* program graphicscard, making sure not-implemented bits are written as zeros */
- set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~AGP_rate_rev));
- /* update our agp_cmd info with read back setting from register just programmed */
- pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
- }
- }
- }
- else
- {
- /* first program all graphicscards */
- for (count = 0; count < pd->count; count++)
- {
- if (pd->di[count].agpi.class_base == PCI_display)
- {
- pci_info *pcii = &(pd->di[count].pcii);
- /* program graphicscard, making sure not-implemented bits are written as zeros */
- set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~AGP_rate_rev));
- /* update our agp_cmd info with read back setting from register just programmed */
- pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
- }
- }
-
- /* _now_ program all bridges */
- for (count = 0; count < pd->count; count++)
- {
- if (pd->di[count].agpi.class_base == PCI_bridge)
- {
- pcii = &(pd->di[count].pcii);
- /* program bridge, making sure not-implemented bits are written as zeros */
- set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~(AGP_rate_rev | AGP_RQ)));
- /* update our agp_cmd info with read back setting from register just programmed */
- pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
- }
- }
-
- /* wait 10mS for the bridges to recover (failsafe!) */
- /* note:
- * some SiS bridge chipsets apparantly require 5mS to recover or the
- * master (graphics card) cannot be initialized correctly! */
- snooze(10000);
- }
-}
-
-static void check_settings(uint32 *command)
-{
- if (current_settings.block_agp)
- {
- TRACE("agp_man: blocking all agp modes (agp.settings)\n");
- *command = 0x00000000;
- return;
- }
- if (current_settings.max_speed != 0)
- {
- if (!(*command & AGP_rate_rev))
- {
- /* AGP 2.0 scheme applies */
- switch (current_settings.max_speed)
- {
- case 8:
- TRACE("agp_man: max AGP 8x speed allowed, using max 4x (agp.settings)\n");
- break;
- case 4:
- TRACE("agp_man: max AGP 4x speed allowed (agp.settings)\n");
- break;
- case 2:
- TRACE("agp_man: max AGP 2x speed allowed (agp.settings)\n");
- *command &= ~AGP_2_4x;
- break;
- case 1:
- TRACE("agp_man: max AGP 1x speed allowed (agp.settings)\n");
- *command &= ~(AGP_2_4x | AGP_2_2x);
- break;
- default:
- TRACE("agp_man: illegal max AGP speed requested, ignoring (agp.settings)\n");
- break;
- }
- }
- else
- {
- /* AGP 3.0 scheme applies */
- switch (current_settings.max_speed)
- {
- case 8:
- TRACE("agp_man: max AGP 8x speed allowed (agp.settings)\n");
- break;
- case 4:
- TRACE("agp_man: max AGP 4x speed allowed (agp.settings)\n");
- *command &= ~AGP_3_8x;
- break;
- case 2:
- TRACE("agp_man: max AGP 2x speed allowed, forcing PCI mode (agp.settings)\n");
- *command = 0x00000000;
- return;
- break;
- case 1:
- TRACE("agp_man: max AGP 1x speed allowed, forcing PCI mode (agp.settings)\n");
- *command = 0x00000000;
- return;
- break;
- default:
- TRACE("agp_man: illegal max AGP speed requested, ignoring (agp.settings)\n");
- break;
- }
- }
- }
- if (current_settings.block_sba)
- {
- if (!(*command & AGP_rate_rev))
- {
- TRACE("agp_man: blocking SBA (agp.settings)\n");
- *command &= ~AGP_SBA;
- }
- else
- {
- TRACE("agp_man: SBA is required for AGP3, not blocking (agp.settings)\n");
- }
- }
- if (current_settings.block_fw)
- {
- TRACE("agp_man: blocking FW (agp.settings)\n");
- *command &= ~AGP_FW;
- }
-}
-
-static void check_capabilities(uint32 agp_stat, uint32 *command)
-{
- uint8 rq_depth_card, rq_depth_cmd;
-
- /* block non-supported AGP modes */
- if (!(agp_stat & AGP_rate_rev))
- {
- /* AGP 2.0 scheme applies */
- if (!(agp_stat & AGP_2_4x)) *command &= ~AGP_2_4x;
- if (!(agp_stat & AGP_2_2x)) *command &= ~AGP_2_2x;
- if (!(agp_stat & AGP_2_1x)) *command &= ~AGP_2_1x;
- }
- else
- {
- /* AGP 3.0 scheme applies */
- if (!(agp_stat & AGP_3_8x)) *command &= ~AGP_3_8x;
- if (!(agp_stat & AGP_3_4x)) *command &= ~AGP_3_4x;
- }
- /* if no AGP mode is supported at all, nothing remains:
- * devices exist that have the AGP style
- * connector with AGP style registers, but not the features!
- * (confirmed Matrox Millenium II AGP for instance) */
- if (!(agp_stat & AGP_rates)) *command = 0x00000000;
-
- /* block sideband adressing if not supported */
- if (!(agp_stat & AGP_SBA)) *command &= ~AGP_SBA;
-
- /* block fast writes if not supported */
- if (!(agp_stat & AGP_FW)) *command &= ~AGP_FW;
-
- /* adjust maximum request depth to least depth supported */
- /* note:
- * this is writable only in the graphics card */
- rq_depth_card = ((agp_stat & AGP_RQ) >> AGP_RQ_shift);
- rq_depth_cmd = ((*command & AGP_RQ) >> AGP_RQ_shift);
- if (rq_depth_card < rq_depth_cmd)
- {
- *command &= ~AGP_RQ;
- *command |= (rq_depth_card << AGP_RQ_shift);
- }
-}
+module_info *modules[] = {
+ (module_info *)&sAGPModuleInfo,
+ NULL
+};
diff --git a/src/add-ons/kernel/bus_managers/agp/agp.h b/src/add-ons/kernel/bus_managers/agp/agp.h
deleted file mode 100644
index 35c4987451..0000000000
--- a/src/add-ons/kernel/bus_managers/agp/agp.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#if !defined(AGP_PROTO_H)
-#define AGP_PROTO_H
-
-
-#include
-#include
-#include "AGP.h"
-
-#define AGP_DEBUG
-#ifdef AGP_DEBUG
-#define TRACE dprintf
-#else
-#define TRACE silent
-#endif
-void silent(const char *, ... );
-
-status_t init(void);
-void uninit(void);
-void enable_agp (uint32 *command);
-long get_nth_agp_info (long index, agp_info *info);
-
-
-#endif
diff --git a/src/add-ons/kernel/bus_managers/agp/agp.settings b/src/add-ons/kernel/bus_managers/agp/agp.settings
deleted file mode 100644
index 23e4cedebe..0000000000
--- a/src/add-ons/kernel/bus_managers/agp/agp.settings
+++ /dev/null
@@ -1,12 +0,0 @@
-# Settings file for the agp busmanager
-#
-# This file should be moved to the directory
-# ~/config/settings/kernel/drivers/
-#
-
-#modifying the settings below will restrict the busmanager in autoselecting the best mode useable:
-
-#max_speed 2 # max AGP speed that may be used (valid are 1,2,4 or 8)
-block_agp false # if true blocks use of AGP entirely: so fallback to PCI mode
-block_sba false # if true blocks use of 'sideband adressing' if possible
-block_fw true # if true blocks use of 'fastwrites'
diff --git a/src/add-ons/kernel/bus_managers/agp/module.cpp b/src/add-ons/kernel/bus_managers/agp/module.cpp
deleted file mode 100644
index 097e021139..0000000000
--- a/src/add-ons/kernel/bus_managers/agp/module.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2003-2004, Niels S. Reedijk,
- * Rudolf Cornelissen
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "agp.h"
-
-//void function for debug messages if logging disabled
-void silent(const char *, ... ) {}
-
-
-static int32
-bus_std_ops(int32 op, ...)
-{
- switch(op) {
- case B_MODULE_INIT:
- TRACE("agp_man: bus module V0.02: init\n");
- if (init() != B_OK)
- return ENODEV;
- break;
- case B_MODULE_UNINIT:
- TRACE("agp_man: bus module V0.02: uninit\n");
- uninit();
- break;
- default:
- return EINVAL;
- }
- return B_OK;
-}
-
-
-static struct agp_module_info sAGPModuleInfo = {
- {
- {
- B_AGP_MODULE_NAME,
- B_KEEP_LOADED, // Keep loaded, even if no driver requires it
- bus_std_ops
- },
- NULL // the rescan function
- },
- get_nth_agp_info,
- enable_agp
-};
-
-module_info *modules[] = {
- (module_info *)&sAGPModuleInfo,
- NULL
-};
diff --git a/src/add-ons/kernel/busses/Jamfile b/src/add-ons/kernel/busses/Jamfile
index 84f7392775..1fdf00db54 100644
--- a/src/add-ons/kernel/busses/Jamfile
+++ b/src/add-ons/kernel/busses/Jamfile
@@ -1,5 +1,6 @@
SubDir HAIKU_TOP src add-ons kernel busses ;
+SubInclude HAIKU_TOP src add-ons kernel busses agp_gart ;
SubInclude HAIKU_TOP src add-ons kernel busses ide ;
SubInclude HAIKU_TOP src add-ons kernel busses scsi ;
SubInclude HAIKU_TOP src add-ons kernel busses usb ;
diff --git a/src/add-ons/kernel/busses/agp_gart/Jamfile b/src/add-ons/kernel/busses/agp_gart/Jamfile
new file mode 100644
index 0000000000..34af1f0949
--- /dev/null
+++ b/src/add-ons/kernel/busses/agp_gart/Jamfile
@@ -0,0 +1,20 @@
+SubDir HAIKU_TOP src add-ons kernel busses agp_gart ;
+
+SetSubDirSupportedPlatformsBeOSCompatible ;
+SubDirC++Flags -fno-rtti ;
+
+UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ;
+UsePrivateHeaders [ FDirName graphics intel_extreme ] ;
+UsePrivateHeaders [ FDirName graphics common ] ;
+UsePrivateHeaders drivers graphics kernel ;
+
+KernelAddon intel :
+ intel_gart.cpp
+
+ kernel_cpp.cpp
+ ;
+
+SEARCH on [ FGristFiles
+ kernel_cpp.cpp
+ ] = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
+
diff --git a/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp b/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp
new file mode 100644
index 0000000000..902235322e
--- /dev/null
+++ b/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+
+#define TRACE_INTEL
+#ifdef TRACE_INTEL
+# define TRACE(x...) dprintf("\33[33magp-intel:\33[0m " x)
+#else
+# define TRACE(x...) ;
+#endif
+
+#ifndef __HAIKU__
+# define B_KERNEL_READ_AREA 0
+# define B_KERNEL_WRITE_AREA 0
+#endif
+
+/* read and write to PCI config space */
+#define get_pci_config(info, offset, size) \
+ (sPCI->read_pci_config((info).bus, (info).device, (info).function, \
+ (offset), (size)))
+#define set_pci_config(info, offset, size, value) \
+ (sPCI->write_pci_config((info).bus, (info).device, (info).function, \
+ (offset), (size), (value)))
+#define write32(address, data) \
+ (*((volatile uint32 *)(address)) = (data))
+#define read32(address) \
+ (*((volatile uint32 *)(address)))
+
+
+const struct supported_device {
+ uint32 bridge_id;
+ uint32 display_id;
+ uint32 type;
+ const char *name;
+} kSupportedDevices[] = {
+ {0x29b0, 0x29b2, INTEL_TYPE_G33, "G33"},
+ {0x29c0, 0x29c2, INTEL_TYPE_G33, "Q35"},
+ {0x29d0, 0x29d2, INTEL_TYPE_G33, "Q33"},
+};
+
+struct intel_info {
+ pci_info bridge;
+ pci_info display;
+ uint32 type;
+
+ uint32 *gtt_base;
+ addr_t gtt_physical_base;
+ area_id gtt_area;
+ size_t gtt_entries;
+ size_t gtt_stolen_entries;
+
+ uint32 *registers;
+ area_id registers_area;
+
+ addr_t aperture_base;
+ addr_t aperture_physical_base;
+ area_id aperture_area;
+ size_t aperture_size;
+ size_t aperture_stolen_size;
+
+ addr_t scratch_page;
+ area_id scratch_area;
+};
+
+static intel_info sInfo;
+static pci_module_info *sPCI;
+
+
+static bool
+has_display_device(pci_info &info, uint32 deviceID)
+{
+ for (uint32 index = 0; sPCI->get_nth_pci_info(index, &info) == B_OK;
+ index++) {
+ if (info.vendor_id != VENDOR_ID_INTEL
+ || info.device_id != deviceID
+ || info.class_base != PCI_display)
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+static void
+determine_memory_sizes(intel_info &info, size_t >tSize, size_t &stolenSize)
+{
+ // read stolen memory from the PCI configuration of the PCI bridge
+ uint16 memoryConfig = get_pci_config(info.bridge,
+ INTEL_GRAPHICS_MEMORY_CONTROL, 2);
+ size_t memorySize = 1 << 20; // 1 MB
+ gttSize = 0;
+ stolenSize = 0;
+
+ if (info.type == INTEL_TYPE_965) {
+ switch (memoryConfig & i965_GTT_MASK) {
+ case i965_GTT_128K:
+ gttSize = 128 << 10;
+ break;
+ case i965_GTT_256K:
+ gttSize = 256 << 10;
+ break;
+ case i965_GTT_512K:
+ gttSize = 512 << 10;
+ break;
+ }
+ } else if (info.type == INTEL_TYPE_G33) {
+ switch (memoryConfig & G33_GTT_MASK) {
+ case G33_GTT_1M:
+ gttSize = 1 << 20;
+ break;
+ case G33_GTT_2M:
+ gttSize = 2 << 20;
+ break;
+ }
+ } else {
+#if 0
+ // older models have the GTT as large as their frame buffer mapping
+ // TODO: check if the i9xx version works with the i8xx chips as well
+ size_t frameBufferSize = 0;
+ if ((info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_8xx) {
+ if ((info.device_type & INTEL_TYPE_83x) != 0
+ && (memoryConfig & MEMORY_MASK) == i830_FRAME_BUFFER_64M)
+ frameBufferSize = 64 << 20;
+ else
+ frameBufferSize = 128 << 20;
+ } else if ((info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx)
+ frameBufferSize = info.pci->u.h0.base_register_sizes[2];
+
+ gttSize = frameBufferSize / 1024;
+#endif
+ }
+
+#if 0
+ // TODO: test with different models!
+
+ if (info.device_type == (INTEL_TYPE_8xx | INTEL_TYPE_83x)) {
+ switch (memoryConfig & STOLEN_MEMORY_MASK) {
+ case i830_LOCAL_MEMORY_ONLY:
+ // TODO: determine its size!
+ break;
+ case i830_STOLEN_512K:
+ memorySize >>= 1;
+ break;
+ case i830_STOLEN_8M:
+ memorySize *= 8;
+ break;
+ }
+ } else if (info.device_type == (INTEL_TYPE_8xx | INTEL_TYPE_85x)
+ || (info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx)
+#endif
+ {
+ switch (memoryConfig & STOLEN_MEMORY_MASK) {
+ case i855_STOLEN_MEMORY_4M:
+ memorySize *= 4;
+ break;
+ case i855_STOLEN_MEMORY_8M:
+ memorySize *= 8;
+ break;
+ case i855_STOLEN_MEMORY_16M:
+ memorySize *= 16;
+ break;
+ case i855_STOLEN_MEMORY_32M:
+ memorySize *= 32;
+ break;
+ case i855_STOLEN_MEMORY_48M:
+ memorySize *= 48;
+ break;
+ case i855_STOLEN_MEMORY_64M:
+ memorySize *= 64;
+ break;
+ case i855_STOLEN_MEMORY_128M:
+ memorySize *= 128;
+ break;
+ case i855_STOLEN_MEMORY_256M:
+ memorySize *= 256;
+ break;
+ }
+ }
+
+ stolenSize = memorySize - gttSize - 4096;
+}
+
+
+static void
+set_gtt_entry(intel_info &info, uint32 offset, addr_t physicalAddress)
+{
+ write32(info.gtt_base + (offset >> GTT_PAGE_SHIFT),
+ (uint32)physicalAddress | GTT_ENTRY_VALID);
+}
+
+
+static void
+intel_unmap(intel_info &info)
+{
+ delete_area(info.registers_area);
+ delete_area(info.gtt_area);
+ delete_area(info.scratch_area);
+ delete_area(info.aperture_area);
+ info.aperture_size = 0;
+}
+
+
+static status_t
+intel_map(intel_info &info)
+{
+ info.gtt_physical_base = get_pci_config(info.display, i915_GTT_BASE, 4);
+
+ size_t gttSize, stolenSize;
+ determine_memory_sizes(info, gttSize, stolenSize);
+
+ info.gtt_entries = gttSize / 4096;
+ info.gtt_stolen_entries = stolenSize / 4096;
+dprintf("GTT base %lx, size %lu, entries %lu, stolen %lu\n", info.gtt_physical_base,
+ gttSize, info.gtt_entries, stolenSize);
+
+ int fbIndex = 0;
+ int mmioIndex = 1;
+ if ((info.type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx) {
+ // for some reason Intel saw the need to change the order of the mappings
+ // with the introduction of the i9xx family
+ mmioIndex = 0;
+ fbIndex = 2;
+ }
+
+ AreaKeeper gttMapper;
+ info.gtt_area = gttMapper.Map("intel GMCH gtt",
+ (void *)info.gtt_physical_base, gttSize, B_ANY_KERNEL_ADDRESS,
+ B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&info.gtt_base);
+ if (gttMapper.InitCheck() < B_OK) {
+ dprintf("agp_intel: could not map GTT!\n");
+ return info.gtt_area;
+ }
+
+ AreaKeeper mmioMapper;
+ info.registers_area = mmioMapper.Map("intel GMCH mmio",
+ (void *)info.display.u.h0.base_registers[mmioIndex],
+ info.display.u.h0.base_register_sizes[mmioIndex], B_ANY_KERNEL_ADDRESS,
+ B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&info.registers);
+ if (mmioMapper.InitCheck() < B_OK) {
+ dprintf("agp_intel: could not map memory I/O!\n");
+ return info.registers_area;
+ }
+
+ void *scratchAddress;
+ AreaKeeper scratchCreator;
+ info.scratch_area = scratchCreator.Create("intel GMCH scratch",
+ &scratchAddress, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_FULL_LOCK,
+ B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
+ if (scratchCreator.InitCheck() < B_OK) {
+ dprintf("agp_intel: could not create scratch page!\n");
+ return info.scratch_area;
+ }
+
+ physical_entry entry;
+ if (get_memory_map(scratchAddress, B_PAGE_SIZE, &entry, 1) != B_OK)
+ return B_ERROR;
+
+ info.aperture_physical_base = info.display.u.h0.base_registers[fbIndex];
+ info.aperture_stolen_size = stolenSize;
+ if (info.aperture_size == 0)
+ info.aperture_size = info.display.u.h0.base_register_sizes[0];
+
+ AreaKeeper apertureMapper;
+ info.aperture_area = apertureMapper.Map("intel graphics aperture",
+ (void *)info.aperture_physical_base, info.aperture_size,
+ B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
+ B_READ_AREA | B_WRITE_AREA, (void **)&info.aperture_base);
+ if (apertureMapper.InitCheck() < B_OK) {
+ // try again without write combining
+ dprintf(DEVICE_NAME ": enabling write combined mode failed.\n");
+
+ info.aperture_area = apertureMapper.Map("intel graphics aperture",
+ (void *)info.aperture_physical_base, info.aperture_size,
+ B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA,
+ (void **)&info.aperture_base);
+ }
+ if (apertureMapper.InitCheck() < B_OK) {
+ dprintf(DEVICE_NAME ": could not map graphics aperture!\n");
+ return info.aperture_area;
+ }
+
+ info.scratch_page = (addr_t)entry.address;
+
+ gttMapper.Detach();
+ mmioMapper.Detach();
+ scratchCreator.Detach();
+ apertureMapper.Detach();
+
+ return B_OK;
+}
+
+
+// #pragma mark - module interface
+
+
+status_t
+intel_create_aperture(uint8 bus, uint8 device, uint8 function, size_t size,
+ void **_aperture)
+{
+ // TODO: we currently only support a single AGP bridge!
+ if ((bus != sInfo.bridge.bus || device != sInfo.bridge.device
+ || function != sInfo.bridge.function)
+ && (bus != sInfo.display.bus || device != sInfo.display.device
+ || function != sInfo.display.function))
+ return B_BAD_VALUE;
+
+ sInfo.aperture_size = size;
+
+ if (intel_map(sInfo) < B_OK)
+ return B_ERROR;
+
+ uint16 gmchControl = get_pci_config(sInfo.bridge,
+ INTEL_GRAPHICS_MEMORY_CONTROL, 2) | MEMORY_CONTROL_ENABLED;
+ set_pci_config(sInfo.bridge, INTEL_GRAPHICS_MEMORY_CONTROL, 2, gmchControl);
+
+ write32(sInfo.registers + INTEL_PAGE_TABLE_CONTROL,
+ sInfo.gtt_physical_base | PAGE_TABLE_ENABLED);
+ read32(sInfo.registers + INTEL_PAGE_TABLE_CONTROL);
+
+ if (sInfo.scratch_page != 0) {
+ for (size_t i = sInfo.gtt_stolen_entries; i < sInfo.gtt_entries; i++) {
+ set_gtt_entry(sInfo, i << GTT_PAGE_SHIFT, sInfo.scratch_page);
+ }
+ read32(sInfo.gtt_base + sInfo.gtt_entries - 1);
+ }
+
+ asm("wbinvd;");
+
+ *_aperture = NULL;
+ return B_OK;
+}
+
+
+void
+intel_delete_aperture(void *aperture)
+{
+ intel_unmap(sInfo);
+}
+
+
+static status_t
+intel_get_aperture_info(void *aperture, aperture_info *info)
+{
+ if (info == NULL)
+ return B_BAD_VALUE;
+
+ info->base = sInfo.aperture_base;
+ info->physical_base = sInfo.aperture_physical_base;
+ info->size = sInfo.aperture_size;
+ info->reserved_size = sInfo.aperture_stolen_size;
+
+ return B_OK;
+}
+
+
+status_t
+intel_set_aperture_size(void *aperture, size_t size)
+{
+ return B_ERROR;
+}
+
+
+static status_t
+intel_bind_page(void *aperture, uint32 offset, addr_t physicalAddress)
+{
+ set_gtt_entry(sInfo, offset << GTT_PAGE_SHIFT, physicalAddress);
+ return B_OK;
+}
+
+
+static status_t
+intel_unbind_page(void *aperture, uint32 offset)
+{
+ if (sInfo.scratch_page != 0)
+ set_gtt_entry(sInfo, offset << GTT_PAGE_SHIFT, sInfo.scratch_page);
+
+ return B_OK;
+}
+
+
+void
+intel_flush_tlbs(void *aperture)
+{
+ read32(sInfo.gtt_base + sInfo.gtt_entries - 1);
+ asm("wbinvd;");
+}
+
+
+// #pragma mark -
+
+
+static status_t
+intel_init()
+{
+ TRACE("bus manager init\n");
+
+ if (get_module(B_PCI_MODULE_NAME, (module_info **)&sPCI) != B_OK)
+ return B_ERROR;
+
+ bool found = false;
+
+ for (uint32 index = 0; sPCI->get_nth_pci_info(index, &sInfo.bridge) == B_OK;
+ index++) {
+ if (sInfo.bridge.vendor_id != VENDOR_ID_INTEL
+ || sInfo.bridge.class_base != PCI_bridge)
+ continue;
+
+ // check device
+ for (uint32 i = 0; i < sizeof(kSupportedDevices)
+ / sizeof(kSupportedDevices[0]); i++) {
+ if (sInfo.bridge.device_id == kSupportedDevices[i].bridge_id) {
+ sInfo.type = kSupportedDevices[i].type;
+ found = has_display_device(sInfo.display,
+ kSupportedDevices[i].display_id);
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (!found)
+ return ENODEV;
+
+ TRACE("found intel bridge\n");
+ return B_OK;
+}
+
+
+static void
+intel_uninit()
+{
+}
+
+
+static int32
+intel_std_ops(int32 op, ...)
+{
+ switch (op) {
+ case B_MODULE_INIT:
+ return intel_init();
+ case B_MODULE_UNINIT:
+ intel_uninit();
+ return B_OK;
+ }
+
+ return B_BAD_VALUE;
+}
+
+
+static struct agp_gart_bus_module_info sIntelModuleInfo = {
+ {
+ "busses/agp_gart/intel/v0",
+ 0,
+ intel_std_ops
+ },
+
+ intel_create_aperture,
+ intel_delete_aperture,
+
+ intel_get_aperture_info,
+ intel_set_aperture_size,
+ intel_bind_page,
+ intel_unbind_page,
+ intel_flush_tlbs
+};
+
+module_info *modules[] = {
+ (module_info *)&sIntelModuleInfo,
+ NULL
+};
diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp
index d7540671de..c57b6eb84e 100644
--- a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp
+++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp
@@ -59,7 +59,7 @@ int32 api_version = B_CUR_DRIVER_API_VERSION;
char *gDeviceNames[MAX_CARDS + 1];
intel_info *gDeviceInfo[MAX_CARDS];
pci_module_info *gPCI;
-agp_module_info *gGART;
+agp_gart_module_info *gGART;
lock gLock;
@@ -138,7 +138,7 @@ init_driver(void)
return status;
}
- get_module(B_AGP_MODULE_NAME, (module_info **)&gGART);
+ get_module(B_AGP_GART_MODULE_NAME, (module_info **)&gGART);
// find devices
@@ -193,7 +193,7 @@ init_driver(void)
if (found == 0) {
uninit_lock(&gLock);
if (gGART != NULL)
- put_module(B_AGP_MODULE_NAME);
+ put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME);
return ENODEV;
}
@@ -217,7 +217,7 @@ uninit_driver(void)
}
if (gGART != NULL)
- put_module(B_AGP_MODULE_NAME);
+ put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME);
}
diff --git a/src/add-ons/kernel/drivers/graphics/nvidia/driver.c b/src/add-ons/kernel/drivers/graphics/nvidia/driver.c
index 82b30b091b..ef0b889501 100644
--- a/src/add-ons/kernel/drivers/graphics/nvidia/driver.c
+++ b/src/add-ons/kernel/drivers/graphics/nvidia/driver.c
@@ -76,7 +76,7 @@ static int32 nv_interrupt(void *data);
static DeviceData *pd;
static isa_module_info *isa_bus = NULL;
static pci_module_info *pci_bus = NULL;
-static agp_module_info *agp_bus = NULL;
+static agp_gart_module_info *agp_bus = NULL;
static device_hooks graphics_device_hooks = {
open_hook,
close_hook,
@@ -1257,7 +1257,7 @@ control_hook(void* dev, uint32 msg, void *buf, size_t len)
if (nca->magic == NV_PRIVATE_DATA_MAGIC) {
if (agp_bus) {
nca->agp_bus = true;
- (*agp_bus->enable_agp)(&(nca->cmd));
+ nca->cmd = agp_bus->set_agp_mode(nca->cmd);
} else {
nca->agp_bus = false;
nca->cmd = 0;
@@ -1476,7 +1476,7 @@ init_driver(void)
}
/* get a handle for the agp bus if it exists */
- get_module(B_AGP_MODULE_NAME, (module_info **)&agp_bus);
+ get_module(B_AGP_GART_MODULE_NAME, (module_info **)&agp_bus);
/* driver private data */
pd = (DeviceData *)calloc(1, sizeof(DeviceData));
@@ -1528,6 +1528,6 @@ uninit_driver(void)
/* put the agp module away if it's there */
if (agp_bus)
- put_module(B_AGP_MODULE_NAME);
+ put_module(B_AGP_GART_MODULE_NAME);
}
diff --git a/src/add-ons/kernel/drivers/graphics/radeon/agp.c b/src/add-ons/kernel/drivers/graphics/radeon/agp.c
index 103e40e1dd..64f9ac7fb5 100644
--- a/src/add-ons/kernel/drivers/graphics/radeon/agp.c
+++ b/src/add-ons/kernel/drivers/graphics/radeon/agp.c
@@ -1,14 +1,11 @@
/*
Copyright (c) 2002, Thomas Kurschel
-
Part of Radeon kernel driver
-
+
AGP fix. Some motherboard BIOSes enable FastWrite even
though the graphics card doesn't support it. Here, we'll
fix that (hopefully it is generic enough).
-
- updated to use AGP_BUS mananager
*/
@@ -17,8 +14,10 @@
static void agp_list_info(agp_info ai);
static void agp_list_active(uint32 cmd);
-// fix invalid AGP settings
-void Radeon_Set_AGP( device_info *di, bool enable_agp )
+
+//! fix invalid AGP settings
+void
+Radeon_Set_AGP(device_info *di, bool enable_agp)
{
uint8 agp_index = 0;
agp_info nth_agp_info;
@@ -26,34 +25,29 @@ void Radeon_Set_AGP( device_info *di, bool enable_agp )
uint32 agp_cmd;
/* abort if no agp busmanager found */
- if (!agp_bus)
- {
+ if (!sAGP) {
SHOW_INFO0(1, "Busmanager not installed.\nWarning Card May hang if AGP Fastwrites are Enabled." );
return;
}
/* contact driver and get a pointer to the registers and shared data */
/* get nth AGP device info */
- while((*agp_bus->get_nth_agp_info)(agp_index, &nth_agp_info) == B_NO_ERROR) {
-
+ while (sAGP->get_nth_agp_info(agp_index, &nth_agp_info) == B_OK) {
/* see if we are this one */
- if ((nth_agp_info.device_id == di->pcii.device_id) &&
- (nth_agp_info.vendor_id == di->pcii.vendor_id) &&
- (nth_agp_info.bus == di->pcii.bus) &&
- (nth_agp_info.device == di->pcii.device) &&
- (nth_agp_info.function == di->pcii.function))
- {
+ if (nth_agp_info.device_id == di->pcii.device_id
+ && nth_agp_info.vendor_id == di->pcii.vendor_id
+ && nth_agp_info.bus == di->pcii.bus
+ && nth_agp_info.device == di->pcii.device
+ && nth_agp_info.function == di->pcii.function) {
SHOW_INFO0(1, "Found AGP capable device" );
found = true;
/* remember our info */
di->agpi = nth_agp_info;
-
+
/* log capabilities */
agp_list_info(nth_agp_info);
-
break;
-
}
agp_index++;
@@ -69,37 +63,33 @@ void Radeon_Set_AGP( device_info *di, bool enable_agp )
}
if (di->settings.force_pci | !enable_agp) {
-
SHOW_INFO0(1, "Disabling AGP mode...");
/* we want zero agp features enabled */
- agp_cmd = 0;
-
- /* write the stuff */
- (*agp_bus->enable_agp)(&agp_cmd);
+ agp_cmd = sAGP->set_agp_mode(0);
} else {
/* activate AGP mode */
SHOW_INFO0(1, "Activating AGP mode...");
agp_cmd = 0xfffffff7;
/* set agp 3 speed bit is agp is v3 */
- if (nth_agp_info.interface.agp_stat & AGP_rate_rev) agp_cmd |= AGP_rate_rev;
+ if ((nth_agp_info.interface.status & AGP_3_MODE) != 0)
+ agp_cmd |= AGP_3_MODE;
/* we want to perma disable fastwrites as they're evil, evil i say */
- agp_cmd &= ~AGP_FW;
+ agp_cmd &= ~AGP_FAST_WRITE;
- /* write the stuff */
- (*agp_bus->enable_agp)(&agp_cmd);
+ agp_cmd = sAGP->set_agp_mode(agp_cmd);
}
/* list mode now activated,
* make sure we have the correct speed scheme for logging */
- agp_list_active(nth_agp_info.interface.agp_cmd |
- (nth_agp_info.interface.agp_stat & AGP_rate_rev));
-
+ agp_list_active(agp_cmd | (nth_agp_info.interface.status & AGP_3_MODE));
}
-static void agp_list_info(agp_info ai)
+
+static void
+agp_list_info(agp_info ai)
{
/*
list device
@@ -118,46 +108,47 @@ static void agp_list_info(agp_info ai)
list capabilities
*/
SHOW_INFO(4, "This device supports AGP specification %ld.%ld;",
- ((ai.interface.agp_cap_id & AGP_rev_major) >> AGP_rev_major_shift),
- ((ai.interface.agp_cap_id & AGP_rev_minor) >> AGP_rev_minor_shift));
+ ((ai.interface.capability_id & AGP_REV_MAJOR) >> AGP_REV_MAJOR_SHIFT),
+ ((ai.interface.capability_id & AGP_REV_MINOR) >> AGP_REV_MINOR_SHIFT));
/* the AGP devices determine AGP speed scheme version used on power-up/reset */
- if (!(ai.interface.agp_stat & AGP_rate_rev))
- {
+ if ((ai.interface.status & AGP_3_MODE) == 0) {
/* AGP 2.0 scheme applies */
- if (ai.interface.agp_stat & AGP_2_1x)
+ if (ai.interface.status & AGP_2_1x)
SHOW_INFO0(4, "AGP 2.0 1x mode is available");
- if (ai.interface.agp_stat & AGP_2_2x)
+ if (ai.interface.status & AGP_2_2x)
SHOW_INFO0(4, "AGP 2.0 2x mode is available");
- if (ai.interface.agp_stat & AGP_2_4x)
+ if (ai.interface.status & AGP_2_4x)
SHOW_INFO0(41, "AGP 2.0 4x mode is available");
- }
- else
- {
+ } else {
/* AGP 3.0 scheme applies */
- if (ai.interface.agp_stat & AGP_3_4x)
+ if (ai.interface.status & AGP_3_4x)
SHOW_INFO0(4, "AGP 3.0 4x mode is available");
- if (ai.interface.agp_stat & AGP_3_8x)
+ if (ai.interface.status & AGP_3_8x)
SHOW_INFO0(4, "AGP 3.0 8x mode is available");
}
- if (ai.interface.agp_stat & AGP_FW) SHOW_INFO0(4, "Fastwrite transfers are supported");
- if (ai.interface.agp_stat & AGP_SBA) SHOW_INFO0(4, "Sideband adressing is supported");
-
+ if (ai.interface.status & AGP_FAST_WRITE)
+ SHOW_INFO0(4, "Fast write transfers are supported");
+ if (ai.interface.status & AGP_SBA)
+ SHOW_INFO0(4, "Sideband adressing is supported");
+
SHOW_INFO(1, "%ld queued AGP requests can be handled.",
- ((ai.interface.agp_stat & AGP_RQ) >> AGP_RQ_shift) + 1);
+ ((ai.interface.status & AGP_REQUEST) >> AGP_REQUEST_SHIFT) + 1);
/*
list current settings,
make sure we have the correct speed scheme for logging
*/
- agp_list_active(ai.interface.agp_cmd | (ai.interface.agp_stat & AGP_rate_rev));
+ agp_list_active(ai.interface.command | (ai.interface.status & AGP_3_MODE));
}
-static void agp_list_active(uint32 cmd)
+
+static void
+agp_list_active(uint32 cmd)
{
SHOW_INFO0(4, "listing settings now in use:");
- if (!(cmd & AGP_rate_rev)) {
+ if ((cmd & AGP_3_MODE) == 0) {
/* AGP 2.0 scheme applies */
if (cmd & AGP_2_1x)
SHOW_INFO0(2,"AGP 2.0 1x mode is set");
@@ -173,17 +164,18 @@ static void agp_list_active(uint32 cmd)
SHOW_INFO0(2,"AGP 3.0 8x mode is set");
}
- if (cmd & AGP_FW) {
- SHOW_INFO0(2, "Fastwrite transfers are enabled");
+ if (cmd & AGP_FAST_WRITE) {
+ SHOW_INFO0(2, "Fast write transfers are enabled");
} else {
- SHOW_INFO0(2, "Fastwrite transfers are disabled");
+ SHOW_INFO0(2, "Fast write transfers are disabled");
}
- if (cmd & AGP_SBA) SHOW_INFO0(4, "Sideband adressing is enabled");
-
+ if (cmd & AGP_SBA)
+ SHOW_INFO0(4, "Sideband adressing is enabled");
+
SHOW_INFO(4, "Max. AGP queued request depth is set to %ld",
- (((cmd & AGP_RQ) >> AGP_RQ_shift) + 1));
-
- if (cmd & AGP_enable)
+ (((cmd & AGP_REQUEST) >> AGP_REQUEST_SHIFT) + 1));
+
+ if (cmd & AGP_ENABLE)
SHOW_INFO0(2, "The AGP interface is enabled.");
else
SHOW_INFO0(2, "The AGP interface is disabled.");
diff --git a/src/add-ons/kernel/drivers/graphics/radeon/driver.c b/src/add-ons/kernel/drivers/graphics/radeon/driver.c
index 6ae7abd39a..ad0ad1e9f3 100644
--- a/src/add-ons/kernel/drivers/graphics/radeon/driver.c
+++ b/src/add-ons/kernel/drivers/graphics/radeon/driver.c
@@ -1,9 +1,7 @@
/*
Copyright (c) 2002, Thomas Kurschel
-
Part of Radeon kernel driver
-
DevFS interface
*/
@@ -24,12 +22,12 @@
int32 api_version = 2;
-static status_t open_hook( const char *name, uint32 flags, void **cookie );
-static status_t close_hook( void *dev );
-static status_t free_hook( void *dev );
-static status_t read_hook( void *dev, off_t pos, void *buf, size_t *len );
-static status_t write_hook( void *dev, off_t pos, const void *buf, size_t *len );
-static status_t control_hook( void *dev, uint32 msg, void *buf, size_t len );
+static status_t open_hook(const char *name, uint32 flags, void **cookie);
+static status_t close_hook(void *dev);
+static status_t free_hook(void *dev);
+static status_t read_hook(void *dev, off_t pos, void *buf, size_t *len);
+static status_t write_hook(void *dev, off_t pos, const void *buf, size_t *len);
+static status_t control_hook(void *dev, uint32 msg, void *buf, size_t len);
static device_hooks graphics_device_hooks = {
@@ -61,10 +59,10 @@ radeon_settings def_settings = { // see comments in radeon.settings
radeon_settings current_settings;
-static void GetDriverSettings(void)
+static void
+GetDriverSettings(void)
{
-
- void *settings_handle = NULL;
+ void *settings_handle = NULL;
SHOW_FLOW0( 1, "" );
@@ -129,118 +127,125 @@ static void GetDriverSettings(void)
}
}
-// public function: check whether there is *any* supported hardware
-status_t init_hardware( void )
+
+// #pragma mark - driver API
+
+
+status_t
+init_hardware(void)
{
- SHOW_INFO0( 0, RADEON_DRIVER_VERSION );
- if( Radeon_CardDetect() == B_OK )
+ SHOW_INFO0(0, RADEON_DRIVER_VERSION);
+ if (Radeon_CardDetect() == B_OK)
return B_OK;
- else
- return B_ERROR;
+
+ return B_ERROR;
}
-// public function: init driver
-status_t init_driver( void )
+status_t
+init_driver(void)
{
- SHOW_FLOW0( 3, "" );
-
- if( get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK )
+ SHOW_FLOW0(3, "");
+
+ if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK)
return B_ERROR;
/* get a handle for the agp bus if it exists */
- get_module(B_AGP_MODULE_NAME, (module_info **)&agp_bus);
+ get_module(B_AGP_GART_MODULE_NAME, (module_info **)&sAGP);
/* driver private data */
- devices = (radeon_devices *)calloc( 1, sizeof( radeon_devices ));
- if( devices == NULL ) {
+ devices = (radeon_devices *)calloc(1, sizeof(radeon_devices));
+ if (devices == NULL) {
put_module(B_PCI_MODULE_NAME);
- if (agp_bus != NULL)
- put_module(B_AGP_MODULE_NAME);
+ if (sAGP != NULL)
+ put_module(B_AGP_GART_MODULE_NAME);
return B_ERROR;
}
-
- (void)INIT_BEN( devices->kernel, "Radeon Kernel" );
-
+
+ (void)INIT_BEN(devices->kernel, "Radeon Kernel");
+
GetDriverSettings();
Radeon_ProbeDevices();
return B_OK;
}
-// public function: uninit driver
-void uninit_driver( void )
+void
+uninit_driver(void)
{
- SHOW_FLOW0( 3, "" );
- DELETE_BEN( devices->kernel );
-
- free( devices );
+ SHOW_FLOW0(3, "");
+ DELETE_BEN(devices->kernel);
+
+ free(devices);
devices = NULL;
- put_module( B_PCI_MODULE_NAME );
- /* put the agp module away if it's there */
- if (agp_bus)
- put_module(B_AGP_MODULE_NAME);
+ put_module(B_PCI_MODULE_NAME);
+ if (sAGP)
+ put_module(B_AGP_GART_MODULE_NAME);
}
-// public function: return list of device names
-const char **publish_devices( void )
+const char **
+publish_devices(void)
{
return (const char **)devices->device_names;
}
-// public function: find hooks for specific device given its name
-device_hooks *find_device( const char *name )
+device_hooks *
+find_device(const char *name)
{
uint32 index;
-
+
// probably, we could always return standard hooks
- for( index = 0; devices->device_names[index]; ++index ) {
- if( strcmp( name, devices->device_names[index] ) == 0 )
+ for (index = 0; devices->device_names[index]; ++index) {
+ if (strcmp(name, devices->device_names[index]) == 0)
return &graphics_device_hooks;
}
-
+
return NULL;
}
-// public function: open device
-static status_t open_hook( const char *name, uint32 flags, void **cookie )
+// #pragma mark - device API
+
+
+static status_t
+open_hook(const char *name, uint32 flags, void **cookie)
{
int32 index = 0;
device_info *di;
- status_t result = B_OK;
+ status_t result = B_OK;
SHOW_FLOW( 3, "name=%s, flags=%ld, cookie=0x%08lx", name, flags, (uint32)cookie );
// find device info
- while( devices->device_names[index] &&
- strcmp(name, devices->device_names[index] ) != 0 )
+ while (devices->device_names[index]
+ && strcmp(name, devices->device_names[index]) != 0) {
index++;
+ }
- di = &(devices->di[index/2]);
+ di = &(devices->di[index / 2]);
- ACQUIRE_BEN( devices->kernel );
+ ACQUIRE_BEN(devices->kernel);
- if( !di->is_open )
- result = Radeon_FirstOpen( di );
+ if (!di->is_open)
+ result = Radeon_FirstOpen(di);
- if( result == B_OK ) {
+ if (result == B_OK) {
di->is_open++;
*cookie = di;
}
-
- RELEASE_BEN( devices->kernel );
- SHOW_FLOW( 3, "returning 0x%08lx", result );
+ RELEASE_BEN(devices->kernel);
+
+ SHOW_FLOW(3, "returning 0x%08lx", result);
return result;
}
-// public function: read from device (denied)
-static status_t read_hook( void *dev, off_t pos, void *buf, size_t *len )
+static status_t
+read_hook(void *dev, off_t pos, void *buf, size_t *len)
{
*len = 0;
return B_NOT_ALLOWED;
@@ -248,22 +253,23 @@ static status_t read_hook( void *dev, off_t pos, void *buf, size_t *len )
// public function: write to device (denied)
-static status_t write_hook( void *dev, off_t pos, const void *buf, size_t *len )
+static status_t
+write_hook(void *dev, off_t pos, const void *buf, size_t *len)
{
*len = 0;
return B_NOT_ALLOWED;
}
-// public function: close device (ignored, wait for free_hook instead)
-static status_t close_hook( void *dev )
+static status_t
+close_hook(void *dev)
{
return B_NO_ERROR;
}
-// public function: free device
-static status_t free_hook( void *dev )
+static status_t
+free_hook(void *dev)
{
device_info *di = (device_info *)dev;
@@ -289,8 +295,8 @@ static status_t free_hook( void *dev )
}
-// public function: ioctl
-static status_t control_hook( void *dev, uint32 msg, void *buf, size_t len )
+static status_t
+control_hook(void *dev, uint32 msg, void *buf, size_t len)
{
device_info *di = (device_info *)dev;
status_t result = B_DEV_INVALID_IOCTL;
diff --git a/src/add-ons/kernel/drivers/graphics/radeon/global_data.c b/src/add-ons/kernel/drivers/graphics/radeon/global_data.c
index 338f5ff21d..547f9fbb47 100644
--- a/src/add-ons/kernel/drivers/graphics/radeon/global_data.c
+++ b/src/add-ons/kernel/drivers/graphics/radeon/global_data.c
@@ -1,9 +1,7 @@
/*
Copyright (c) 2002, Thomas Kurschel
-
Part of Radeon kernel driver
-
Global variables
*/
@@ -16,4 +14,4 @@ int debug_level_error = 4;
radeon_devices *devices;
pci_module_info *pci_bus;
-agp_module_info *agp_bus;
+agp_gart_module_info *sAGP;
diff --git a/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h b/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h
index d681c59426..0416601f1c 100644
--- a/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h
+++ b/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h
@@ -176,7 +176,7 @@ typedef struct {
extern pci_module_info *pci_bus;
-extern agp_module_info *agp_bus;
+extern agp_gart_module_info *sAGP;
extern radeon_devices *devices;
diff --git a/src/add-ons/kernel/drivers/graphics/via/driver.c b/src/add-ons/kernel/drivers/graphics/via/driver.c
index 1a26210f45..9018d29b94 100644
--- a/src/add-ons/kernel/drivers/graphics/via/driver.c
+++ b/src/add-ons/kernel/drivers/graphics/via/driver.c
@@ -81,7 +81,7 @@ static int32 eng_interrupt(void *data);
static DeviceData *pd;
static isa_module_info *isa_bus = NULL;
static pci_module_info *pci_bus = NULL;
-static agp_module_info *agp_bus = NULL;
+static agp_gart_module_info *agp_bus = NULL;
static device_hooks graphics_device_hooks = {
open_hook,
close_hook,
@@ -102,6 +102,7 @@ static uint16 via_device_list[] = {
0x3108, /* K8M800 Unichrome Pro (unknown chiptype) */
0x3122, /* CLE266 Unichrome Pro (CLE3122) */
0x3205, /* KM400 Unichrome (VT3205) */
+// 0x3344, /* P4M800 Pro (VT3344) */
0x7205, /* KM400 Unichrome (VT7205) */
0
};
@@ -279,13 +280,13 @@ init_driver(void) {
}
/* get a handle for the agp bus if it exists */
- get_module(B_AGP_MODULE_NAME, (module_info **)&agp_bus);
+ get_module(B_AGP_GART_MODULE_NAME, (module_info **)&agp_bus);
/* driver private data */
pd = (DeviceData *)calloc(1, sizeof(DeviceData));
if (!pd) {
if (agp_bus)
- put_module(B_AGP_MODULE_NAME);
+ put_module(B_AGP_GART_MODULE_NAME);
put_module(B_ISA_MODULE_NAME);
put_module(B_PCI_MODULE_NAME);
return B_ERROR;
@@ -328,7 +329,7 @@ void uninit_driver(void) {
/* put the agp module away if it's there */
if (agp_bus)
- put_module(B_AGP_MODULE_NAME);
+ put_module(B_AGP_GART_MODULE_NAME);
}
static status_t map_device(device_info *di)
@@ -900,7 +901,7 @@ control_hook (void* dev, uint32 msg, void *buf, size_t len) {
if (nca->magic == VIA_PRIVATE_DATA_MAGIC) {
if (agp_bus) {
nca->agp_bus = true;
- (*agp_bus->enable_agp)(&(nca->cmd));
+ nca->cmd = agp_bus->set_agp_mode(nca->cmd);
} else {
nca->agp_bus = false;
nca->cmd = 0;