pci: Allow for PCI addresses to be 64-bit
PATCH v2 1/1 pci: Allow for PCI addresses to be 64-bit
PCI bus is inherently 64-bit. While not all system require access to the full 64-bit PCI address range some do. This allows those systems to enable the full PCI address width via CONFIG_SYS_PCI_64BIT.
---
Fixed up all the other bits associated with 64-bit PCI support.
- k
drivers/pci/pci.c | 37 ++++++++++++++++++-------- drivers/pci/pci_auto.c | 67 +++++++++++++++++++++++++++++------------------ include/pci.h | 40 +++++++++++++++++----------- 3 files changed, 91 insertions(+), 53 deletions(-)
drivers/pci/pci.c +26 -11
@@ -218,12 +218,12 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)* */ -unsigned long pci_hose_phys_to_bus (struct pci_controller *hose, +pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,phys_addr_t phys_addr,unsigned long flags) {struct pci_region *res; -unsigned long bus_addr; +pci_addr_t bus_addr;int i;if (!hose) {
@@ -252,7 +252,7 @@ Done: }phys_addr_t pci_hose_bus_to_phys (struct pci_controller * hose, -unsigned long bus_addr, +pci_addr_t bus_addr,unsigned long flags) {struct pci_region *res;
@@ -288,15 +288,17 @@ Done:int pci_hose_config_device (struct pci_controller *hose,pci_dev_t dev,unsigned long io, -unsigned long mem, +pci_addr_t mem,unsigned long command) { -unsigned int bar_response, bar_size, bar_value, old_command; +unsigned int bar_response, old_command; +pci_addr_t bar_value; +pci_size_t bar_size;unsigned char pin;int bar, found_mem64; -debug ("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n" , - io, mem, command); +debug ("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n" , + io, (u64 )mem, command);pci_hose_write_config_dword (hose, dev,PCI_COMMAND ,0 );
@@ -319,10 +321,19 @@ int pci_hose_config_device(struct pci_controller *hose, io = io + bar_size; }else {if ((bar_response &PCI_BASE_ADDRESS_MEM_TYPE_MASK ) == -PCI_BASE_ADDRESS_MEM_TYPE_64 ) - found_mem64 =1 ; +PCI_BASE_ADDRESS_MEM_TYPE_64 ) { +u32 bar_response_upper; +u64 bar64; +pci_hose_write_config_dword (hose, dev, bar+4 ,0xffffffff ); +pci_hose_read_config_dword (hose, dev, bar+4 , &bar_response_upper); - bar_size = ~(bar_response &PCI_BASE_ADDRESS_MEM_MASK ) +1 ; + bar64 = ((u64 )bar_response_upper <<32 ) | bar_response; + + bar_size = ~(bar64 &PCI_BASE_ADDRESS_MEM_MASK ) +1 ; + found_mem64 =1 ; + }else { + bar_size = (u32)(~(bar_response &PCI_BASE_ADDRESS_MEM_MASK ) +1 ); + }/* round up region base address to multiple of size */ mem = ((mem -1 ) | (bar_size -1 )) +1 ;
@@ -332,11 +343,15 @@ int pci_hose_config_device(struct pci_controller *hose, }/* Write it out and update our limit */ -pci_hose_write_config_dword (hose, dev, bar, bar_value); +pci_hose_write_config_dword (hose, dev, bar, (u32 )bar_value);if (found_mem64) { bar +=4 ; +#ifdef CONFIG_SYS_PCI_64BIT +pci_hose_write_config_dword (hose, dev, bar, bar_value>>32 ); +#else pci_hose_write_config_dword (hose, dev, bar,0x00000000 ); +#endif } }
drivers/pci/pci_auto.c +41 -26
138 lines not on this page · raw message
include/pci.h +24 -16
@@ -101,8 +101,8 @@#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02/* Below 1M [obsolete] */ #define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04/* 64 bit address */ #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08/* prefetchable? */ -#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) -#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03ULL)/* bit 1 is reserved if address_space = 1 */ /* Header type 0 (normal devices) */
@@ -111,7 +111,7 @@#define PCI_SUBSYSTEM_ID 0x2e#define PCI_ROM_ADDRESS 0x30/* Bits 31..11 are address, 10..1 reserved */ #define PCI_ROM_ADDRESS_ENABLE 0x01 -#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) +#define PCI_ROM_ADDRESS_MASK (~0x7ffULL)#define PCI_CAPABILITY_LIST 0x34/* Offset of first capability list entry */
@@ -312,13 +312,21 @@#include <pci_ids.h> +#ifdef CONFIG_SYS_PCI_64BIT +typedef u64 pci_addr_t ; +typedef u64 pci_size_t ; +#else +typedef u32 pci_addr_t ; +typedef u32 pci_size_t ; +#endif +struct pci_region { -unsigned long bus_start;/* Start on the bus */ -phys_addr_t phys_start;/* Start in physical address space */ -unsigned long size;/* Size */ -unsigned long flags;/* Resource flags */ +pci_addr_t bus_start;/* Start on the bus */ +phys_addr_t phys_start;/* Start in physical address space */ +pci_size_t size;/* Size */ +unsigned long flags;/* Resource flags */ -unsigned long bus_lower; +pci_addr_t bus_lower; };#define PCI_REGION_MEM 0x00000000/* PCI memory space */
@@ -330,9 +338,9 @@ struct pci_region {#define PCI_REGION_RO 0x00000200/* Read-only memory */ extern __inline__void pci_set_region (struct pci_region *reg, -unsigned long bus_start, +pci_addr_t bus_start,phys_addr_t phys_start, -unsigned long size, +pci_size_t size,unsigned long flags) { reg->bus_start = bus_start; reg->phys_start = phys_start;
@@ -433,9 +441,9 @@ extern __inline__ void pci_set_ops(struct pci_controller *hose,extern void pci_setup_indirect (struct pci_controller * hose,u32 cfg_addr,u32 cfg_data);extern phys_addr_t pci_hose_bus_to_phys (struct pci_controller * hose, -unsigned long addr,unsigned long flags); -extern unsigned long pci_hose_phys_to_bus (struct pci_controller * hose, -phys_addr_t addr,unsigned long flags); +pci_addr_t addr,unsigned long flags); +extern pci_addr_t pci_hose_phys_to_bus (struct pci_controller * hose, +phys_addr_t addr,unsigned long flags);#define pci_phys_to_bus (dev, addr, flags) \ pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
@@ -483,8 +491,8 @@ extern int pci_hose_scan(struct pci_controller *hose);extern int pci_hose_scan_bus (struct pci_controller *hose,int bus);extern void pciauto_region_init (struct pci_region * res); -extern void pciauto_region_align (struct pci_region *res,unsigned long size); -extern int pciauto_region_allocate (struct pci_region * res,unsigned int size,unsigned int *bar); +extern void pciauto_region_align (struct pci_region *res,pci_size_t size); +extern int pciauto_region_allocate (struct pci_region * res,pci_size_t size,pci_addr_t *bar); extern void pciauto_setup_device(struct pci_controller *hose, pci_dev_t dev, int bars_num, struct pci_region *mem,
@@ -500,7 +508,7 @@ extern pci_dev_t pci_find_class(int wanted_class, int wanted_sub_code,extern int pci_hose_config_device (struct pci_controller *hose,pci_dev_t dev,unsigned long io, -unsigned long mem, +pci_addr_t mem,unsigned long command);#ifdef CONFIG_MPC824X
Signature · 1 line
1.5.5.1
PATCH v2 1/1 pci: Allow for PCI addresses to be 64-bit
Quoted 8 lines · Kumar Gala
PCI bus is inherently 64-bit. While not all system require access to the full 64-bit PCI address range some do. This allows those systems to enable the full PCI address width via
CONFIG_SYS_PCI_64BIT.Signed-off-by Kumar Gala <[email protected]>---
Fixed up all the other bits associated with 64-bit PCI support.
guess this is really v3, the next one that fixes some whitespace issues will be v4
- k
PATCH v2 1/1 pci: Allow for PCI addresses to be 64-bit
In reply to Kumar GalaQuoted 8 lines · Kumar Gala
PCI bus is inherently 64-bit. While not all system require access to the full 64-bit PCI address range some do. This allows those systems to enable the full PCI address width via
CONFIG_SYS_PCI_64BIT.Signed-off-by Kumar Gala <[email protected]>---
Fixed up all the other bits associated with 64-bit PCI support.
So, this is looking a bit more complete now :) A few minor comments inline.
-B
drivers/pci/pci.c
Quoted 15 lines
- k
drivers/pci/pci.c | 37 ++++++++++++++++++-------- drivers/pci/pci_auto.c | 67 ++++++++++++++++++++++++++++ +------------------ include/pci.h | 40 +++++++++++++++++----------- 3 files changed, 91 insertions(+), 53 deletions(-)drivers/pci/pci.c +0
-0
------snip--------
drivers/pci/pci.c int pci_hose_config_device(struct · line 330
Quoted 13 lines
drivers/pci/pci.c +5
-2@@ -319,10 +321,19 @@ int pci_hose_config_device(structpci_controller *hose, io = io + bar_size; }else {if ((bar_response &PCI_BASE_ADDRESS_MEM_TYPE_MASK ) == -PCI_BASE_ADDRESS_MEM_TYPE_64 ) - found_mem64 =1 ; +PCI_BASE_ADDRESS_MEM_TYPE_64 ) { +u32 bar_response_upper; +u64 bar64; +pci_hose_write_config_dword (hose, dev, bar+4 ,0xffffffff ); +pci_hose_read_config_dword (hose, dev, bar+4 , &bar_response_upper);
Fix alignment of code.
Quoted 18 lines
drivers/pci/pci.c +7
-1- bar_size = ~(bar_response &PCI_BASE_ADDRESS_MEM_MASK ) +1 ; + bar64 = ((u64 )bar_response_upper <<32 ) | bar_response; + + bar_size = ~(bar64 &PCI_BASE_ADDRESS_MEM_MASK ) +1 ; + found_mem64 =1 ; + }else { + bar_size = (u32)(~(bar_response &PCI_BASE_ADDRESS_MEM_MASK ) +1 ); + }/* round up region base address to multiple of size */ mem = ((mem - 1) | (bar_size - 1)) + 1;drivers/pci/pci.c +0
-0@@ -332,11 +343,15 @@ int pci_hose_config_device(struct pci_controller *hose, }
drivers/pci/pci.c int pci_hose_config_device(struct · line 354
Quoted 10 lines
drivers/pci/pci.c +3
-1/* Write it out and update our limit */ -pci_hose_write_config_dword (hose, dev, bar, bar_value); +pci_hose_write_config_dword (hose, dev, bar, (u32 )bar_value);if (found_mem64) { bar +=4 ; +#ifdef CONFIG_SYS_PCI_64BIT +pci_hose_write_config_dword (hose, dev, bar, bar_value>>32 );
spaces around ">>" ? Might want to cast the result to (u32) for consistency.
Quoted 38 lines
drivers/pci/pci.c +2
-0+#else pci_hose_write_config_dword (hose, dev, bar,0x00000000 ); +#endif } }drivers/pci/pci_auto.c +3
-3@@ -45,14 +45,14 @@ void pciauto_region_init(struct pci_region* res) res->bus_lower = res->bus_start ? res->bus_start :0x1000 ; } -void pciauto_region_align (struct pci_region *res,unsigned long size) +void pciauto_region_align (struct pci_region *res,pci_size_t size) { res->bus_lower = ((res->bus_lower -1 ) | (size -1 )) +1 ; } -int pciauto_region_allocate (struct pci_region * res,unsigned int size, unsigned int *bar) +int pciauto_region_allocate (struct pci_region * res,pci_size_t size,pci_addr_t *bar) { -unsigned long addr; +pci_addr_t addr;if (!res) { DEBUGF("No resource");drivers/pci/pci_auto.c +0
-0@@ -68,13 +68,13 @@ int pciauto_region_allocate(struct pci_region*res, unsigned int size, unsigned
res->bus_lower = addr + size;drivers/pci/pci_auto.c +1
-1-DEBUGF ("address=0x%lx bus_lower=%x" , addr, res->bus_lower); + DEBUGF("address=0x%llx bus_lower=%llx", (u64)addr, (u64)res-
Quoted 1 line
Quoted 1 line
bus_lower);
While you're changing this, can we add the "0x" to the bus_lower print?
Quoted 75 lines
*bar = addr; return 0;error:
drivers/pci/pci_auto.c +1
-1- *bar =0xffffffff ; + *bar = (pci_addr_t)-1 ;return -1; }drivers/pci/pci_auto.c +3
-1@@ -88,7 +88,9 @@ void pciauto_setup_device(struct pci_controller *hose, struct pci_region *prefetch, struct pci_region *io) { -unsigned int bar_value, bar_response, bar_size; +unsigned int bar_response; +pci_addr_t bar_value; +pci_size_t bar_size;unsigned int cmdstat =0 ;struct pci_region *bar_res;int bar, bar_nr = 0;drivers/pci/pci_auto.c +15
-11@@ -114,33 +116,46 @@ void pciauto_setup_device(struct pci_controller *hose, & 0xffff) + 1; bar_res = io; -DEBUGF ("PCI Autoconfig: BAR %d, I/O, size=0x%x, " , bar_nr, bar_size); +DEBUGF ("PCI Autoconfig: BAR %d, I/O, size=0x%llx, " , bar_nr, (u64 )bar_size); }else {if ( (bar_response &PCI_BASE_ADDRESS_MEM_TYPE_MASK ) == -PCI_BASE_ADDRESS_MEM_TYPE_64 ) - found_mem64 =1 ; +PCI_BASE_ADDRESS_MEM_TYPE_64 ) { +u32 bar_response_upper; +u64 bar64; +pci_hose_write_config_dword (hose, dev, bar+4 ,0xffffffff ); +pci_hose_read_config_dword (hose, dev, bar+4 , &bar_response_upper); + + bar64 = ((u64 )bar_response_upper <<32 ) | bar_response; - bar_size = ~(bar_response &PCI_BASE_ADDRESS_MEM_MASK ) +1 ; + bar_size = ~(bar64 &PCI_BASE_ADDRESS_MEM_MASK ) +1 ; + found_mem64 =1 ; + }else { + bar_size = (u32)(~(bar_response &PCI_BASE_ADDRESS_MEM_MASK ) +1 ); + }if (prefetch && (bar_response &PCI_BASE_ADDRESS_MEM_PREFETCH )) bar_res = prefetch;else bar_res = mem; -DEBUGF ("PCI Autoconfig: BAR %d, Mem, size=0x%x, " , bar_nr, bar_size); +DEBUGF ("PCI Autoconfig: BAR %d, Mem, size=0x%llx, " , bar_nr, (u64 )bar_size); }if (pciauto_region_allocate (bar_res, bar_size, &bar_value) ==0 ) {/* Write it out and update our limit */ -pci_hose_write_config_dword (hose, dev, bar, bar_value); +pci_hose_write_config_dword (hose, dev, bar, (u32 )bar_value); -/* -* If we are a 64-bit decoder then increment to the -* upper 32 bits of the bar and force it to locate -* in the lower 4GB of memory. -*/ if (found_mem64) { bar += 4;
drivers/pci/pci_auto.c
Quoted 2 lines
drivers/pci/pci_auto.c +2
-0+#ifdef CONFIG_SYS_PCI_64BIT +pci_hose_write_config_dword (hose, dev, bar, bar_value>>32 );
same as earlier.....
Quoted 26 lines
drivers/pci/pci_auto.c +6
-0+#else +/* +* If we are a 64-bit decoder then increment to the +* upper 32 bits of the bar and force it to locate +* in the lower 4GB of memory. +*/ pci_hose_write_config_dword(hose, dev, bar, 0x00000000); +#endif } cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?drivers/pci/pci_auto.c +3
-3@@ -289,10 +304,10 @@ void pciauto_config_init(struct pci_controller *hose)if (hose->pci_mem) {pciauto_region_init (hose->pci_mem); -DEBUGF ("PCI Autoconfig: Bus Memory region: [%lx-%lx],\n" +DEBUGF ("PCI Autoconfig: Bus Memory region: [%llx-%llx],\n" "\t\tPhysical Memory [%x-%x]\n" , - hose->pci_mem->bus_start, - hose->pci_mem->bus_start + hose->pci_mem->size -1 , + (u64 )hose->pci_mem->bus_start, + (u64)(hose->pci_mem->bus_start + hose->pci_mem->size -1 ), hose->pci_mem->phys_start, hose->pci_mem->phys_start + hose->pci_mem->size -1 );
Quoted 1 line
}
Don't the phys_start and size need to print as 64b? The region elements are defined as phys_addr_t and pci_size_t now. Also would prefer to see a "0x" prefix on those hex prints, since you're changing this anyway.
Quoted 15 lines
drivers/pci/pci_auto.c +3
-3@@ -300,10 +315,10 @@ void pciauto_config_init(struct pci_controller *hose)if (hose->pci_prefetch) {pciauto_region_init (hose->pci_prefetch); -DEBUGF ("PCI Autoconfig: Bus Prefetchable Mem: [%lx-%lx],\n" + DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [%llx-%llx],\n" "\t\tPhysical Memory [%x-%x]\n", - hose->pci_prefetch->bus_start, - hose->pci_prefetch->bus_start + hose->pci_prefetch->size -1 , + (u64)hose->pci_prefetch->bus_start, + (u64)(hose->pci_prefetch->bus_start + hose->pci_prefetch- >size - 1), hose->pci_prefetch->phys_start,
Quoted 2 lines
hose->pci_prefetch->phys_start + hose->pci_prefetch->size - 1);
64b prints of phys_start and size? "0x" prefix?
Quoted 5 lines
drivers/pci/pci_auto.c +0
-0@@ -312,10 +327,10 @@ void pciauto_config_init(struct pci_controller *hose)if (hose->pci_io) {pciauto_region_init (hose->pci_io);
drivers/pci/pci_auto.c void pciauto_config_init(struct pci_controller · line 336
Quoted 10 lines
drivers/pci/pci_auto.c +3
-3-DEBUGF ("PCI Autoconfig: Bus I/O region: [%lx-%lx],\n" +DEBUGF ("PCI Autoconfig: Bus I/O region: [%llx-%llx],\n" "\t\tPhysical Memory: [%x-%x]\n" , - hose->pci_io->bus_start, - hose->pci_io->bus_start + hose->pci_io->size -1 , + (u64 )hose->pci_io->bus_start, + (u64)(hose->pci_io->bus_start + hose->pci_io->size -1 ), hose->pci_io->phys_start, hose->pci_io->phys_start + hose->pci_io->size -1 );
phys_start/size should print as 64b? "0x" prefix?
Quoted 76 lines
include/pci.h +2
-2@@ -101,8 +101,8 @@#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02/* Below 1M [obsolete] */ #define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04/* 64 bit address */ #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08/* prefetchable? */ -#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) -#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03ULL)/* bit 1 is reserved if address_space = 1 */ /* Header type 0 (normal devices) */ @@ -111,7 +111,7 @@#define PCI_SUBSYSTEM_ID 0x2e#define PCI_ROM_ADDRESS 0x30/* Bits 31..11 are address, 10..1 reserved */
#definePCI_ROM_ADDRESS_ENABLE0x01include/pci.h +1
-1-#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) +#define PCI_ROM_ADDRESS_MASK (~0x7ffULL)#define
PCI_CAPABILITY_LIST0x34/* Offset of first capability list
entry */include/pci.h +15
-7@@ -312,13 +312,21 @@#include <pci_ids.h> +#ifdef CONFIG_SYS_PCI_64BIT +typedef u64 pci_addr_t ; +typedef u64 pci_size_t ; +#else +typedef u32 pci_addr_t ; +typedef u32 pci_size_t ; +#endif +struct pci_region { -unsigned long bus_start;/* Start on the bus */ -phys_addr_t phys_start;/* Start in physical address space */ -unsigned long size;/* Size */ -unsigned long flags;/* Resource flags */ +pci_addr_t bus_start;/* Start on the bus */ +phys_addr_t phys_start;/* Start in physical address space */ +pci_size_t size;/* Size */ +unsigned long flags;/* Resource flags */ -unsigned long bus_lower; +pci_addr_t bus_lower; };#define PCI_REGION_MEM 0x00000000/* PCI memory space */ @@ -330,9 +338,9 @@ struct pci_region {#define PCI_REGION_RO 0x00000200/* Read-only memory */ extern __inline__void pci_set_region (struct pci_region *reg, -unsigned long bus_start, +pci_addr_t bus_start,phys_addr_t phys_start, -unsigned long size, +pci_size_t size,unsigned long flags) { reg->bus_start = bus_start; reg->phys_start = phys_start;@@ -433,9 +441,9 @@ extern __inline__ void pci_set_ops(struct pci_controller *hose,extern void
pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);extern
phys_addr_tpci_hose_bus_to_phys(struct pci_controller* hose,include/pci.h +0
-2- unsigned long addr, unsigned long flags); -extern unsigned long pci_hose_phys_to_bus(struct pci_controller*hose,
include/pci.h extern __inline__ void pci_set_ops(struct pci_controller *hose, · line 444
Quoted 2 lines
include/pci.h +1
-1- phys_addr_t addr, unsigned long flags); + pci_addr_t addr, unsigned long flags);
check whitespace here
Quoted 34 lines
include/pci.h +2
-0+extern pci_addr_t pci_hose_phys_to_bus (struct pci_controller * hose, +phys_addr_t addr,unsigned long flags);#define pci_phys_to_bus(dev, addr, flags) \ pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))include/pci.h +1
-2@@ -483,8 +491,8 @@ extern int pci_hose_scan(struct pci_controller *hose);extern int pci_hose_scan_bus (struct pci_controller *hose,int bus);extern void pciauto_region_init (struct pci_region * res); -extern void pciauto_region_align (struct pci_region *res,unsigned long size); -extern int pciauto_region_allocate (struct pci_region * res,unsigned int size, unsigned int *bar); +extern void pciauto_region_align(struct pci_region *res, pci_size_tsize);
+extern intpciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar);
extern void pciauto_setup_device(structpci_controller*hose,
pci_dev_tdev, intbars_num, structpci_region*mem,include/pci.h +1
-1@@ -500,7 +508,7 @@ extern pci_dev_t pci_find_class(int wanted_class, int wanted_sub_code, extern int pci_hose_config_device(struct pci_controller *hose,pci_dev_t dev,unsigned long io, -unsigned long mem, +pci_addr_t mem,unsigned long command);#ifdef
CONFIG_MPC824XSignature · 1 line
1.5.5.1