/drivers/old/agp/agp.c |
---|
0,0 → 1,602 |
#include "types.h" |
#include "link.h" |
#include <stdio.h> |
#include <malloc.h> |
#include <memory.h> |
#include "pci.h" |
#include "agp.h" |
#include "syscall.h" |
agp_t *bridge; |
int __stdcall srv_agp(ioctl_t *io); |
u32_t __stdcall drvEntry(int action) |
{ |
u32_t retval; |
int i; |
if(action != 1) |
return 0; |
if(!dbg_open("/rd/1/drivers/agp.log")) |
{ |
printf("Can't open /rd/1/drivers/agp.log\nExit\n"); |
return 0; |
} |
if( FindPciDevice() == 0) |
{ |
dbgprintf("Device not found\n"); |
return 0; |
}; |
return 0; |
// retval = RegService("AGP", srv_2d); |
// dbgprintf("reg service %s as: %x\n", "HDRAW", retval); |
// return retval; |
}; |
#include "pci.inc" |
#include "isoch.inc" |
static void intel_8xx_tlbflush(void *mem) |
{ |
u32_t temp; |
temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL); |
pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp & ~(1 << 7)); |
temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL); |
pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp | (1 << 7)); |
} |
static aper_size_t intel_8xx_sizes[7] = |
{ |
{ 256, 65536, 64, 0 }, |
{ 128, 32768, 32, 32 }, |
{ 64, 16384, 16, 48 }, |
{ 32, 8192, 8, 56 }, |
{ 16, 4096, 4, 60 }, |
{ 8, 2048, 2, 62 }, |
{ 4, 1024, 1, 63 } |
}; |
static int intel_845_configure() |
{ |
u32_t temp; |
u8_t temp2; |
aper_size_t *current_size; |
current_size = bridge->current_size; |
/* aperture size */ |
pciWriteByte(bridge->PciTag, INTEL_APSIZE, current_size->size_value); |
dbgprintf("INTEL_APSIZE %d\n", current_size->size_value ); |
if (bridge->apbase_config != 0) |
{ |
pciWriteLong(bridge->PciTag, AGP_APBASE, bridge->apbase_config); |
} |
else |
{ |
/* address to map to */ |
temp = pciReadLong(bridge->PciTag, AGP_APBASE); |
bridge->gart_addr = (temp & PCI_MAP_MEMORY_ADDRESS_MASK); |
bridge->apbase_config = temp; |
} |
dbgprintf("AGP_APBASE %x\n", temp ); |
/* attbase - aperture base */ |
pciWriteLong(bridge->PciTag, INTEL_ATTBASE, bridge->gatt_dma); |
/* agpctrl */ |
pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, 0x0000); |
/* agpm */ |
temp2 = pciReadByte(bridge->PciTag, INTEL_I845_AGPM); |
pciWriteByte(bridge->PciTag, INTEL_I845_AGPM, temp2 | (1 << 1)); |
/* clear any possible error conditions */ |
pciWriteWord(bridge->PciTag, INTEL_I845_ERRSTS, 0x001c); |
return 0; |
} |
int agp_generic_create_gatt_table() |
{ |
count_t pages; |
pages = bridge->current_size->pages_count; |
if( bridge->gatt_dma = AllocPages(pages)) |
{ |
if(bridge->gatt_table = |
(u32_t*)MapIoMem((void*)bridge->gatt_dma, |
pages<<12, PG_SW+PG_NOCACHE)) |
{ |
dbgprintf("gatt map %x at %x %d pages\n",bridge->gatt_dma , |
bridge->gatt_table, pages); |
/* AK: bogus, should encode addresses > 4GB */ |
u32_t volatile *table = bridge->gatt_table; |
count_t count = bridge->current_size->num_entries; |
while(count--) { /* FIXME memset */ |
addr_t tmp; |
*table = 0; |
table++; |
} |
return 1; |
}; |
}; |
dbgprintf("unable to get memory for " |
"graphics translation table.\n"); |
return 0; |
} |
static int __intel_8xx_fetch_size(u8_t temp) |
{ |
int i; |
aper_size_t *values; |
values = bridge->aperture_sizes; |
values = intel_8xx_sizes; |
for (i = 0; i < 7; i++) |
{ |
if (temp == values[i].size_value) |
{ |
bridge->previous_size = |
bridge->current_size = (void *) (values + i); |
bridge->aperture_size_idx = i; |
return values[i].size; |
} |
} |
return 0; |
} |
static int intel_8xx_fetch_size(void) |
{ |
u8_t temp; |
temp = pciReadByte(bridge->PciTag, INTEL_APSIZE); |
return __intel_8xx_fetch_size(temp); |
} |
int agp_bind_memory(addr_t agp_addr, addr_t dma_addr, size_t size) |
{ |
int ret_val; |
count_t count; |
// if (curr == NULL) |
// return -EINVAL; |
// if (curr->is_bound == TRUE) { |
// printk(KERN_INFO PFX "memory %p is already bound!\n", curr); |
// return -EINVAL; |
// } |
// if (curr->is_flushed == FALSE) { |
// curr->bridge->driver->cache_flush(); |
// curr->is_flushed = TRUE; |
// } |
// ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); |
u32_t volatile *table = &bridge->gatt_table[agp_addr>>12]; |
count = size >> 12; |
dma_addr |= 0x00000017; |
while(count--) |
{ |
*table = dma_addr; |
table++; |
dma_addr+=4096; |
} |
bridge->tlb_flush(NULL); |
// if (ret_val != 0) |
// return ret_val; |
// curr->is_bound = TRUE; |
// curr->pg_start = pg_start; |
return 0; |
} |
void get_agp_version(agp_t *bridge) |
{ |
u32_t ncapid; |
/* Exit early if already set by errata workarounds. */ |
if (bridge->major_version != 0) |
return; |
ncapid = pciReadLong(bridge->PciTag, bridge->capndx); |
bridge->major_version = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; |
bridge->minor_version = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf; |
} |
static void agp_v2_parse_one(u32_t *requested_mode, u32_t *bridge_agpstat, u32_t *vga_agpstat) |
{ |
u32_t tmp; |
if (*requested_mode & AGP2_RESERVED_MASK) { |
dbgprintf("reserved bits set (%x) in mode 0x%x. Fixed.\n", |
*requested_mode & AGP2_RESERVED_MASK, *requested_mode); |
*requested_mode &= ~AGP2_RESERVED_MASK; |
} |
/* Check the speed bits make sense. Only one should be set. */ |
tmp = *requested_mode & 7; |
switch (tmp) { |
case 0: |
dbgprintf("Setting to x1 mode.\n"); |
*requested_mode |= AGPSTAT2_1X; |
break; |
case 1: |
case 2: |
break; |
case 3: |
*requested_mode &= ~(AGPSTAT2_1X); /* rate=2 */ |
break; |
case 4: |
break; |
case 5: |
case 6: |
case 7: |
*requested_mode &= ~(AGPSTAT2_1X|AGPSTAT2_2X); /* rate=4*/ |
break; |
} |
/* disable SBA if it's not supported */ |
if (!((*bridge_agpstat & AGPSTAT_SBA) && (*vga_agpstat & AGPSTAT_SBA) && (*requested_mode & AGPSTAT_SBA))) |
*bridge_agpstat &= ~AGPSTAT_SBA; |
/* Set rate */ |
if (!((*bridge_agpstat & AGPSTAT2_4X) && (*vga_agpstat & AGPSTAT2_4X) && (*requested_mode & AGPSTAT2_4X))) |
*bridge_agpstat &= ~AGPSTAT2_4X; |
if (!((*bridge_agpstat & AGPSTAT2_2X) && (*vga_agpstat & AGPSTAT2_2X) && (*requested_mode & AGPSTAT2_2X))) |
*bridge_agpstat &= ~AGPSTAT2_2X; |
if (!((*bridge_agpstat & AGPSTAT2_1X) && (*vga_agpstat & AGPSTAT2_1X) && (*requested_mode & AGPSTAT2_1X))) |
*bridge_agpstat &= ~AGPSTAT2_1X; |
/* Now we know what mode it should be, clear out the unwanted bits. */ |
if (*bridge_agpstat & AGPSTAT2_4X) |
*bridge_agpstat &= ~(AGPSTAT2_1X | AGPSTAT2_2X); /* 4X */ |
if (*bridge_agpstat & AGPSTAT2_2X) |
*bridge_agpstat &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */ |
if (*bridge_agpstat & AGPSTAT2_1X) |
*bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1X */ |
/* Apply any errata. */ |
if (bridge->flags & AGP_ERRATA_FASTWRITES) |
*bridge_agpstat &= ~AGPSTAT_FW; |
if (bridge->flags & AGP_ERRATA_SBA) |
*bridge_agpstat &= ~AGPSTAT_SBA; |
if (bridge->flags & AGP_ERRATA_1X) { |
*bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); |
*bridge_agpstat |= AGPSTAT2_1X; |
} |
/* If we've dropped down to 1X, disable fast writes. */ |
if (*bridge_agpstat & AGPSTAT2_1X) |
*bridge_agpstat &= ~AGPSTAT_FW; |
} |
static void agp_v3_parse_one(u32_t *requested_mode, |
u32_t *bridge_agpstat, |
u32_t *vga_agpstat) |
{ |
u32_t origbridge = *bridge_agpstat, origvga = *vga_agpstat; |
u32_t tmp; |
if (*requested_mode & AGP3_RESERVED_MASK) |
{ |
dbgprintf("reserved bits set (%x) in mode 0x%x. Fixed.\n", |
*requested_mode & AGP3_RESERVED_MASK, *requested_mode); |
*requested_mode &= ~AGP3_RESERVED_MASK; |
} |
/* Check the speed bits make sense. */ |
tmp = *requested_mode & 7; |
if (tmp == 0) { |
dbgprintf("Setting to AGP3 x4 mode.\n"); |
*requested_mode |= AGPSTAT3_4X; |
} |
if (tmp >= 3) { |
dbgprintf("Setting to AGP3 x8 mode.\n"); |
*requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X; |
} |
/* ARQSZ - Set the value to the maximum one. |
* Don't allow the mode register to override values. */ |
*bridge_agpstat = ((*bridge_agpstat & ~AGPSTAT_ARQSZ) | |
max_t(u32_t,(*bridge_agpstat & AGPSTAT_ARQSZ),(*vga_agpstat & AGPSTAT_ARQSZ))); |
/* Calibration cycle. |
* Don't allow the mode register to override values. */ |
*bridge_agpstat = ((*bridge_agpstat & ~AGPSTAT_CAL_MASK) | |
min_t(u32_t,(*bridge_agpstat & AGPSTAT_CAL_MASK),(*vga_agpstat & AGPSTAT_CAL_MASK))); |
/* SBA *must* be supported for AGP v3 */ |
*bridge_agpstat |= AGPSTAT_SBA; |
/* |
* Set speed. |
* Check for invalid speeds. This can happen when applications |
* written before the AGP 3.0 standard pass AGP2.x modes to AGP3 hardware |
*/ |
if (*requested_mode & AGPSTAT_MODE_3_0) { |
/* |
* Caller hasn't a clue what it is doing. Bridge is in 3.0 mode, |
* have been passed a 3.0 mode, but with 2.x speed bits set. |
* AGP2.x 4x -> AGP3.0 4x. |
*/ |
if (*requested_mode & AGPSTAT2_4X) { |
dbgprintf("broken AGP3 flags (%x). Fixed.\n", *requested_mode); |
*requested_mode &= ~AGPSTAT2_4X; |
*requested_mode |= AGPSTAT3_4X; |
} |
} else { |
/* |
* The caller doesn't know what they are doing. We are in 3.0 mode, |
* but have been passed an AGP 2.x mode. |
* Convert AGP 1x,2x,4x -> AGP 3.0 4x. |
*/ |
dbgprintf("broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",*requested_mode); |
*requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X); |
*requested_mode |= AGPSTAT3_4X; |
} |
if (*requested_mode & AGPSTAT3_8X) { |
if (!(*bridge_agpstat & AGPSTAT3_8X)) { |
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); |
*bridge_agpstat |= AGPSTAT3_4X; |
dbgprintf("requested AGPx8 but bridge not capable.\n"); |
return; |
} |
if (!(*vga_agpstat & AGPSTAT3_8X)) { |
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); |
*bridge_agpstat |= AGPSTAT3_4X; |
dbgprintf("requested AGPx8 but graphic card not capable.\n"); |
return; |
} |
/* All set, bridge & device can do AGP x8*/ |
*bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); |
goto done; |
} else { |
/* |
* If we didn't specify AGPx8, we can only do x4. |
* If the hardware can't do x4, we're up shit creek, and never |
* should have got this far. |
*/ |
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); |
if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X)) |
*bridge_agpstat |= AGPSTAT3_4X; |
else { |
dbgprintf("Badness. Don't know which AGP mode to set. " |
"[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n", |
origbridge, origvga, *bridge_agpstat, *vga_agpstat); |
if (!(*bridge_agpstat & AGPSTAT3_4X)) |
dbgprintf("Bridge couldn't do AGP x4.\n"); |
if (!(*vga_agpstat & AGPSTAT3_4X)) |
dbgprintf("Graphic card couldn't do AGP x4.\n"); |
return; |
} |
} |
done: |
/* Apply any errata. */ |
if (bridge->flags & AGP_ERRATA_FASTWRITES) |
*bridge_agpstat &= ~AGPSTAT_FW; |
if (bridge->flags & AGP_ERRATA_SBA) |
*bridge_agpstat &= ~AGPSTAT_SBA; |
if (bridge->flags & AGP_ERRATA_1X) { |
*bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); |
*bridge_agpstat |= AGPSTAT2_1X; |
} |
} |
u32_t agp_collect_device_status(agp_t *bridge, u32_t requested_mode, |
u32_t bridge_agpstat) |
{ |
PCITAG vgaTag; |
u32_t vga_agpstat; |
int cap_ptr; |
for (;;) |
{ |
vgaTag = pci_find_class(PCI_CLASS_DISPLAY_VGA); |
if (vgaTag == -1) |
{ |
dbgprintf("Couldn't find an AGP VGA controller.\n"); |
return 0; |
} |
cap_ptr = pci_find_capability(vgaTag, PCI_CAP_ID_AGP); |
if (cap_ptr) |
break; |
} |
/* |
* Ok, here we have a AGP device. Disable impossible |
* settings, and adjust the readqueue to the minimum. |
*/ |
vga_agpstat = pciReadLong(vgaTag, cap_ptr+PCI_AGP_STATUS); |
/* adjust RQ depth */ |
bridge_agpstat = ((bridge_agpstat & ~AGPSTAT_RQ_DEPTH) | |
min_t(u32_t, (requested_mode & AGPSTAT_RQ_DEPTH), |
min_t(u32_t, (bridge_agpstat & AGPSTAT_RQ_DEPTH), (vga_agpstat & AGPSTAT_RQ_DEPTH)))); |
/* disable FW if it's not supported */ |
if (!((bridge_agpstat & AGPSTAT_FW) && |
(vga_agpstat & AGPSTAT_FW) && |
(requested_mode & AGPSTAT_FW))) |
bridge_agpstat &= ~AGPSTAT_FW; |
/* Check to see if we are operating in 3.0 mode */ |
if (bridge->mode & AGPSTAT_MODE_3_0) |
agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); |
else |
agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); |
return bridge_agpstat; |
} |
void agp_device_command(u32_t bridge_agpstat, int agp_v3) |
{ |
PCITAG device = 0; |
int mode; |
mode = bridge_agpstat & 0x7; |
if (agp_v3) |
mode *= 4; |
for_each_pci_dev(device) |
{ |
int agp = pci_find_capability(device, PCI_CAP_ID_AGP); |
if (!agp) |
continue; |
dbgprintf("Putting AGP V%d device at into %dx mode\n", |
agp_v3 ? 3 : 2, mode); |
pciWriteLong(device, agp + PCI_AGP_COMMAND, bridge_agpstat); |
} |
} |
void agp_generic_enable(u32_t requested_mode) |
{ |
u32_t bridge_agpstat, temp; |
get_agp_version(bridge); |
dbgprintf("Found an AGP %d.%d compliant device.\n", |
bridge->major_version, bridge->minor_version); |
bridge_agpstat = pciReadLong(bridge->PciTag, |
bridge->capndx + PCI_AGP_STATUS); |
bridge_agpstat = agp_collect_device_status(bridge, requested_mode, bridge_agpstat); |
if (bridge_agpstat == 0) |
/* Something bad happened. FIXME: Return error code? */ |
return; |
bridge_agpstat |= AGPSTAT_AGP_ENABLE; |
/* Do AGP version specific frobbing. */ |
if (bridge->major_version >= 3) |
{ |
if (bridge->mode & AGPSTAT_MODE_3_0) |
{ |
/* If we have 3.5, we can do the isoch stuff. */ |
if (bridge->minor_version >= 5) |
agp_3_5_enable(bridge); |
agp_device_command(bridge_agpstat, TRUE); |
return; |
} |
else |
{ |
/* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/ |
bridge_agpstat &= ~(7<<10) ; |
temp = pciReadLong(bridge->PciTag, bridge->capndx+AGPCTRL); |
temp |= (1<<9); |
pciWriteLong(bridge->PciTag, bridge->capndx+AGPCTRL, temp); |
dbgprintf("Device is in legacy mode," |
" falling back to 2.x\n"); |
} |
} |
/* AGP v<3 */ |
agp_device_command(bridge_agpstat, FALSE); |
} |
static agp_t intel_845_driver = |
{ |
.aperture_sizes = intel_8xx_sizes, |
// .size_type = U8_APER_SIZE, |
// .num_aperture_sizes = 7, |
.configure = intel_845_configure, |
.fetch_size = intel_8xx_fetch_size, |
// .cleanup = intel_8xx_cleanup, |
.tlb_flush = intel_8xx_tlbflush, |
// .mask_memory = agp_generic_mask_memory, |
// .masks = intel_generic_masks, |
// .agp_enable = agp_generic_enable, |
// .cache_flush = global_cache_flush, |
.create_gatt_table = agp_generic_create_gatt_table, |
// .free_gatt_table = agp_generic_free_gatt_table, |
// .insert_memory = agp_generic_insert_memory, |
// .remove_memory = agp_generic_remove_memory, |
// .alloc_by_type = agp_generic_alloc_by_type, |
// .free_by_type = agp_generic_free_by_type, |
// .agp_alloc_page = agp_generic_alloc_page, |
// .agp_destroy_page = agp_generic_destroy_page, |
}; |
int init_bridge(PCITAG pciTag) |
{ |
size_t size_value; |
bridge = &intel_845_driver; |
bridge->PciTag = pciTag; |
bridge->capndx = pci_find_capability(pciTag, PCI_CAP_ID_AGP); |
size_value = bridge->fetch_size(); |
if (size_value == 0) { |
dbgprintf("unable to determine aperture size.\n"); |
return 0; |
}; |
dbgprintf("fetch size = %x\n", size_value); |
if( bridge->create_gatt_table() ) |
{ |
bridge->configure(); |
return 1; |
} |
return 0; |
} |
#include "detect.inc" |
/drivers/old/agp/agp.h |
---|
0,0 → 1,147 |
/* Chipset independant registers (from AGP Spec) */ |
#define AGP_APBASE 0x10 |
#define AGPSTAT 0x4 |
#define AGPCMD 0x8 |
#define AGPNISTAT 0xc |
#define AGPCTRL 0x10 |
#define AGPAPSIZE 0x14 |
#define AGPNEPG 0x16 |
#define AGPGARTLO 0x18 |
#define AGPGARTHI 0x1c |
#define AGPNICMD 0x20 |
#define AGP_MAJOR_VERSION_SHIFT (20) |
#define AGP_MINOR_VERSION_SHIFT (16) |
#define AGPSTAT_RQ_DEPTH (0xff000000) |
#define AGPSTAT_RQ_DEPTH_SHIFT 24 |
#define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10) |
#define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13) |
#define AGPSTAT_ARQSZ_SHIFT 13 |
#define AGPSTAT_SBA (1<<9) |
#define AGPSTAT_AGP_ENABLE (1<<8) |
#define AGPSTAT_FW (1<<4) |
#define AGPSTAT_MODE_3_0 (1<<3) |
#define AGPSTAT2_1X (1<<0) |
#define AGPSTAT2_2X (1<<1) |
#define AGPSTAT2_4X (1<<2) |
#define AGPSTAT3_RSVD (1<<2) |
#define AGPSTAT3_8X (1<<1) |
#define AGPSTAT3_4X (1) |
#define AGPCTRL_APERENB (1<<8) |
#define AGPCTRL_GTLBEN (1<<7) |
#define AGP2_RESERVED_MASK 0x00fffcc8 |
#define AGP3_RESERVED_MASK 0x00ff00c4 |
#define AGP_ERRATA_FASTWRITES 1<<0 |
#define AGP_ERRATA_SBA 1<<1 |
#define AGP_ERRATA_1X 1<<2 |
/* Intel registers */ |
#define INTEL_APSIZE 0xb4 |
#define INTEL_ATTBASE 0xb8 |
#define INTEL_AGPCTRL 0xb0 |
#define INTEL_NBXCFG 0x50 |
#define INTEL_ERRSTS 0x91 |
/* Intel i845 registers */ |
#define INTEL_I845_AGPM 0x51 |
#define INTEL_I845_ERRSTS 0xc8 |
/* Chipset independant registers (from AGP Spec) */ |
#define AGP_APBASE 0x10 |
typedef struct |
{ |
size_t size; |
count_t num_entries; |
count_t pages_count; |
u32_t size_value; |
}aper_size_t; |
typedef struct |
{ |
PCITAG PciTag; |
aper_size_t *aperture_sizes; |
aper_size_t *current_size; |
aper_size_t *previous_size; |
int aperture_size_idx; |
u32_t volatile *gatt_table; |
addr_t gatt_dma; |
addr_t apbase_config; |
addr_t gart_addr; |
u32_t flags; |
u32_t mode; |
int capndx; |
char major_version; |
char minor_version; |
// int num_aperture_sizes; |
// enum aper_size_type size_type; |
// int cant_use_aperture; |
// int needs_scratch_page; |
// struct gatt_mask *masks; |
int (*fetch_size)(); |
int (*configure)(); |
// void (*agp_enable)(struct agp_bridge_data *, u32); |
// void (*cleanup)(void); |
void (*tlb_flush)(); |
// u32_t (*mask_memory)(struct agp_bridge_data *,u32_t, int); |
// void (*cache_flush)(void); |
int (*create_gatt_table)(); |
// int (*free_gatt_table)(struct agp_bridge_data *); |
// int (*insert_memory)(struct agp_memory *, off_t, int); |
// int (*remove_memory)(struct agp_memory *, off_t, int); |
// struct agp_memory *(*alloc_by_type) (size_t, int); |
// void (*free_by_type)(struct agp_memory *); |
// void *(*agp_alloc_page)(struct agp_bridge_data *); |
// void (*agp_destroy_page)(void *); |
}agp_t; |
/* |
* min()/max() macros that also do |
* strict type-checking.. See the |
* "unnecessary" pointer comparison. |
*/ |
#define min(x,y) ({ \ |
typeof(x) _x = (x); \ |
typeof(y) _y = (y); \ |
(void) (&_x == &_y); \ |
_x < _y ? _x : _y; }) |
#define max(x,y) ({ \ |
typeof(x) _x = (x); \ |
typeof(y) _y = (y); \ |
(void) (&_x == &_y); \ |
_x > _y ? _x : _y; }) |
#define min_t(type,x,y) \ |
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) |
#define max_t(type,x,y) \ |
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) |
#define PCI_ANY_ID (~0) |
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d))!=-1) |
/drivers/old/agp/agp.lk |
---|
0,0 → 1,27 |
IMP |
_KernelAlloc core.KernelAlloc, |
_KernelFree core.KernelFree, |
_UserAlloc core.UserAlloc, |
_UserFree core.UserFree, |
_CommitPages core.CommitPages, |
_AllocPages core.AllocPages, |
_UnmapPages core.UnmapPages, |
_CreateObject core.CreateObject, |
_DestroyObject core.DestroyObject, |
_MapIoMem core.MapIoMem, |
_GetPgAddr core.GetPgAddr, |
_CreateRingBuffer core.CreateRingBuffer, |
_PciApi core.PciApi, |
_PciRead8 core.PciRead8, |
_PciRead16 core.PciRead16, |
_PciRead32 core.PciRead32, |
_PciWrite8 core.PciWrite8, |
_PciWrite16 core.PciWrite16, |
_PciWrite32 core.PciWrite32, |
_RegService core.RegService, |
_SysMsgBoardStr core.SysMsgBoardStr |
FIL agp.obj, |
vsprintf.obj, |
icompute.obj |
/drivers/old/agp/detect.inc |
---|
0,0 → 1,116 |
#define PCI_CLASS_BRIDGE_HOST 0x06 |
#define INTEL_82443LX_0 (0x7180<<16)|0x8086 |
#define INTEL_82443BX_0 (0x7190<<16)|0x8086 |
#define INTEL_82443GX_0 (0x71a0<<16)|0x8086 |
#define INTEL_82810_MC1 (0x7120<<16)|0x8086 |
#define INTEL_82810_MC3 (0x7122<<16)|0x8086 |
#define INTEL_82810E_MC (0x7124<<16)|0x8086 |
#define INTEL_82815_MC (0x1130<<16)|0x8086 |
#define INTEL_82820_HB (0x2500<<16)|0x8086 |
#define INTEL_82820_UP_HB (0x2501<<16)|0x8086 |
#define INTEL_82830_HB (0x3575<<16)|0x8086 |
#define INTEL_82840_HB (0x1a21<<16)|0x8086 |
#define INTEL_82845_HB (0x1a30<<16)|0x8086 |
#define INTEL_82845G_HB (0x2560<<16)|0x8086 |
#define INTEL_82850_HB (0x2530<<16)|0x8086 |
#define INTEL_82855PM_HB (0x3340<<16)|0x8086 |
#define INTEL_82855GM_HB (0x3580<<16)|0x8086 |
#define INTEL_82860_HB (0x2531<<16)|0x8086 |
#define INTEL_82865_HB (0x2570<<16)|0x8086 |
#define INTEL_82875_HB (0x2578<<16)|0x8086 |
#define INTEL_7505_0 (0x2550<<16)|0x8086 |
#define INTEL_7205_0 (0x255d<<16)|0x8086 |
#define INTEL_82915G_HB (0x2580<<16)|0x8086 |
#define INTEL_82915GM_HB (0x2590<<16)|0x8086 |
#define INTEL_82945G_HB (0x2770<<16)|0x8086 |
#define INTEL_82945GM_HB (0x27A0<<16)|0x8086 |
typedef struct |
{ |
int id; |
int driver; |
}pci_device_t; |
static pci_device_t agp_dev_table[] = { |
// { INTEL_82443LX_0, 0 }, |
// { INTEL_82443BX_0, 0 }, |
// { INTEL_82443GX_0, 0 }, |
// { INTEL_82810_MC1, 0 }, |
// { INTEL_82810_MC3, 0 }, |
// { INTEL_82810E_MC, 0 }, |
// { INTEL_82815_MC, 0 }, |
// { INTEL_82820_HB, 0 }, |
// { INTEL_82820_UP_HB,0 }, |
// { INTEL_82830_HB, 0 }, |
// { INTEL_82840_HB, 0 }, |
// { INTEL_82845_HB, 0 }, |
// { INTEL_82845G_HB, 0 }, |
// { INTEL_82850_HB, 0 }, |
// { INTEL_82855PM_HB, 0 }, |
// { INTEL_82855GM_HB, 0 }, |
// { INTEL_82860_HB, 0 }, |
{ INTEL_82865_HB, 0 }, |
// { INTEL_82875_HB, 0 }, |
// { INTEL_7505_0, 0 }, |
// { INTEL_7205_0, 0 }, |
// { INTEL_82915G_HB, 0 }, |
// { INTEL_82915GM_HB, 0 }, |
// { INTEL_82945G_HB, 0 }, |
// { INTEL_82945GM_HB, 0 }, |
{ 0, 0 } |
}; |
pci_device_t* agp_dev_match(u32_t dev, pci_device_t *list) |
{ |
while(list->id) |
{ |
if(dev == list->id) |
return list; |
list++; |
} |
return NULL; |
} |
int FindPciDevice() |
{ |
u32_t bus, last_bus; |
PCITAG tag; |
if( (last_bus = PciApi(1))==-1) |
return 0; |
for(bus=0;bus<=last_bus;bus++) |
{ |
u32_t devfn; |
for(devfn=0;devfn<256;devfn++) |
{ |
u32_t pciId; |
u8_t devclass; |
pci_device_t *dev; |
pciId = PciRead32(bus,devfn, 0); |
devclass = PciRead8(bus,devfn, 0x0B); |
if( devclass != PCI_CLASS_BRIDGE_HOST) |
continue; |
if( (dev = agp_dev_match(pciId, agp_dev_table))!=NULL) |
{ |
dbgprintf("detect agp host %x\n",dev->id); |
PCITAG PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
return init_bridge(PciTag); |
}; |
}; |
}; |
return 0; |
}; |
/drivers/old/agp/isoch.inc |
---|
0,0 → 1,483 |
struct agp_3_5_dev |
{ |
link_t link; |
int capndx; |
u32_t maxbw; |
PCITAG tag; |
}; |
static inline list_insert_tail(link_t *new, link_t *old) |
{ |
new->prev = old; |
new->next = old->next; |
new->next->prev = new; |
old->next = new; |
} |
static void agp_3_5_dev_list_insert(link_t *head, link_t *new) |
{ |
struct agp_3_5_dev *cur, *n = (struct agp_3_5_dev*)new; |
link_t *pos = head->next; |
while(pos != head){ |
cur = (struct agp_3_5_dev*)pos; |
if(cur->maxbw > n->maxbw) |
break; |
} |
list_insert_tail(new, pos); |
} |
static void agp_3_5_dev_list_sort(link_t *list, unsigned int ndevs) |
{ |
struct agp_3_5_dev *cur; |
link_t *pos, *tmp, *start = list->next; |
u32_t nistat; |
list_initialize(list); |
for (pos = start; pos != list; ) |
{ |
PCITAG tag; |
cur = (struct agp_3_5_dev*)pos; |
tag = cur->tag; |
nistat = pciReadLong(tag, cur->capndx+AGPNISTAT); |
cur->maxbw = (nistat >> 16) & 0xff; |
tmp = pos; |
pos = pos->next; |
agp_3_5_dev_list_insert(list, tmp); |
} |
} |
/* |
* Initialize all isochronous transfer parameters for an AGP 3.0 |
* node (i.e. a host bridge in combination with the adapters |
* lying behind it...) |
*/ |
static int agp_3_5_isochronous_node_enable(agp_t *bridge, |
link_t *dev_list, unsigned int ndevs) |
{ |
/* |
* Convenience structure to make the calculations clearer |
* here. The field names come straight from the AGP 3.0 spec. |
*/ |
struct isoch_data { |
u32_t maxbw; |
u32_t n; |
u32_t y; |
u32_t l; |
u32_t rq; |
struct agp_3_5_dev *dev; |
}; |
PCITAG td = bridge->PciTag; |
// struct list_head *head = &dev_list->list, *pos; |
struct agp_3_5_dev *cur; |
struct isoch_data *master, target; |
unsigned int cdev = 0; |
u32_t mnistat, tnistat, tstatus, mcmd; |
u16_t tnicmd, mnicmd; |
u8_t mcapndx; |
u32_t tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async; |
u32_t step, rem, rem_isoch, rem_async; |
int ret = 0; |
/* |
* We'll work with an array of isoch_data's (one for each |
* device in dev_list) throughout this function. |
*/ |
if ((master = malloc(ndevs * sizeof(*master))) == NULL) { |
ret = -1; |
goto get_out; |
} |
/* |
* Sort the device list by maxbw. We need to do this because the |
* spec suggests that the devices with the smallest requirements |
* have their resources allocated first, with all remaining resources |
* falling to the device with the largest requirement. |
* |
* We don't exactly do this, we divide target resources by ndevs |
* and split them amongst the AGP 3.0 devices. The remainder of such |
* division operations are dropped on the last device, sort of like |
* the spec mentions it should be done. |
* |
* We can't do this sort when we initially construct the dev_list |
* because we don't know until this function whether isochronous |
* transfers are enabled and consequently whether maxbw will mean |
* anything. |
*/ |
agp_3_5_dev_list_sort(dev_list, ndevs); |
tnistat = pciReadLong(td, bridge->capndx+AGPNISTAT); |
tstatus = pciReadLong(td, bridge->capndx+AGPSTAT); |
/* Extract power-on defaults from the target */ |
target.maxbw = (tnistat >> 16) & 0xff; |
target.n = (tnistat >> 8) & 0xff; |
target.y = (tnistat >> 6) & 0x3; |
target.l = (tnistat >> 3) & 0x7; |
target.rq = (tstatus >> 24) & 0xff; |
y_max = target.y; |
/* |
* Extract power-on defaults for each device in dev_list. Along |
* the way, calculate the total isochronous bandwidth required |
* by these devices and the largest requested payload size. |
*/ |
link_t *pos; |
for (pos = dev_list->next; pos != dev_list; pos = pos->next ) |
{ |
PCITAG dev; |
cur = (struct agp_3_5_dev*)pos; |
dev = cur->tag; |
mcapndx = cur->capndx; |
mnistat = pciReadLong(dev, cur->capndx+AGPNISTAT); |
master[cdev].maxbw = (mnistat >> 16) & 0xff; |
master[cdev].n = (mnistat >> 8) & 0xff; |
master[cdev].y = (mnistat >> 6) & 0x3; |
master[cdev].dev = cur; |
tot_bw += master[cdev].maxbw; |
y_max = max(y_max, master[cdev].y); |
cdev++; |
} |
/* Check if this configuration has any chance of working */ |
if (tot_bw > target.maxbw) { |
dbgprintf("isochronous bandwidth required " |
"by AGP 3.0 devices exceeds that which is supported by " |
"the AGP 3.0 bridge!\n"); |
ret = -1; |
goto free_and_exit; |
} |
target.y = y_max; |
/* |
* Write the calculated payload size into the target's NICMD |
* register. Doing this directly effects the ISOCH_N value |
* in the target's NISTAT register, so we need to do this now |
* to get an accurate value for ISOCH_N later. |
*/ |
tnicmd = pciReadWord(td, bridge->capndx+AGPNICMD); |
tnicmd &= ~(0x3 << 6); |
tnicmd |= target.y << 6; |
pciWriteWord(td, bridge->capndx+AGPNICMD, tnicmd); |
/* Reread the target's ISOCH_N */ |
tnistat = pciReadLong(td, bridge->capndx+AGPNISTAT); |
target.n = (tnistat >> 8) & 0xff; |
/* Calculate the minimum ISOCH_N needed by each master */ |
for (cdev=0; cdev<ndevs; cdev++) { |
master[cdev].y = target.y; |
master[cdev].n = master[cdev].maxbw / (master[cdev].y + 1); |
tot_n += master[cdev].n; |
} |
/* Exit if the minimal ISOCH_N allocation among the masters is more |
* than the target can handle. */ |
if (tot_n > target.n) { |
dbgprintf("number of isochronous " |
"transactions per period required by AGP 3.0 devices " |
"exceeds that which is supported by the AGP 3.0 " |
"bridge!\n"); |
ret = -1; |
goto free_and_exit; |
} |
/* Calculate left over ISOCH_N capability in the target. We'll give |
* this to the hungriest device (as per the spec) */ |
rem = target.n - tot_n; |
/* |
* Calculate the minimum isochronous RQ depth needed by each master. |
* Along the way, distribute the extra ISOCH_N capability calculated |
* above. |
*/ |
for (cdev=0; cdev<ndevs; cdev++) { |
/* |
* This is a little subtle. If ISOCH_Y > 64B, then ISOCH_Y |
* byte isochronous writes will be broken into 64B pieces. |
* This means we need to budget more RQ depth to account for |
* these kind of writes (each isochronous write is actually |
* many writes on the AGP bus). |
*/ |
master[cdev].rq = master[cdev].n; |
if(master[cdev].y > 0x1) |
master[cdev].rq *= (1 << (master[cdev].y - 1)); |
tot_rq += master[cdev].rq; |
} |
master[ndevs-1].n += rem; |
/* Figure the number of isochronous and asynchronous RQ slots the |
* target is providing. */ |
rq_isoch = (target.y > 0x1) ? target.n * (1 << (target.y - 1)) : target.n; |
rq_async = target.rq - rq_isoch; |
/* Exit if the minimal RQ needs of the masters exceeds what the target |
* can provide. */ |
if (tot_rq > rq_isoch) { |
dbgprintf("number of request queue slots " |
"required by the isochronous bandwidth requested by " |
"AGP 3.0 devices exceeds the number provided by the " |
"AGP 3.0 bridge!\n"); |
ret = -1; |
goto free_and_exit; |
} |
/* Calculate asynchronous RQ capability in the target (per master) as |
* well as the total number of leftover isochronous RQ slots. */ |
step = rq_async / ndevs; |
rem_async = step + (rq_async % ndevs); |
rem_isoch = rq_isoch - tot_rq; |
/* Distribute the extra RQ slots calculated above and write our |
* isochronous settings out to the actual devices. */ |
for (cdev=0; cdev<ndevs; cdev++) |
{ |
PCITAG dev; |
cur = master[cdev].dev; |
dev = cur->tag; |
mcapndx = cur->capndx; |
master[cdev].rq += (cdev == ndevs - 1) |
? (rem_async + rem_isoch) : step; |
mnicmd = pciReadWord(dev, cur->capndx+AGPNICMD); |
mcmd = pciReadLong(dev, cur->capndx+AGPCMD); |
mnicmd &= ~(0xff << 8); |
mnicmd &= ~(0x3 << 6); |
mcmd &= ~(0xff << 24); |
mnicmd |= master[cdev].n << 8; |
mnicmd |= master[cdev].y << 6; |
mcmd |= master[cdev].rq << 24; |
pciWriteLong(dev, cur->capndx+AGPCMD, mcmd); |
pciWriteWord(dev, cur->capndx+AGPNICMD, mnicmd); |
} |
free_and_exit: |
free(master); |
get_out: |
return ret; |
} |
/* |
* This function basically allocates request queue slots among the |
* AGP 3.0 systems in nonisochronous nodes. The algorithm is |
* pretty stupid, divide the total number of RQ slots provided by the |
* target by ndevs. Distribute this many slots to each AGP 3.0 device, |
* giving any left over slots to the last device in dev_list. |
*/ |
static void agp_3_5_nonisochronous_node_enable(agp_t *bridge, |
link_t *dev_list, unsigned int ndevs) |
{ |
struct agp_3_5_dev *cur; |
u32_t tstatus, mcmd; |
u32_t trq, mrq, rem; |
unsigned int cdev = 0; |
tstatus = pciReadLong(bridge->PciTag, bridge->capndx+AGPSTAT); |
trq = (tstatus >> 24) & 0xff; |
mrq = trq / ndevs; |
rem = mrq + (trq % ndevs); |
link_t *pos; |
for (pos = dev_list->next; cdev<ndevs; cdev++, pos=pos->next) { |
cur = (struct agp_3_5_dev*)pos; |
mcmd = pciReadLong(cur->tag, cur->capndx+AGPCMD); |
mcmd &= ~(0xff << 24); |
mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24; |
pciWriteLong(cur->tag, cur->capndx+AGPCMD, mcmd); |
} |
} |
/* |
* Fully configure and enable an AGP 3.0 host bridge and all the devices |
* lying behind it. |
*/ |
int agp_3_5_enable(agp_t *bridge) |
{ |
u8_t mcapndx; |
u32_t isoch, arqsz; |
u32_t tstatus, mstatus, ncapid; |
u32_t mmajor; |
u16_t mpstat; |
link_t dev_list; |
struct agp_3_5_dev *cur, *pos; |
unsigned int ndevs = 0; |
PCITAG dev = 0; |
int ret = 0; |
/* Extract some power-on defaults from the target */ |
tstatus = pciReadLong(bridge->PciTag, bridge->capndx+AGPSTAT); |
isoch = (tstatus >> 17) & 0x1; |
if (isoch == 0) /* isoch xfers not available, bail out. */ |
return -1; |
arqsz = (tstatus >> 13) & 0x7; |
list_initialize(&dev_list); |
/* Find all AGP devices, and add them to dev_list. */ |
for_each_pci_dev(dev) |
{ |
u16_t devclass; |
mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP); |
if (mcapndx == 0) |
continue; |
devclass = pciReadWord(dev, 0x0A); |
switch (devclass & 0xff00) |
{ |
case 0x0600: /* Bridge */ |
/* Skip bridges. We should call this function for each one. */ |
continue; |
case 0x0001: /* Unclassified device */ |
/* Don't know what this is, but log it for investigation. */ |
if (mcapndx != 0) { |
dbgprintf("Wacky, found unclassified AGP device.\n"); |
} |
continue; |
case 0x0300: /* Display controller */ |
case 0x0400: /* Multimedia controller */ |
if((cur = malloc(sizeof(*cur))) == NULL) |
{ |
ret = -1; |
goto free_and_exit; |
} |
cur->tag = dev; |
list_prepend(&cur->link, &dev_list); |
ndevs++; |
continue; |
default: |
continue; |
} |
} |
/* |
* Take an initial pass through the devices lying behind our host |
* bridge. Make sure each one is actually an AGP 3.0 device, otherwise |
* exit with an error message. Along the way store the AGP 3.0 |
* cap_ptr for each device |
*/ |
cur = (struct agp_3_5_dev*)dev_list.next; |
while(&cur->link != &dev_list) |
{ |
dev = cur->tag; |
mpstat = pciReadWord(dev, PCI_STATUS); |
if ((mpstat & PCI_STATUS_CAP_LIST) == 0) |
continue; |
mcapndx = pciReadByte(dev, PCI_CAPABILITY_LIST); |
if (mcapndx != 0) { |
do { |
ncapid = pciReadLong(dev, mcapndx); |
if ((ncapid & 0xff) != 2) |
mcapndx = (ncapid >> 8) & 0xff; |
} |
while (((ncapid & 0xff) != 2) && (mcapndx != 0)); |
} |
if (mcapndx == 0) { |
dbgprintf("woah! Non-AGP device " |
"found on the secondary bus of an AGP 3.5 bridge!\n"); |
ret = -1; |
goto free_and_exit; |
} |
mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; |
if (mmajor < 3) { |
dbgprintf("woah! AGP 2.0 device " |
"found on the secondary bus of an AGP 3.5 " |
"bridge operating with AGP 3.0 electricals!\n"); |
ret = -1; |
goto free_and_exit; |
} |
cur->capndx = mcapndx; |
mstatus = pciReadLong(dev, cur->capndx+AGPSTAT); |
if (((mstatus >> 3) & 0x1) == 0) { |
dbgprintf("woah! AGP 3.x device " |
"not operating in AGP 3.x mode found on the " |
"secondary bus of an AGP 3.5 bridge operating " |
"with AGP 3.0 electricals!\n"); |
ret = -1; |
goto free_and_exit; |
} |
cur = (struct agp_3_5_dev*)cur->link.next; |
} |
/* |
* Call functions to divide target resources amongst the AGP 3.0 |
* masters. This process is dramatically different depending on |
* whether isochronous transfers are supported. |
*/ |
if (isoch) { |
ret = agp_3_5_isochronous_node_enable(bridge, &dev_list, ndevs); |
if (ret) { |
dbgprintf("Something bad happened setting " |
"up isochronous xfers. Falling back to " |
"non-isochronous xfer mode.\n"); |
} else { |
goto free_and_exit; |
} |
} |
agp_3_5_nonisochronous_node_enable(bridge, &dev_list, ndevs); |
free_and_exit: |
/* Be sure to free the dev_list */ |
for (pos = (struct agp_3_5_dev*)dev_list.next; &pos->link != &dev_list; ) |
{ |
cur = pos; |
pos = (struct agp_3_5_dev*)pos->link.next; |
free(cur); |
} |
get_out: |
return ret; |
} |
/drivers/old/agp/link.h |
---|
0,0 → 1,60 |
typedef struct link |
{ |
struct link *prev; |
struct link *next; |
}link_t; |
#define LIST_INITIALIZE(name) \ |
link_t name = { .prev = &name, .next = &name } |
#define list_get_instance(link, type, member) \ |
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member)))) |
static inline void link_initialize(link_t *link) |
{ |
link->prev = NULL; |
link->next = NULL; |
} |
static inline void list_initialize(link_t *head) |
{ |
head->prev = head; |
head->next = head; |
} |
static inline void list_append(link_t *link, link_t *head) |
{ |
link->prev = head->prev; |
link->next = head; |
head->prev->next = link; |
head->prev = link; |
} |
static inline void list_remove(link_t *link) |
{ |
link->next->prev = link->prev; |
link->prev->next = link->next; |
link_initialize(link); |
} |
static inline Bool list_empty(link_t *head) |
{ |
return head->next == head ? TRUE : FALSE; |
} |
static inline void list_prepend(link_t *link, link_t *head) |
{ |
link->next = head->next; |
link->prev = head; |
head->next->prev = link; |
head->next = link; |
} |
static inline list_insert(link_t *new, link_t *old) |
{ |
new->prev = old->prev; |
new->next = old; |
new->prev->next = new; |
old->prev = new; |
} |
/drivers/old/agp/makefile |
---|
0,0 → 1,32 |
CC = gcc |
FASM = e:/fasm/fasm.exe |
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf |
LDRHD = -shared -T ld.x -s --file-alignment 32 |
INCLUDES = -I ../../include |
HFILES:= ../../include/types.h \ |
../../include/syscall.h \ |
agp.h |
SRC_DEP:= pci.inc \ |
detect.inc \ |
isoch.inc |
AGP_SRC:= agp.c |
AGP = agp.dll |
all: $(AGP) |
$(AGP): agp.obj $(SRC_DEP) $(HFILES) Makefile |
wlink name agp.dll SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @agp.lk |
kpack.exe agp.dll agp.drv |
agp.obj : agp.c $(SRC_DEP) $(HFILES) Makefile |
$(CC) $(INCLUDES) $(CFLAGS) -o agp.obj agp.c |
/drivers/old/agp/pci.inc |
---|
0,0 → 1,128 |
#define PCI_FIND_CAP_TTL 48 |
static int __pci_find_next_cap_ttl(PCITAG pciTag, u8_t pos, |
int cap, int *ttl) |
{ |
u8_t id; |
while ((*ttl)--) |
{ |
pos = pciReadByte(pciTag, pos); |
if (pos < 0x40) |
break; |
pos &= ~3; |
id = pciReadByte(pciTag, pos + PCI_CAP_LIST_ID); |
if (id == 0xff) |
break; |
if (id == cap) |
return pos; |
pos += PCI_CAP_LIST_NEXT; |
} |
return 0; |
} |
static int __pci_find_next_cap(PCITAG pciTag, u8_t pos, int cap) |
{ |
int ttl = PCI_FIND_CAP_TTL; |
return __pci_find_next_cap_ttl(pciTag, pos, cap, &ttl); |
} |
static int __pci_bus_find_cap_start(PCITAG pciTag) |
{ |
u16_t status; |
u8_t hdr_type; |
status = pciReadWord(pciTag, PCI_STATUS); |
if (!(status & PCI_STATUS_CAP_LIST)) |
return 0; |
hdr_type = pciReadByte(pciTag, 0x0E); |
switch (hdr_type) |
{ |
case PCI_HEADER_TYPE_NORMAL: |
case PCI_HEADER_TYPE_BRIDGE: |
return PCI_CAPABILITY_LIST; |
case PCI_HEADER_TYPE_CARDBUS: |
return PCI_CB_CAPABILITY_LIST; |
default: |
return 0; |
} |
return 0; |
} |
int pci_find_capability(PCITAG pciTag, int cap) |
{ |
int pos; |
pos = __pci_bus_find_cap_start(pciTag); |
if (pos) |
pos = __pci_find_next_cap(pciTag, pos, cap); |
return pos; |
} |
PCITAG pci_find_class(u16_t class) |
{ |
u32_t bus, last_bus; |
PCITAG tag; |
if( (last_bus = PciApi(1))==-1) |
return -1; |
for(bus=0;bus<=last_bus;bus++) |
{ |
u32_t devfn; |
for(devfn=0;devfn<256;devfn++) |
{ |
u16_t devclass; |
devclass = PciRead16(bus,devfn, 0x0A); |
if( devclass != class) |
continue; |
return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
}; |
}; |
return -1; |
}; |
PCITAG pci_get_device(u32_t vendor, u32_t device, PCITAG from) |
{ |
u32_t bus, last_bus; |
u32_t devfn; |
if( (last_bus = PciApi(1))==-1) |
return -1; |
bus = PCI_BUS_FROM_TAG(from); |
devfn = PCI_DFN_FROM_TAG(from); |
devfn++; |
for(;bus<=last_bus; bus++) |
{ |
for(;devfn < 256;devfn++) |
{ |
u32_t tmp; |
u32_t dev_vendor; |
u32_t dev_id; |
tmp = PciRead32(bus,devfn, 0); |
dev_vendor = (u16_t)tmp; |
dev_id = tmp >> 16; |
if ((vendor == PCI_ANY_ID || dev_vendor == vendor)) |
return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
}; |
}; |
return -1; |
} |
/drivers/old/agp/syscall.h |
---|
0,0 → 1,257 |
#define OS_BASE 0x80000000 |
typedef struct |
{ |
u32_t handle; |
u32_t io_code; |
void *input; |
int inp_size; |
void *output; |
int out_size; |
}ioctl_t; |
typedef int (__stdcall *srv_proc_t)(ioctl_t *); |
#define ERR_OK 0 |
#define ERR_PARAM -1 |
u32_t __stdcall drvEntry(int)__asm__("_drvEntry"); |
/////////////////////////////////////////////////////////////////////////////// |
#define STDCALL __attribute__ ((stdcall)) __attribute__ ((dllimport)) |
#define IMPORT __attribute__ ((dllimport)) |
/////////////////////////////////////////////////////////////////////////////// |
#define SysMsgBoardStr __SysMsgBoardStr |
#define PciApi __PciApi |
//#define RegService __RegService |
#define CreateObject __CreateObject |
#define DestroyObject __DestroyObject |
/////////////////////////////////////////////////////////////////////////////// |
#define PG_SW 0x003 |
#define PG_NOCACHE 0x018 |
void* STDCALL AllocKernelSpace(size_t size)__asm__("AllocKernelSpace"); |
void* STDCALL KernelAlloc(size_t size)__asm__("KernelAlloc"); |
void* STDCALL KernelFree(void *mem)__asm__("KernelFree"); |
void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc"); |
int STDCALL UserFree(void *mem)__asm__("UserFree"); |
addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages"); |
void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer"); |
u32_t STDCALL RegService(char *name, srv_proc_t proc)__asm__("RegService"); |
//void *CreateObject(u32 pid, size_t size); |
//void *DestroyObject(void *obj); |
addr_t STDCALL MapIoMem(void* base,size_t size,u32_t flags)__asm__("MapIoMem"); |
/////////////////////////////////////////////////////////////////////////////// |
static u32_t PciApi(int cmd); |
u8_t STDCALL PciRead8 (u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead8"); |
u16_t STDCALL PciRead16(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead16"); |
u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32"); |
u32_t STDCALL PciWrite8 (u32_t bus, u32_t devfn, u32_t reg,u8_t val) __asm__("PciWrite8"); |
u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16"); |
u32_t STDCALL PciWrite32(u32_t bus, u32_t devfn, u32_t reg,u32_t val)__asm__("PciWrite32"); |
#define pciReadByte(tag, reg) \ |
PciRead8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg)) |
#define pciReadWord(tag, reg) \ |
PciRead16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg)) |
#define pciReadLong(tag, reg) \ |
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg)) |
#define pciWriteByte(tag, reg, val) \ |
PciWrite8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val)) |
#define pciWriteWord(tag, reg, val) \ |
PciWrite16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val)) |
#define pciWriteLong(tag, reg, val) \ |
PciWrite32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val)) |
/////////////////////////////////////////////////////////////////////////////// |
int dbg_open(char *path); |
int dbgprintf(const char* format, ...); |
/////////////////////////////////////////////////////////////////////////////// |
extern inline int GetScreenSize() |
{ |
int retval; |
asm("int $0x40" |
:"=a"(retval) |
:"a"(61), "b"(1)); |
return retval; |
} |
extern inline int GetScreenBpp() |
{ |
int retval; |
asm("int $0x40" |
:"=a"(retval) |
:"a"(61), "b"(2)); |
return retval; |
} |
extern inline int GetScreenPitch() |
{ |
int retval; |
asm("int $0x40" |
:"=a"(retval) |
:"a"(61), "b"(3)); |
return retval; |
} |
extern inline u32_t GetPgAddr(void *mem) |
{ |
u32_t retval; |
__asm__ __volatile__ ( |
"call *__imp__GetPgAddr \n\t" |
:"=eax" (retval) |
:"a" (mem) ); |
return retval; |
}; |
extern inline void CommitPages(void *mem, u32_t page, u32_t size) |
{ |
size = (size+4095) & ~4095; |
__asm__ __volatile__ ( |
"call *__imp__CommitPages" |
::"a" (page), "b"(mem),"c"(size>>12) |
:"edx" ); |
__asm__ __volatile__ ("":::"eax","ebx","ecx"); |
}; |
extern inline void UnmapPages(void *mem, size_t size) |
{ |
size = (size+4095) & ~4095; |
__asm__ __volatile__ ( |
"call *__imp__UnmapPages" |
::"a" (mem), "c"(size>>12) |
:"edx"); |
__asm__ __volatile__ ("":::"eax","ecx"); |
}; |
extern inline void usleep(u32_t delay) |
{ |
if( !delay ) |
delay++; |
delay*=2000; |
__asm__ __volatile__ ( |
"1:\n\t" |
"xorl %%eax, %%eax \n\t" |
"cpuid \n\t" |
"decl %%edi \n\t" |
"jnz 1b" |
: |
:"D"(delay) |
:"eax","ebx","ecx","edx"); |
}; |
extern inline u32_t __PciApi(int cmd) |
{ |
u32_t retval; |
__asm__ __volatile__ ( |
"call *__imp__PciApi" |
:"=a" (retval) |
:"a" (cmd) |
:"memory"); |
return retval; |
}; |
extern inline void* __CreateObject(u32_t pid, size_t size) |
{ |
void *retval; |
__asm__ __volatile__ ( |
"call *__imp__CreateObject \n\t" |
:"=a" (retval) |
:"a" (size),"b"(pid) |
:"esi","edi", "memory"); |
return retval; |
} |
extern inline void *__DestroyObject(void *obj) |
{ |
__asm__ __volatile__ ( |
"call *__imp__DestroyObject" |
: |
:"a" (obj) |
:"ebx","edx","esi","edi", "memory"); |
} |
/* |
u32 __RegService(char *name, srv_proc_t proc) |
{ |
u32 retval; |
asm __volatile__ |
( |
"pushl %%eax \n\t" |
"pushl %%ebx \n\t" |
"call *__imp__RegService \n\t" |
:"=eax" (retval) |
:"a" (proc), "b" (name) |
:"memory" |
); |
return retval; |
}; |
*/ |
extern inline u32_t safe_cli(void) |
{ |
u32_t ifl; |
__asm__ __volatile__ ( |
"pushf\n\t" |
"popl %0\n\t" |
"cli\n" |
: "=r" (ifl)); |
return ifl; |
} |
extern inline void safe_sti(u32_t ifl) |
{ |
__asm__ __volatile__ ( |
"pushl %0\n\t" |
"popf\n" |
: : "r" (ifl) |
); |
} |
extern inline void __clear (void * dst, unsigned len) |
{ |
u32_t tmp; |
__asm__ __volatile__ ( |
// "xorl %%eax, %%eax \n\t" |
"cld \n\t" |
"rep stosb \n" |
:"=c"(tmp),"=D"(tmp) |
:"a"(0),"c"(len),"D"(dst)); |
__asm__ __volatile__ ("":::"ecx","edi"); |
}; |
/drivers/old/agp/types.h |
---|
0,0 → 1,44 |
#define NULL (void*)0 |
typedef unsigned char u8_t; |
typedef unsigned short int u16_t; |
typedef unsigned int u32_t; |
typedef unsigned long long u64_t; |
typedef unsigned int addr_t; |
typedef unsigned int size_t; |
typedef unsigned int count_t; |
typedef unsigned int eflags_t; |
typedef unsigned int Bool; |
#define TRUE (Bool)1 |
#define FALSE (Bool)0 |
/* |
* min()/max() macros that also do |
* strict type-checking.. See the |
* "unnecessary" pointer comparison. |
*/ |
#define min(x,y) ({ \ |
typeof(x) _x = (x); \ |
typeof(y) _y = (y); \ |
(void) (&_x == &_y); \ |
_x < _y ? _x : _y; }) |
#define max(x,y) ({ \ |
typeof(x) _x = (x); \ |
typeof(y) _y = (y); \ |
(void) (&_x == &_y); \ |
_x > _y ? _x : _y; }) |
#define min_t(type,x,y) \ |
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) |
#define max_t(type,x,y) \ |
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) |
/drivers/video/agp/agp.lk |
---|
File deleted |
/drivers/video/agp/agp.h |
---|
File deleted |
/drivers/video/agp/makefile |
---|
File deleted |
/drivers/video/agp/isoch.inc |
---|
File deleted |
/drivers/video/agp/detect.inc |
---|
File deleted |
/drivers/video/agp/syscall.h |
---|
File deleted |
/drivers/video/agp/link.h |
---|
File deleted |
/drivers/video/agp/pci.inc |
---|
File deleted |
/drivers/video/agp/agp.c |
---|
File deleted |
/drivers/video/agp/types.h |
---|
File deleted |