[U-Boot] [PATCH 00/11] Allow PCI bus address, PA, and VA to differ

This patch series cleans up much of for VA/PA/PCI bus address confusion that is is currently causing a couple of problems on the 8641 36-bit port, and was preventing us from having a PCI mem bus address that differed from the virtual address of the region.
I have fixed a number of problems, from the ahci driver directly using the pci BAR setting as a virtual address, to the CFI flash driver inconsistently treating flash_info->start as a physical address or virtual address, to pci window mapping overlap.
We also now require support for Kumar's new CONFIG_ADDR_MAP code, which I have added - his patches will need to be applied before these; some of these patches are actually fixes to that code. I ended up doing some cleanup to the BAT defines as I was implementing this capability.
Here's the diffstat: board/alaska/alaska.c | 36 +++++++------- board/etin/debris/flash.c | 1 + board/etin/kvme080/kvme080.c | 1 + board/freescale/mpc8641hpcn/mpc8641hpcn.c | 22 ++++---- cpu/mpc85xx/tlb.c | 4 +- cpu/mpc86xx/cpu_init.c | 27 +++++++++++ drivers/block/ahci.c | 7 +-- drivers/mtd/cfi_flash.c | 53 +++++++++----------- drivers/pci/pci.c | 19 ++++++++ include/74xx_7xx.h | 37 --------------- include/addr_map.h | 2 +- include/asm-ppc/e300.h | 35 -------------- include/asm-ppc/io.h | 2 +- include/asm-ppc/mmu.h | 73 ++++++++++++++++++++++------ include/configs/MPC8641HPCN.h | 30 +++++++++--- include/flash.h | 2 +- include/mpc824x.h | 39 --------------- include/mpc86xx.h | 41 ---------------- include/pci.h | 28 +++++++++-- lib_generic/addr_map.c | 4 +- lib_ppc/bat_rw.c | 28 +++++++++++ lib_ppc/board.c | 2 +- 22 files changed, 243 insertions(+), 250 deletions(-)
I am submitting this as a series, because these are required, in this order, for MPC8641HPCN to continue to build and boot. I am aware that I've changed files that belong to a number of maintainers; I'm not sure how we want to handle this.
Cheers, Becky

Casting a pointer to a phys_addr_t when it's an unsigned long long on a 32-bit system without first casting to a non-pointer type generates a compiler warning. Fix this.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- include/asm-ppc/io.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index a8003ef..4ddad26 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -311,7 +311,7 @@ static inline phys_addr_t virt_to_phys(void * vaddr) #ifdef CONFIG_ADDR_MAP return addrmap_virt_to_phys(vaddr); #else - return (phys_addr_t)(vaddr); + return (phys_addr_t)((unsigned long)vaddr); #endif }

Dear Becky Bruce,
In message 1228367087-27268-2-git-send-email-beckyb@kernel.crashing.org you wrote:
Casting a pointer to a phys_addr_t when it's an unsigned long long on a 32-bit system without first casting to a non-pointer type generates a compiler warning. Fix this.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
include/asm-ppc/io.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk

In message 20081216155539.6345F832E8A1@gemini.denx.de I wrote:
In message 1228367087-27268-2-git-send-email-beckyb@kernel.crashing.org you wrote:
Casting a pointer to a phys_addr_t when it's an unsigned long long on a 32-bit system without first casting to a non-pointer type generates a compiler warning. Fix this.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
include/asm-ppc/io.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
Applied, thanks.
Unfortunately this leaves problems on some MIPS based systems:
... au1x00_eth.c: In function 'au1x00_send': au1x00_eth.c:158: warning: passing argument 1 of 'virt_to_phys' discards qualifiers from pointer target type au1x00_eth.c: In function 'au1x00_recv': au1x00_eth.c:211: warning: passing argument 1 of 'virt_to_phys' discards qualifiers from pointer target type au1x00_eth.c: In function 'au1x00_init': au1x00_eth.c:252: warning: passing argument 1 of 'virt_to_phys' discards qualifiers from pointer target type
(for dbau1000, dbau1100, dbau1500, dbau1550, dbau1550_el and gth2)
Best regards,
Wolfgang Denk

Because the inbound pci windows are mapped generously, set up the more specific outbound windows first. This way, when we search the pci regions for something, we will hit on the more specific region. This can actually be a problem on systems with large amounts of RAM.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- board/freescale/mpc8641hpcn/mpc8641hpcn.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/board/freescale/mpc8641hpcn/mpc8641hpcn.c b/board/freescale/mpc8641hpcn/mpc8641hpcn.c index b83ed6c..9b6b69e 100644 --- a/board/freescale/mpc8641hpcn/mpc8641hpcn.c +++ b/board/freescale/mpc8641hpcn/mpc8641hpcn.c @@ -163,9 +163,6 @@ void pci_init_board(void) } debug("\n");
- /* inbound */ - r += fsl_pci_setup_inbound_windows(r); - /* outbound memory */ pci_set_region(r++, CONFIG_SYS_PCI1_MEM_BASE, @@ -180,6 +177,9 @@ void pci_init_board(void) CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO);
+ /* inbound */ + r += fsl_pci_setup_inbound_windows(r); + hose->region_count = r - hose->regions;
hose->first_busno=first_free_busno; @@ -212,9 +212,6 @@ void pci_init_board(void) struct pci_controller *hose = &pci2_hose; struct pci_region *r = hose->regions;
- /* inbound */ - r += fsl_pci_setup_inbound_windows(r); - /* outbound memory */ pci_set_region(r++, CONFIG_SYS_PCI2_MEM_BASE, @@ -229,6 +226,9 @@ void pci_init_board(void) CONFIG_SYS_PCI2_IO_SIZE, PCI_REGION_IO);
+ /* inbound */ + r += fsl_pci_setup_inbound_windows(r); + hose->region_count = r - hose->regions;
hose->first_busno=first_free_busno;

On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
Because the inbound pci windows are mapped generously, set up the more specific outbound windows first. This way, when we search the pci regions for something, we will hit on the more specific region. This can actually be a problem on systems with large amounts of RAM.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
board/freescale/mpc8641hpcn/mpc8641hpcn.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-)
I've got a patch I'm about to post that will supersede the for this patch. Don't really like depending on the order of the regions.
- k

It is no longer always true that the pci bus address can be used as the virtual address for pci accesses. pci_map_bar() is created to return the virtual address for a pci region.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- drivers/pci/pci.c | 19 +++++++++++++++++++ include/pci.h | 28 ++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e2b05d8..cb1217f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -116,6 +116,25 @@ PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02) PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff) PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
+/* Get a virtual address associated with a BAR region */ +void *pci_map_bar(pci_dev_t pdev, int bar, int flags) +{ + pci_addr_t pci_bus_addr; + u32 bar_response; + + /* read BAR address */ + pci_read_config_dword(pdev, bar, &bar_response); + pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); + + /* + * Pass "0" as the length argument to pci_bus_to_virt. The arg + * isn't actualy used on any platform because u-boot assumes a static + * linear mapping. In the future, this could read the BAR size + * and pass that as the size if needed. + */ + return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE); +} + /* * */ diff --git a/include/pci.h b/include/pci.h index eebe8a8..0d29a10 100644 --- a/include/pci.h +++ b/include/pci.h @@ -450,10 +450,29 @@ extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose, #define pci_bus_to_phys(dev, addr, flags) \ pci_hose_bus_to_phys(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
-#define pci_phys_to_mem(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_MEM) -#define pci_mem_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_MEM) -#define pci_phys_to_io(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_IO) -#define pci_io_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_IO) +#define pci_virt_to_bus(dev, addr, flags) \ + pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), \ + (virt_to_phys(addr)), (flags)) +#define pci_bus_to_virt(dev, addr, flags, len, map_flags) \ + map_physmem(pci_hose_bus_to_phys(pci_bus_to_hose(PCI_BUS(dev)), \ + (addr), (flags)), \ + (len), (map_flags)) + +#define pci_phys_to_mem(dev, addr) \ + pci_phys_to_bus((dev), (addr), PCI_REGION_MEM) +#define pci_mem_to_phys(dev, addr) \ + pci_bus_to_phys((dev), (addr), PCI_REGION_MEM) +#define pci_phys_to_io(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_IO) +#define pci_io_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_IO) + +#define pci_virt_to_mem(dev, addr) \ + pci_virt_to_bus((dev), (addr), PCI_REGION_MEM) +#define pci_mem_to_virt(dev, addr, len, map_flags) \ + pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags)) +#define pci_virt_to_io(dev, addr) \ + pci_virt_to_bus((dev), (addr), PCI_REGION_IO) +#define pci_io_to_virt(dev, addr, len, map_flags) \ + pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
extern int pci_hose_read_config_byte(struct pci_controller *hose, pci_dev_t dev, int where, u8 *val); @@ -484,6 +503,7 @@ extern int pci_hose_write_config_byte_via_dword(struct pci_controller *hose, extern int pci_hose_write_config_word_via_dword(struct pci_controller *hose, pci_dev_t dev, int where, u16 val);
+extern void *pci_map_bar(pci_dev_t pdev, int bar, int flags); extern void pci_register_hose(struct pci_controller* hose); extern struct pci_controller* pci_bus_to_hose(int bus);

On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
It is no longer always true that the pci bus address can be used as the virtual address for pci accesses. pci_map_bar() is created to return the virtual address for a pci region.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
drivers/pci/pci.c | 19 +++++++++++++++++++ include/pci.h | 28 ++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-)
Wolfgang,
What about picking this up?
- k

The BAT fields are architected; there's no need for these to be in cpu-specific files. Drop the duplication and move these to include/asm-ppc/mmu.h. Also, remove the BL_xxx defines that were only used by the alaska board, and switch to using the BATU_BL_xxx defines used by all the other boards. The BL_ defines previously in use had to be shifted into the proper position for use, which was inefficient.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- board/alaska/alaska.c | 36 +++++++++++++------------- board/etin/debris/flash.c | 1 + board/etin/kvme080/kvme080.c | 1 + include/74xx_7xx.h | 37 --------------------------- include/asm-ppc/e300.h | 35 ------------------------- include/asm-ppc/mmu.h | 57 ++++++++++++++++++++++++++++++++--------- include/mpc824x.h | 39 ---------------------------- include/mpc86xx.h | 41 ------------------------------ 8 files changed, 64 insertions(+), 183 deletions(-)
diff --git a/board/alaska/alaska.c b/board/alaska/alaska.c index 33b4a6e..89c1abd 100644 --- a/board/alaska/alaska.c +++ b/board/alaska/alaska.c @@ -33,9 +33,9 @@ void setupBat (ulong size)
/* Flash 0 */ #if defined (CONFIG_SYS_AMD_BOOT) - batu = CONFIG_SYS_FLASH0_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; + batu = CONFIG_SYS_FLASH0_BASE | BATU_BL_512K | BPP_RW | BPP_RX; #else - batu = CONFIG_SYS_FLASH0_BASE | (BL_16M << 2) | BPP_RW | BPP_RX; + batu = CONFIG_SYS_FLASH0_BASE | BATU_BL_16M | BPP_RW | BPP_RX; #endif batl = CONFIG_SYS_FLASH0_BASE | 0x22; write_bat (IBAT0, batu, batl); @@ -43,22 +43,22 @@ void setupBat (ulong size)
/* Flash 1 */ #if defined (CONFIG_SYS_AMD_BOOT) - batu = CONFIG_SYS_FLASH1_BASE | (BL_16M << 2) | BPP_RW | BPP_RX; + batu = CONFIG_SYS_FLASH1_BASE | BATU_BL_16M | BPP_RW | BPP_RX; #else - batu = CONFIG_SYS_FLASH1_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; + batu = CONFIG_SYS_FLASH1_BASE | BATU_BL_512K | BPP_RW | BPP_RX; #endif batl = CONFIG_SYS_FLASH1_BASE | 0x22; write_bat (IBAT1, batu, batl); write_bat (DBAT1, batu, batl);
/* CPLD */ - batu = CONFIG_SYS_CPLD_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; + batu = CONFIG_SYS_CPLD_BASE | BATU_BL_512K | BPP_RW | BPP_RX; batl = CONFIG_SYS_CPLD_BASE | 0x22; write_bat (IBAT2, 0, 0); write_bat (DBAT2, batu, batl);
/* FPGA */ - batu = CONFIG_SYS_FPGA_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; + batu = CONFIG_SYS_FPGA_BASE | BATU_BL_512K | BPP_RW | BPP_RX; batl = CONFIG_SYS_FPGA_BASE | 0x22; write_bat (IBAT3, 0, 0); write_bat (DBAT3, batu, batl); @@ -80,17 +80,17 @@ void setupBat (ulong size) mtspr (DBAT5U, batu);
if (size <= 0x800000) /* 8MB */ - blocksize = BL_8M << 2; + blocksize = BATU_BL_8M; else if (size <= 0x1000000) /* 16MB */ - blocksize = BL_16M << 2; + blocksize = BATU_BL_16M; else if (size <= 0x2000000) /* 32MB */ - blocksize = BL_32M << 2; + blocksize = BATU_BL_32M; else if (size <= 0x4000000) /* 64MB */ - blocksize = BL_64M << 2; + blocksize = BATU_BL_64M; else if (size <= 0x8000000) /* 128MB */ - blocksize = BL_128M << 2; + blocksize = BATU_BL_128M; else if (size <= 0x10000000) /* 256MB */ - blocksize = BL_256M << 2; + blocksize = BATU_BL_256M;
/* Memory */ batu = CONFIG_SYS_SDRAM_BASE | blocksize | BPP_RW | BPP_RX; @@ -108,17 +108,17 @@ void setupBat (ulong size) } else { size -= 0x10000000; if (size <= 0x800000) /* 8MB */ - blocksize = BL_8M << 2; + blocksize = BATU_BL_8M; else if (size <= 0x1000000) /* 16MB */ - blocksize = BL_16M << 2; + blocksize = BATU_BL_16M; else if (size <= 0x2000000) /* 32MB */ - blocksize = BL_32M << 2; + blocksize = BATU_BL_32M; else if (size <= 0x4000000) /* 64MB */ - blocksize = BL_64M << 2; + blocksize = BATU_BL_64M; else if (size <= 0x8000000) /* 128MB */ - blocksize = BL_128M << 2; + blocksize = BATU_BL_128M; else if (size <= 0x10000000) /* 256MB */ - blocksize = BL_256M << 2; + blocksize = BATU_BL_256M;
batu = (CONFIG_SYS_SDRAM_BASE + 0x10000000) | blocksize | BPP_RW | BPP_RX; diff --git a/board/etin/debris/flash.c b/board/etin/debris/flash.c index a3c8138..f9e8619 100644 --- a/board/etin/debris/flash.c +++ b/board/etin/debris/flash.c @@ -27,6 +27,7 @@ #include <asm/processor.h> #include <asm/pci_io.h> #include <mpc824x.h> +#include <asm/mmu.h>
int (*do_flash_erase)(flash_info_t*, uint32_t, uint32_t); int (*write_dword)(flash_info_t*, ulong, uint64_t); diff --git a/board/etin/kvme080/kvme080.c b/board/etin/kvme080/kvme080.c index 8c6afc9..21616f5 100644 --- a/board/etin/kvme080/kvme080.c +++ b/board/etin/kvme080/kvme080.c @@ -27,6 +27,7 @@ #include <i2c.h> #include <netdev.h> #include <asm/processor.h> +#include <asm/mmu.h>
int checkboard(void) { diff --git a/include/74xx_7xx.h b/include/74xx_7xx.h index 4a03cec..69a2174 100644 --- a/include/74xx_7xx.h +++ b/include/74xx_7xx.h @@ -66,43 +66,6 @@ #define L2CR_L2OH_INV 0x00020000 /* bits 14-15 - output hold time = long */ #define L2CR_L2IP 0x00000001 /* global invalidate in progress */
-/*---------------------------------------------------------------- - * BAT settings. Look in config_<BOARD>.h for the actual setup - */ - -#define BATU_BL_128K 0x00000000 -#define BATU_BL_256K 0x00000004 -#define BATU_BL_512K 0x0000000c -#define BATU_BL_1M 0x0000001c -#define BATU_BL_2M 0x0000003c -#define BATU_BL_4M 0x0000007c -#define BATU_BL_8M 0x000000fc -#define BATU_BL_16M 0x000001fc -#define BATU_BL_32M 0x000003fc -#define BATU_BL_64M 0x000007fc -#define BATU_BL_128M 0x00000ffc -#define BATU_BL_256M 0x00001ffc - -#define BATU_VS 0x00000002 -#define BATU_VP 0x00000001 -#define BATU_INVALID 0x00000000 - -#define BATL_WRITETHROUGH 0x00000040 -#define BATL_CACHEINHIBIT 0x00000020 -#define BATL_MEMCOHERENCE 0x00000010 -#define BATL_GUARDEDSTORAGE 0x00000008 -#define BATL_NO_ACCESS 0x00000000 - -#define BATL_PP_MSK 0x00000003 -#define BATL_PP_00 0x00000000 /* No access */ -#define BATL_PP_01 0x00000001 /* Read-only */ -#define BATL_PP_10 0x00000002 /* Read-write */ -#define BATL_PP_11 0x00000003 - -#define BATL_PP_NO_ACCESS BATL_PP_00 -#define BATL_PP_RO BATL_PP_01 -#define BATL_PP_RW BATL_PP_10 - #ifndef __ASSEMBLY__ /* cpu ids we detect */ typedef enum __cpu_t { diff --git a/include/asm-ppc/e300.h b/include/asm-ppc/e300.h index 05db0de..bfef4df 100644 --- a/include/asm-ppc/e300.h +++ b/include/asm-ppc/e300.h @@ -88,39 +88,4 @@ #define HID2_IWLCK_101 0x0000A000 /* way 0 through way 4 locked */ #define HID2_IWLCK_110 0x0000C000 /* way 0 through way 5 locked */
- -/* BAT (block address translation */ -#define BATU_BEPI_MSK 0xfffe0000 -#define BATU_BL_MSK 0x00001ffc - -#define BATU_BL_128K 0x00000000 -#define BATU_BL_256K 0x00000004 -#define BATU_BL_512K 0x0000000c -#define BATU_BL_1M 0x0000001c -#define BATU_BL_2M 0x0000003c -#define BATU_BL_4M 0x0000007c -#define BATU_BL_8M 0x000000fc -#define BATU_BL_16M 0x000001fc -#define BATU_BL_32M 0x000003fc -#define BATU_BL_64M 0x000007fc -#define BATU_BL_128M 0x00000ffc -#define BATU_BL_256M 0x00001ffc - -#define BATU_VS 0x00000002 -#define BATU_VP 0x00000001 - -#define BATL_BRPN_MSK 0xfffe0000 -#define BATL_WIMG_MSK 0x00000078 - -#define BATL_WRITETHROUGH 0x00000040 -#define BATL_CACHEINHIBIT 0x00000020 -#define BATL_MEMCOHERENCE 0x00000010 -#define BATL_GUARDEDSTORAGE 0x00000008 - -#define BATL_PP_MSK 0x00000003 -#define BATL_PP_00 0x00000000 /* No access */ -#define BATL_PP_01 0x00000001 /* Read-only */ -#define BATL_PP_10 0x00000002 /* Read-write */ -#define BATL_PP_11 0x00000003 - #endif /* __E300_H__ */ diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 6d942d0..ce04e62 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -153,19 +153,50 @@ extern void print_bats(void);
#endif /* __ASSEMBLY__ */
-/* Block size masks */ -#define BL_128K 0x000 -#define BL_256K 0x001 -#define BL_512K 0x003 -#define BL_1M 0x007 -#define BL_2M 0x00F -#define BL_4M 0x01F -#define BL_8M 0x03F -#define BL_16M 0x07F -#define BL_32M 0x0FF -#define BL_64M 0x1FF -#define BL_128M 0x3FF -#define BL_256M 0x7FF +#define BATU_VS 0x00000002 +#define BATU_VP 0x00000001 +#define BATU_INVALID 0x00000000 + +#define BATL_WRITETHROUGH 0x00000040 +#define BATL_CACHEINHIBIT 0x00000020 +#define BATL_MEMCOHERENCE 0x00000010 +#define BATL_GUARDEDSTORAGE 0x00000008 +#define BATL_NO_ACCESS 0x00000000 + +#define BATL_PP_MSK 0x00000003 +#define BATL_PP_00 0x00000000 /* No access */ +#define BATL_PP_01 0x00000001 /* Read-only */ +#define BATL_PP_10 0x00000002 /* Read-write */ +#define BATL_PP_11 0x00000003 + +#define BATL_PP_NO_ACCESS BATL_PP_00 +#define BATL_PP_RO BATL_PP_01 +#define BATL_PP_RW BATL_PP_10 + +/* BAT Block size values */ +#define BATU_BL_128K 0x00000000 +#define BATU_BL_256K 0x00000004 +#define BATU_BL_512K 0x0000000c +#define BATU_BL_1M 0x0000001c +#define BATU_BL_2M 0x0000003c +#define BATU_BL_4M 0x0000007c +#define BATU_BL_8M 0x000000fc +#define BATU_BL_16M 0x000001fc +#define BATU_BL_32M 0x000003fc +#define BATU_BL_64M 0x000007fc +#define BATU_BL_128M 0x00000ffc +#define BATU_BL_256M 0x00001ffc + +/* Block lengths for processors that support extended block length */ +#ifdef HID0_XBSEN +#define BATU_BL_512M 0x00003ffc +#define BATU_BL_1G 0x00007ffc +#define BATU_BL_2G 0x0000fffc +#define BATU_BL_4G 0x0001fffc +#define BATU_BL_MAX BATU_BL_4G +#else +#define BATU_BL_MAX BATU_BL_256M +#endif
/* BAT Access Protection */ #define BPP_XX 0x00 /* No access */ diff --git a/include/mpc824x.h b/include/mpc824x.h index 5aa9370..fca9371 100644 --- a/include/mpc824x.h +++ b/include/mpc824x.h @@ -451,45 +451,6 @@ #define MICR_EADDR_MASK 0x30000000 #define MICR_EADDR_SHIFT 28
-#define BATU_BEPI_MSK 0xfffe0000 -#define BATU_BL_MSK 0x00001ffc - -#define BATU_BL_128K 0x00000000 -#define BATU_BL_256K 0x00000004 -#define BATU_BL_512K 0x0000000c -#define BATU_BL_1M 0x0000001c -#define BATU_BL_2M 0x0000003c -#define BATU_BL_4M 0x0000007c -#define BATU_BL_8M 0x000000fc -#define BATU_BL_16M 0x000001fc -#define BATU_BL_32M 0x000003fc -#define BATU_BL_64M 0x000007fc -#define BATU_BL_128M 0x00000ffc -#define BATU_BL_256M 0x00001ffc - -#define BATU_VS 0x00000002 -#define BATU_VP 0x00000001 - -#define BATL_BRPN_MSK 0xfffe0000 -#define BATL_WIMG_MSK 0x00000078 - -#define BATL_WRITETHROUGH 0x00000040 -#define BATL_CACHEINHIBIT 0x00000020 -#define BATL_MEMCOHERENCE 0x00000010 -#define BATL_GUARDEDSTORAGE 0x00000008 - -#define BATL_PP_MSK 0x00000003 -#define BATL_PP_00 0x00000000 /* No access */ -#define BATL_PP_01 0x00000001 /* Read-only */ -#define BATL_PP_10 0x00000002 /* Read-write */ -#define BATL_PP_11 0x00000003 - -/* - * I'd attempt to do defines for the PP bits, but it's use is a bit - * too complex, see the PowerPC Operating Environment Architecture - * section in the PowerPc arch book, chapter 4. - */ - /*eumb and epic config*/
#define EPIC_FPR 0x00041000 diff --git a/include/mpc86xx.h b/include/mpc86xx.h index f119d5b..9b63582 100644 --- a/include/mpc86xx.h +++ b/include/mpc86xx.h @@ -34,47 +34,6 @@ #define L2CR_HWF 0x00000800 /* bit 20 - hardware flush */ #define L2CR_L2IP 0x00000001 /* global invalidate in progress */
-/* - * BAT settings. Look in config_<BOARD>.h for the actual setup - */ - -#define BATU_BL_128K 0x00000000 -#define BATU_BL_256K 0x00000004 -#define BATU_BL_512K 0x0000000c -#define BATU_BL_1M 0x0000001c -#define BATU_BL_2M 0x0000003c -#define BATU_BL_4M 0x0000007c -#define BATU_BL_8M 0x000000fc -#define BATU_BL_16M 0x000001fc -#define BATU_BL_32M 0x000003fc -#define BATU_BL_64M 0x000007fc -#define BATU_BL_128M 0x00000ffc -#define BATU_BL_256M 0x00001ffc -#define BATU_BL_512M 0x00003ffc -#define BATU_BL_1G 0x00007ffc -#define BATU_BL_2G 0x0000fffc -#define BATU_BL_4G 0x0001fffc - -#define BATU_VS 0x00000002 -#define BATU_VP 0x00000001 -#define BATU_INVALID 0x00000000 - -#define BATL_WRITETHROUGH 0x00000040 -#define BATL_CACHEINHIBIT 0x00000020 -#define BATL_MEMCOHERENCE 0x00000010 -#define BATL_GUARDEDSTORAGE 0x00000008 -#define BATL_NO_ACCESS 0x00000000 - -#define BATL_PP_MSK 0x00000003 -#define BATL_PP_00 0x00000000 /* No access */ -#define BATL_PP_01 0x00000001 /* Read-only */ -#define BATL_PP_10 0x00000002 /* Read-write */ -#define BATL_PP_11 0x00000003 - -#define BATL_PP_NO_ACCESS BATL_PP_00 -#define BATL_PP_RO BATL_PP_01 -#define BATL_PP_RW BATL_PP_10 - #define HID0_XBSEN 0x00000100 #define HID0_HIGH_BAT_EN 0x00800000 #define HID0_XAEN 0x00020000

Some parts can support large physical mappings; so make the size argument to addrmap_set_entry a phys_size_t. Also update the 85xx tlb code to be sure the size quantity is unsigned.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- cpu/mpc85xx/tlb.c | 4 ++-- include/addr_map.h | 2 +- lib_generic/addr_map.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/cpu/mpc85xx/tlb.c b/cpu/mpc85xx/tlb.c index f80d8b2..5b5f791 100644 --- a/cpu/mpc85xx/tlb.c +++ b/cpu/mpc85xx/tlb.c @@ -55,7 +55,7 @@ void set_tlb(u8 tlb, u32 epn, u64 rpn,
#ifdef CONFIG_ADDR_MAP if ((tlb == 1) && (gd->flags & GD_FLG_RELOC)) - addrmap_set_entry(epn, rpn, (1 << ((tsize * 2) + 10)), esel); + addrmap_set_entry(epn, rpn, (1UL << ((tsize * 2) + 10)), esel); #endif }
@@ -117,7 +117,7 @@ void init_addr_map(void)
addrmap_set_entry(tlb_table[i].epn, tlb_table[i].rpn, - (1 << ((tlb_table[i].tsize * 2) + 10)), + (1UL << ((tlb_table[i].tsize * 2) + 10)), tlb_table[i].esel); }
diff --git a/include/addr_map.h b/include/addr_map.h index 234487a..d55f5f6 100644 --- a/include/addr_map.h +++ b/include/addr_map.h @@ -24,6 +24,6 @@ extern phys_addr_t addrmap_virt_to_phys(void *vaddr); extern unsigned long addrmap_phys_to_virt(phys_addr_t paddr); extern void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, - unsigned long size, int idx); + phys_size_t size, int idx);
#endif diff --git a/lib_generic/addr_map.c b/lib_generic/addr_map.c index b8d9c2d..ff8532c 100644 --- a/lib_generic/addr_map.c +++ b/lib_generic/addr_map.c @@ -21,8 +21,8 @@
static struct { phys_addr_t paddr; + phys_size_t size; unsigned long vaddr; - unsigned long size; } address_map[CONFIG_SYS_NUM_ADDR_MAP];
phys_addr_t addrmap_virt_to_phys(void * vaddr) @@ -70,7 +70,7 @@ unsigned long addrmap_phys_to_virt(phys_addr_t paddr) }
void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, - unsigned long size, int idx) + phys_size_t size, int idx) { if (idx > CONFIG_SYS_NUM_ADDR_MAP) return;

On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
Some parts can support large physical mappings; so make the size argument to addrmap_set_entry a phys_size_t. Also update the 85xx tlb code to be sure the size quantity is unsigned.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
cpu/mpc85xx/tlb.c | 4 ++-- include/addr_map.h | 2 +- lib_generic/addr_map.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-)
I reposted my patches (v4) and folded this into those patches.
- k

If CONFIG_ADDR_MAP is enabled, update the address map whenever we write a bat.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- cpu/mpc86xx/cpu_init.c | 27 +++++++++++++++++++++++++++ include/asm-ppc/mmu.h | 16 +++++++++++++--- lib_ppc/bat_rw.c | 28 ++++++++++++++++++++++++++++ lib_ppc/board.c | 2 +- 4 files changed, 69 insertions(+), 4 deletions(-)
diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c index a7e6036..4f29122 100644 --- a/cpu/mpc86xx/cpu_init.c +++ b/cpu/mpc86xx/cpu_init.c @@ -154,3 +154,30 @@ void setup_bats(void)
return; } + +#ifdef CONFIG_ADDR_MAP +/* Initialize address mapping array */ +void init_addr_map(void) +{ + int i; + ppc_bat_t bat = DBAT0; + phys_size_t size; + unsigned long upper, lower; + + for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++, bat++) { + if (read_bat(bat, &upper, &lower) != -1) { + if (!BATU_VALID(upper)) + size = 0; + else + size = BATU_SIZE(upper); + addrmap_set_entry(BATU_VADDR(upper), BATL_PADDR(lower), + size, i); + } +#ifdef CONFIG_HIGH_BATS + /* High bats are not contiguous with low BAT numbers */ + if (bat == DBAT3) + bat = DBAT4 - 1; +#endif + } +} +#endif diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index ce04e62..fa92b90 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -138,6 +138,10 @@ typedef struct _MMU_context { extern void _tlbie(unsigned long va); /* invalidate a TLB entry */ extern void _tlbia(void); /* invalidate all TLB entries */
+#ifdef CONFIG_ADDR_MAP +extern void init_addr_map(void); +#endif + typedef enum { IBAT0 = 0, IBAT1, IBAT2, IBAT3, DBAT0, DBAT1, DBAT2, DBAT3, @@ -203,6 +207,14 @@ extern void print_bats(void); #define BPP_RX 0x01 /* Read only */ #define BPP_RW 0x02 /* Read/write */
+/* Macros to get values from BATs, once data is in the BAT register format */ +#define BATU_VALID(x) (x & 0x3) +#define BATU_VADDR(x) (x & 0xfffe0000) +#define BATL_PADDR(x) ((phys_addr_t)((x & 0xfffe0000) \ + | ((x & 0x0e00ULL) << 24) \ + | ((x & 0x04ULL) << 30))) +#define BATU_SIZE(x) (1UL << (fls((x & BATU_BL_MAX) >> 2) + 17)) + /* Used to set up SDR1 register */ #define HASH_TABLE_SIZE_64K 0x00010000 #define HASH_TABLE_SIZE_128K 0x00020000 @@ -462,9 +474,7 @@ extern void set_tlb(u8 tlb, u32 epn, u64 rpn, extern void disable_tlb(u8 esel); extern void invalidate_tlb(u8 tlb); extern void init_tlbs(void); -#ifdef CONFIG_ADDR_MAP -extern void init_addr_map(void); -#endif + extern unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg);
#define SET_TLB_ENTRY(_tlb, _epn, _rpn, _perms, _wimge, _ts, _esel, _sz, _iprot) \ diff --git a/lib_ppc/bat_rw.c b/lib_ppc/bat_rw.c index a40b377..c48c240 100644 --- a/lib_ppc/bat_rw.c +++ b/lib_ppc/bat_rw.c @@ -27,14 +27,23 @@ #include <asm/mmu.h> #include <asm/io.h>
+#ifdef CONFIG_ADDR_MAP +#include <addr_map.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) { + int batn = -1; + sync();
switch (bat) { case DBAT0: mtspr (DBAT0L, lower); mtspr (DBAT0U, upper); + batn = 0; break; case IBAT0: mtspr (IBAT0L, lower); @@ -43,6 +52,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT1: mtspr (DBAT1L, lower); mtspr (DBAT1U, upper); + batn = 1; break; case IBAT1: mtspr (IBAT1L, lower); @@ -51,6 +61,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT2: mtspr (DBAT2L, lower); mtspr (DBAT2U, upper); + batn = 2; break; case IBAT2: mtspr (IBAT2L, lower); @@ -59,6 +70,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT3: mtspr (DBAT3L, lower); mtspr (DBAT3U, upper); + batn = 3; break; case IBAT3: mtspr (IBAT3L, lower); @@ -68,6 +80,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT4: mtspr (DBAT4L, lower); mtspr (DBAT4U, upper); + batn = 4; break; case IBAT4: mtspr (IBAT4L, lower); @@ -76,6 +89,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT5: mtspr (DBAT5L, lower); mtspr (DBAT5U, upper); + batn = 5; break; case IBAT5: mtspr (IBAT5L, lower); @@ -84,6 +98,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT6: mtspr (DBAT6L, lower); mtspr (DBAT6U, upper); + batn = 6; break; case IBAT6: mtspr (IBAT6L, lower); @@ -92,6 +107,7 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) case DBAT7: mtspr (DBAT7L, lower); mtspr (DBAT7U, upper); + batn = 7; break; case IBAT7: mtspr (IBAT7L, lower); @@ -102,6 +118,18 @@ int write_bat (ppc_bat_t bat, unsigned long upper, unsigned long lower) return (-1); }
+#ifdef CONFIG_ADDR_MAP + if ((gd->flags & GD_FLG_RELOC) && (batn >= 0)) { + phys_size_t size; + if (!BATU_VALID(upper)) + size = 0; + else + size = BATU_SIZE(upper); + addrmap_set_entry(BATU_VADDR(upper), BATL_PADDR(lower), + size, batn); + } +#endif + sync(); isync();
diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 61c29b5..d610047 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -698,7 +698,7 @@ void board_init_r (gd_t *id, ulong dest_addr) */ trap_init (dest_addr);
-#if defined(CONFIG_ADDR_MAP) && defined(CONFIG_E500) +#ifdef CONFIG_ADDR_MAP init_addr_map(); #endif

include/flash.h was commented to say that the address in flash_info->start was a physical address. However, from u-boot's point of view, and looking at most flash code, it makes more sense for this to be a virtual address. So I corrected the comment to indicate that this was a virtual address.
The only flash driver that was actually treating the address as physical was the mtd/cfi_flash driver. However, this code was using it inconsistently as it actually directly dereferenced the "start" element, while it used map_physmem to get a virtual address in other places. I changed this driver so that the code which initializes the info->start field calls map_physmem to get a virtual address, eliminating the need for further map_physmem calls. The code is now consistent.
The *only* place a physical address should be used is when defining the flash banks list that is used to initialize the flash_info struct. I have fixed the one platform that was impacted by this change (MPC8641D).
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- drivers/mtd/cfi_flash.c | 53 ++++++++++++++++++---------------------- include/configs/MPC8641HPCN.h | 2 +- include/flash.h | 2 +- 3 files changed, 26 insertions(+), 31 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index e8afe99..292cc28 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -305,17 +305,12 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset) { unsigned int byte_offset = offset * info->portwidth;
- return map_physmem(info->start[sect] + byte_offset, - flash_sector_size(info, sect) - byte_offset, - MAP_NOCACHE); + return (void *)(info->start[sect] + byte_offset); }
static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, unsigned int offset, void *addr) { - unsigned int byte_offset = offset * info->portwidth; - - unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset); }
/*----------------------------------------------------------------------- @@ -793,12 +788,10 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr) static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword) { - void *dstaddr; + void *dstaddr = (void *)dest; int flag; flash_sect_t sect;
- dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE); - /* Check if Flash is (sufficiently) erased */ switch (info->portwidth) { case FLASH_CFI_8BIT: @@ -817,10 +810,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest, flag = 0; break; } - if (!flag) { - unmap_physmem(dstaddr, info->portwidth); + if (!flag) return ERR_NOT_ERASED; - }
/* Disable interrupts which might cause a timeout here */ flag = disable_interrupts (); @@ -862,8 +853,6 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest, if (flag) enable_interrupts ();
- unmap_physmem(dstaddr, info->portwidth); - return flash_full_status_check (info, find_sector (info, dest), info->write_tout, "write"); } @@ -877,7 +866,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int cnt; int retcode; void *src = cp; - void *dst = map_physmem(dest, len, MAP_NOCACHE); + void *dst = dest; void *dst2 = dst; int flag = 0; uint offset = 0; @@ -1039,7 +1028,6 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, }
out_unmap: - unmap_physmem(dst, len); return retcode; } #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */ @@ -1288,7 +1276,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) /* handle unaligned start */ if ((aln = addr - wp) != 0) { cword.l = 0; - p = map_physmem(wp, info->portwidth, MAP_NOCACHE); + p = (uchar *)wp; for (i = 0; i < aln; ++i) flash_add_byte (info, &cword, flash_read8(p + i));
@@ -1300,7 +1288,6 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) flash_add_byte (info, &cword, flash_read8(p + i));
rc = flash_write_cfiword (info, wp, cword); - unmap_physmem(p, info->portwidth); if (rc != 0) return rc;
@@ -1359,14 +1346,13 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) * handle unaligned tail bytes */ cword.l = 0; - p = map_physmem(wp, info->portwidth, MAP_NOCACHE); + p = (uchar *)wp; for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) { flash_add_byte (info, &cword, *src++); --cnt; } for (; i < info->portwidth; ++i) flash_add_byte (info, &cword, flash_read8(p + i)); - unmap_physmem(p, info->portwidth);
return flash_write_cfiword (info, wp, cword); } @@ -1605,7 +1591,7 @@ static void flash_read_jedec_ids (flash_info_t * info) * board_flash_get_legacy needs to fill in at least: * info->portwidth, info->chipwidth and info->interface for Jedec probing. */ -static int flash_detect_legacy(ulong base, int banknum) +static int flash_detect_legacy(phys_addr_t base, int banknum) { flash_info_t *info = &flash_info[banknum];
@@ -1621,7 +1607,10 @@ static int flash_detect_legacy(ulong base, int banknum)
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { info->vendor = modes[i]; - info->start[0] = base; + info->start[0] = + (ulong)map_physmem(base, + info->portwith, + MAP_NOCACHE); if (info->portwidth == FLASH_CFI_8BIT && info->interface == FLASH_CFI_X8X16) { info->addr_unlock1 = 0x2AAA; @@ -1635,8 +1624,11 @@ static int flash_detect_legacy(ulong base, int banknum) info->manufacturer_id, info->device_id, info->device_id2); - if (jedec_flash_match(info, base)) + if (jedec_flash_match(info, info->start[0])) break; + else + unmap_physmem(info->start[0], + MAP_NOCACHE); } }
@@ -1658,7 +1650,7 @@ static int flash_detect_legacy(ulong base, int banknum) return 0; /* use CFI */ } #else -static inline int flash_detect_legacy(ulong base, int banknum) +static inline int flash_detect_legacy(phys_addr_t base, int banknum) { return 0; /* use CFI */ } @@ -1799,12 +1791,12 @@ static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry) * The following code cannot be run from FLASH! * */ -ulong flash_get_size (ulong base, int banknum) +ulong flash_get_size (phys_addr_t base, int banknum) { flash_info_t *info = &flash_info[banknum]; int i, j; flash_sect_t sect_cnt; - unsigned long sector; + phys_addr_t sector; unsigned long tmp; int size_ratio; uchar num_erase_regions; @@ -1820,7 +1812,7 @@ ulong flash_get_size (ulong base, int banknum) info->legacy_unlock = 0; #endif
- info->start[0] = base; + info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
if (flash_detect_cfi (info, &qry)) { info->vendor = le16_to_cpu(qry.p_id); @@ -1909,7 +1901,10 @@ ulong flash_get_size (ulong base, int banknum) printf("ERROR: too many flash sectors\n"); break; } - info->start[sect_cnt] = sector; + info->start[sect_cnt] = + (ulong)map_physmem(sector, + info->portwidth, + MAP_NOCACHE); sector += (erase_region_size * size_ratio);
/* @@ -1986,7 +1981,7 @@ unsigned long flash_init (void) char *s = getenv("unlock"); #endif
-#define BANK_BASE(i) (((unsigned long [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i]) +#define BANK_BASE(i) (((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
/* Init: no FLASHes known */ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) { diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 69b4c44..c25380b 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -187,7 +187,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); | CONFIG_SYS_PHYS_ADDR_HIGH)
-#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE} +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE_PHYS}
/* Convert an address into the right format for the BR registers */ #ifdef CONFIG_PHYS_64BIT diff --git a/include/flash.h b/include/flash.h index 6e2981c..02c6a04 100644 --- a/include/flash.h +++ b/include/flash.h @@ -33,7 +33,7 @@ typedef struct { ulong size; /* total bank size in bytes */ ushort sector_count; /* number of erase units */ ulong flash_id; /* combined device & manufacturer code */ - ulong start[CONFIG_SYS_MAX_FLASH_SECT]; /* physical sector start addresses */ + ulong start[CONFIG_SYS_MAX_FLASH_SECT]; /* virtual sector start address */ uchar protect[CONFIG_SYS_MAX_FLASH_SECT]; /* sector protection status */ #ifdef CONFIG_SYS_FLASH_CFI uchar portwidth; /* the width of the port */

On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
include/flash.h was commented to say that the address in flash_info->start was a physical address. However, from u-boot's point of view, and looking at most flash code, it makes more sense for this to be a virtual address. So I corrected the comment to indicate that this was a virtual address.
The only flash driver that was actually treating the address as physical was the mtd/cfi_flash driver. However, this code was using it inconsistently as it actually directly dereferenced the "start" element, while it used map_physmem to get a virtual address in other places. I changed this driver so that the code which initializes the info->start field calls map_physmem to get a virtual address, eliminating the need for further map_physmem calls. The code is now consistent.
The *only* place a physical address should be used is when defining the flash banks list that is used to initialize the flash_info struct. I have fixed the one platform that was impacted by this change (MPC8641D).
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
drivers/mtd/cfi_flash.c | 53 +++++++++++++++++ +---------------------- include/configs/MPC8641HPCN.h | 2 +- include/flash.h | 2 +- 3 files changed, 26 insertions(+), 31 deletions(-)
Stefan,
Have you reviewed this. I'm not sure if remvoing the map_physmem() is the right answer because I'm assuming Haavard added them for a reason (AVR32?). Should we instead change info->start to be a phys_addr_t?
- k
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index e8afe99..292cc28 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -305,17 +305,12 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset) { unsigned int byte_offset = offset * info->portwidth;
- return map_physmem(info->start[sect] + byte_offset,
flash_sector_size(info, sect) - byte_offset,
MAP_NOCACHE);
- return (void *)(info->start[sect] + byte_offset);
}
static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, unsigned int offset, void *addr) {
- unsigned int byte_offset = offset * info->portwidth;
- unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset);
}
/ *----------------------------------------------------------------------- @@ -793,12 +788,10 @@ static flash_sect_t find_sector (flash_info_t
- info, ulong addr)
static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword) {
- void *dstaddr;
- void *dstaddr = (void *)dest; int flag; flash_sect_t sect;
- dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);
- /* Check if Flash is (sufficiently) erased */ switch (info->portwidth) { case FLASH_CFI_8BIT:
@@ -817,10 +810,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest, flag = 0; break; }
- if (!flag) {
unmap_physmem(dstaddr, info->portwidth);
- if (!flag) return ERR_NOT_ERASED;
}
/* Disable interrupts which might cause a timeout here */ flag = disable_interrupts ();
@@ -862,8 +853,6 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest, if (flag) enable_interrupts ();
- unmap_physmem(dstaddr, info->portwidth);
- return flash_full_status_check (info, find_sector (info, dest), info->write_tout, "write");
} @@ -877,7 +866,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int cnt; int retcode; void *src = cp;
- void *dst = map_physmem(dest, len, MAP_NOCACHE);
- void *dst = dest; void *dst2 = dst; int flag = 0; uint offset = 0;
@@ -1039,7 +1028,6 @@ static int flash_write_cfibuffer (flash_info_t
- info, ulong dest, uchar * cp, }
out_unmap:
- unmap_physmem(dst, len); return retcode;
} #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */ @@ -1288,7 +1276,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) /* handle unaligned start */ if ((aln = addr - wp) != 0) { cword.l = 0;
p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
for (i = 0; i < aln; ++i) flash_add_byte (info, &cword, flash_read8(p + i));p = (uchar *)wp;
@@ -1300,7 +1288,6 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) flash_add_byte (info, &cword, flash_read8(p + i));
rc = flash_write_cfiword (info, wp, cword);
if (rc != 0) return rc;unmap_physmem(p, info->portwidth);
@@ -1359,14 +1346,13 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) * handle unaligned tail bytes */ cword.l = 0;
- p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
- p = (uchar *)wp; for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) { flash_add_byte (info, &cword, *src++); --cnt; } for (; i < info->portwidth; ++i) flash_add_byte (info, &cword, flash_read8(p + i));
unmap_physmem(p, info->portwidth);
return flash_write_cfiword (info, wp, cword);
} @@ -1605,7 +1591,7 @@ static void flash_read_jedec_ids (flash_info_t
- info)
- board_flash_get_legacy needs to fill in at least:
- info->portwidth, info->chipwidth and info->interface for Jedec
probing. */ -static int flash_detect_legacy(ulong base, int banknum) +static int flash_detect_legacy(phys_addr_t base, int banknum) { flash_info_t *info = &flash_info[banknum];
@@ -1621,7 +1607,10 @@ static int flash_detect_legacy(ulong base, int banknum)
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { info->vendor = modes[i];
info->start[0] = base;
info->start[0] =
(ulong)map_physmem(base,
info->portwith,
MAP_NOCACHE); if (info->portwidth == FLASH_CFI_8BIT && info->interface == FLASH_CFI_X8X16) { info->addr_unlock1 = 0x2AAA;
@@ -1635,8 +1624,11 @@ static int flash_detect_legacy(ulong base, int banknum) info->manufacturer_id, info->device_id, info->device_id2);
if (jedec_flash_match(info, base))
if (jedec_flash_match(info, info->start[0])) break;
else
unmap_physmem(info->start[0],
}MAP_NOCACHE); }
@@ -1658,7 +1650,7 @@ static int flash_detect_legacy(ulong base, int banknum) return 0; /* use CFI */ } #else -static inline int flash_detect_legacy(ulong base, int banknum) +static inline int flash_detect_legacy(phys_addr_t base, int banknum) { return 0; /* use CFI */ } @@ -1799,12 +1791,12 @@ static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
- The following code cannot be run from FLASH!
*/ -ulong flash_get_size (ulong base, int banknum) +ulong flash_get_size (phys_addr_t base, int banknum) { flash_info_t *info = &flash_info[banknum]; int i, j; flash_sect_t sect_cnt;
- unsigned long sector;
- phys_addr_t sector; unsigned long tmp; int size_ratio; uchar num_erase_regions;
@@ -1820,7 +1812,7 @@ ulong flash_get_size (ulong base, int banknum) info->legacy_unlock = 0; #endif
- info->start[0] = base;
- info->start[0] = (ulong)map_physmem(base, info->portwidth,
MAP_NOCACHE);
if (flash_detect_cfi (info, &qry)) { info->vendor = le16_to_cpu(qry.p_id); @@ -1909,7 +1901,10 @@ ulong flash_get_size (ulong base, int banknum) printf("ERROR: too many flash sectors\n"); break; }
info->start[sect_cnt] = sector;
info->start[sect_cnt] =
(ulong)map_physmem(sector,
info->portwidth,
MAP_NOCACHE); sector += (erase_region_size * size_ratio); /*
@@ -1986,7 +1981,7 @@ unsigned long flash_init (void) char *s = getenv("unlock"); #endif
-#define BANK_BASE(i) (((unsigned long [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i]) +#define BANK_BASE(i) (((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
/* Init: no FLASHes known */ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) { diff --git a/include/configs/MPC8641HPCN.h b/include/configs/ MPC8641HPCN.h index 69b4c44..c25380b 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -187,7 +187,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); | CONFIG_SYS_PHYS_ADDR_HIGH)
-#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE} +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE_PHYS}
/* Convert an address into the right format for the BR registers */ #ifdef CONFIG_PHYS_64BIT diff --git a/include/flash.h b/include/flash.h index 6e2981c..02c6a04 100644 --- a/include/flash.h +++ b/include/flash.h @@ -33,7 +33,7 @@ typedef struct { ulong size; /* total bank size in bytes */ ushort sector_count; /* number of erase units */ ulong flash_id; /* combined device & manufacturer code */
- ulong start[CONFIG_SYS_MAX_FLASH_SECT]; /* physical sector start
addresses */
- ulong start[CONFIG_SYS_MAX_FLASH_SECT]; /* virtual sector start
address */ uchar protect[CONFIG_SYS_MAX_FLASH_SECT]; /* sector protection status */ #ifdef CONFIG_SYS_FLASH_CFI uchar portwidth; /* the width of the port */ -- 1.5.6.5
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On Jan 14, 2009, at 2:38 AM, Kumar Gala wrote:
Stefan,
Have you reviewed this. I'm not sure if remvoing the map_physmem() is the right answer because I'm assuming Haavard added them for a reason (AVR32?). Should we instead change info->start to be a phys_addr_t?
- k
As I look at this we really need to understand what Haavard was trying to get with:
commit 12d30aa79779c2aa7a998bbae4c075f822a53004 Author: Haavard Skinnemoen hskinnemoen@atmel.com Date: Thu Dec 13 12:56:34 2007 +0100
cfi_flash: Use map_physmem() and unmap_physmem()
Use map_physmem() and unmap_physmem() to convert from physical to virtual addresses. This gives the arch a chance to provide an uncached mapping for flash accesses.
Signed-off-by: Haavard Skinnemoen hskinnemoen@atmel.com
Since this only addresses the usage in cfi_flash.c but not in other users of flash_info (like commands)
- k

Kumar Gala wrote:
As I look at this we really need to understand what Haavard was trying to get with:
commit 12d30aa79779c2aa7a998bbae4c075f822a53004 Author: Haavard Skinnemoen hskinnemoen@atmel.com Date: Thu Dec 13 12:56:34 2007 +0100
cfi_flash: Use map_physmem() and unmap_physmem() Use map_physmem() and unmap_physmem() to convert from physical to virtual addresses. This gives the arch a chance to provide an
uncached mapping for flash accesses.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Since this only addresses the usage in cfi_flash.c but not in other users of flash_info (like commands)
Yeah, there are probably tons of places that really should use map/unmap_physmem() but doesn't. I've been playing with the thought of enabling the Paging bit on AVR32 to support uncached mappings of all physical memory...this is likely to make all of those places very visible.
My goal was to solve a very specific problem (make the cfi_flash driver work on AVR32 boards) by introducing a generic primitive which may be used to solve other similar problems in the future.
I also think it conceptually makes sense to treat physical and virtual addresses as different entities, as they are fundamentally not the same thing on many architectures.
Haavard

Kumar Gala wrote:
On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
include/flash.h was commented to say that the address in flash_info->start was a physical address. However, from u-boot's point of view, and looking at most flash code, it makes more sense for this to be a virtual address. So I corrected the comment to indicate that this was a virtual address.
The only flash driver that was actually treating the address as physical was the mtd/cfi_flash driver. However, this code was using it inconsistently as it actually directly dereferenced the "start" element, while it used map_physmem to get a virtual address in other places. I changed this driver so that the code which initializes the info->start field calls map_physmem to get a virtual address, eliminating the need for further map_physmem calls. The code is now consistent.
The *only* place a physical address should be used is when defining the flash banks list that is used to initialize the flash_info struct. I have fixed the one platform that was impacted by this change (MPC8641D).
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
drivers/mtd/cfi_flash.c | 53 +++++++++++++++++ +---------------------- include/configs/MPC8641HPCN.h | 2 +- include/flash.h | 2 +- 3 files changed, 26 insertions(+), 31 deletions(-)
Stefan,
Have you reviewed this. I'm not sure if remvoing the map_physmem() is the right answer because I'm assuming Haavard added them for a reason (AVR32?). Should we instead change info->start to be a phys_addr_t?
There was definitely a reason: On AVR32, the caches are enabled by default, and I prefer that they stay that way since it makes everything faster. But when dealing with the flash, we must bypass the caches by using a different virtual address which maps to the same physical memory.
From what I can tell from a quick scan, this patch doesn't seem to change that; all it does is push the map_physmem() call a bit up the stack so it gets called less often. That seems like a good thing to me.
However, what I don't understand is if the 'start' array is really supposed to hold virtual addresses, why isn't it an array of pointers?
Haavard

On Jan 14, 2009, at 5:34 AM, Haavard Skinnemoen wrote:
Kumar Gala wrote:
On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
include/flash.h was commented to say that the address in flash_info->start was a physical address. However, from u-boot's point of view, and looking at most flash code, it makes more sense for this to be a virtual address. So I corrected the comment to indicate that this was a virtual address.
The only flash driver that was actually treating the address as physical was the mtd/cfi_flash driver. However, this code was using it inconsistently as it actually directly dereferenced the "start" element, while it used map_physmem to get a virtual address in other places. I changed this driver so that the code which initializes the info->start field calls map_physmem to get a virtual address, eliminating the need for further map_physmem calls. The code is now consistent.
The *only* place a physical address should be used is when defining the flash banks list that is used to initialize the flash_info struct. I have fixed the one platform that was impacted by this change (MPC8641D).
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
drivers/mtd/cfi_flash.c | 53 +++++++++++++++++ +---------------------- include/configs/MPC8641HPCN.h | 2 +- include/flash.h | 2 +- 3 files changed, 26 insertions(+), 31 deletions(-)
Stefan,
Have you reviewed this. I'm not sure if remvoing the map_physmem() is the right answer because I'm assuming Haavard added them for a reason (AVR32?). Should we instead change info->start to be a phys_addr_t?
There was definitely a reason: On AVR32, the caches are enabled by default, and I prefer that they stay that way since it makes everything faster. But when dealing with the flash, we must bypass the caches by using a different virtual address which maps to the same physical memory.
From what I can tell from a quick scan, this patch doesn't seem to change that; all it does is push the map_physmem() call a bit up the stack so it gets called less often. That seems like a good thing to me.
However, what I don't understand is if the 'start' array is really supposed to hold virtual addresses, why isn't it an array of pointers?
That is good to hear. Clearly this patch doesn't deal with the mapping required by any AVR32 platforms. If you had the resources to keep the flash mapping you create around "for ever" or not.
- k

On Wednesday 14 January 2009, Kumar Gala wrote:
On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
include/flash.h was commented to say that the address in flash_info->start was a physical address. However, from u-boot's point of view, and looking at most flash code, it makes more sense for this to be a virtual address. So I corrected the comment to indicate that this was a virtual address.
The only flash driver that was actually treating the address as physical was the mtd/cfi_flash driver. However, this code was using it inconsistently as it actually directly dereferenced the "start" element, while it used map_physmem to get a virtual address in other places. I changed this driver so that the code which initializes the info->start field calls map_physmem to get a virtual address, eliminating the need for further map_physmem calls. The code is now consistent.
The *only* place a physical address should be used is when defining the flash banks list that is used to initialize the flash_info struct. I have fixed the one platform that was impacted by this change (MPC8641D).
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
drivers/mtd/cfi_flash.c | 53 +++++++++++++++++ +---------------------- include/configs/MPC8641HPCN.h | 2 +- include/flash.h | 2 +- 3 files changed, 26 insertions(+), 31 deletions(-)
Stefan,
Have you reviewed this.
No, I must have forgotten about it. Thanks for reminding me. I'll have a closer look at it hopefully by tomorrow.
BTW: This patch needs to be split up in the CFI part and the MPC8641HPCN part.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Clean up PCI mapping concepts in the 8641 config - rename _BASE to _BUS, as it's actually a PCI bus address, separate virtual and physical addresses into _VIRT and _PHYS, and use each appopriately.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- board/freescale/mpc8641hpcn/mpc8641hpcn.c | 10 +++++----- include/configs/MPC8641HPCN.h | 17 +++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/board/freescale/mpc8641hpcn/mpc8641hpcn.c b/board/freescale/mpc8641hpcn/mpc8641hpcn.c index 9b6b69e..28c1683 100644 --- a/board/freescale/mpc8641hpcn/mpc8641hpcn.c +++ b/board/freescale/mpc8641hpcn/mpc8641hpcn.c @@ -165,14 +165,14 @@ void pci_init_board(void)
/* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCI1_MEM_BASE, + CONFIG_SYS_PCI1_MEM_BUS, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM);
/* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCI1_IO_BASE, + CONFIG_SYS_PCI1_IO_BUS, CONFIG_SYS_PCI1_IO_PHYS, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO); @@ -195,7 +195,7 @@ void pci_init_board(void) * Activate ULI1575 legacy chip by performing a fake * memory access. Needed to make ULI RTC work. */ - in_be32((unsigned *) ((char *)(CONFIG_SYS_PCI1_MEM_BASE + in_be32((unsigned *) ((char *)(CONFIG_SYS_PCI1_MEM_VIRT + CONFIG_SYS_PCI1_MEM_SIZE - 0x1000000)));
} else { @@ -214,14 +214,14 @@ void pci_init_board(void)
/* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCI2_MEM_BASE, + CONFIG_SYS_PCI2_MEM_BUS, CONFIG_SYS_PCI2_MEM_PHYS, CONFIG_SYS_PCI2_MEM_SIZE, PCI_REGION_MEM);
/* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCI2_IO_BASE, + CONFIG_SYS_PCI2_IO_BUS, CONFIG_SYS_PCI2_IO_PHYS, CONFIG_SYS_PCI2_IO_SIZE, PCI_REGION_IO); diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index c25380b..1d287ec 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -341,14 +341,17 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); * General PCI * Addresses are mapped 1-1. */ -#define CONFIG_SYS_PCI1_MEM_BASE 0x80000000 + +#define CONFIG_SYS_PCI1_MEM_VIRT 0x80000000 #ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_PCI1_MEM_BUS CONFIG_SYS_PCI1_MEM_VIRT #define CONFIG_SYS_PCI1_MEM_PHYS 0x0000000c00000000ULL #else -#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_BASE +#define CONFIG_SYS_PCI1_MEM_BUS CONFIG_SYS_PCI1_MEM_VIRT +#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_VIRT #endif #define CONFIG_SYS_PCI1_MEM_SIZE 0x20000000 /* 512M */ -#define CONFIG_SYS_PCI1_IO_BASE 0x00000000 +#define CONFIG_SYS_PCI1_IO_BUS 0x00000000 #define CONFIG_SYS_PCI1_IO_VIRT 0xffc00000 #define CONFIG_SYS_PCI1_IO_PHYS (CONFIG_SYS_PCI1_IO_VIRT \ | CONFIG_SYS_PHYS_ADDR_HIGH) @@ -358,12 +361,14 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define KSEG1ADDR(x) ({u32 _x=le32_to_cpu(*(u32 *)(x)); (&_x);}) #define _IO_BASE 0x00000000
-#define CONFIG_SYS_PCI2_MEM_BASE (CONFIG_SYS_PCI1_MEM_BASE \ +#define CONFIG_SYS_PCI2_MEM_BUS (CONFIG_SYS_PCI1_MEM_BUS \ + + CONFIG_SYS_PCI1_MEM_SIZE) +#define CONFIG_SYS_PCI2_MEM_VIRT (CONFIG_SYS_PCI1_MEM_VIRT \ + CONFIG_SYS_PCI1_MEM_SIZE) #define CONFIG_SYS_PCI2_MEM_PHYS (CONFIG_SYS_PCI1_MEM_PHYS \ + CONFIG_SYS_PCI1_MEM_SIZE) #define CONFIG_SYS_PCI2_MEM_SIZE 0x20000000 /* 512M */ -#define CONFIG_SYS_PCI2_IO_BASE 0x00000000 +#define CONFIG_SYS_PCI2_IO_BUS 0x00000000 #define CONFIG_SYS_PCI2_IO_VIRT (CONFIG_SYS_PCI1_IO_VIRT \ + CONFIG_SYS_PCI1_IO_SIZE) #define CONFIG_SYS_PCI2_IO_PHYS (CONFIG_SYS_PCI1_IO_PHYS \ @@ -511,7 +516,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SYS_DBAT2L (BAT_PHYS_ADDR(CONFIG_SYS_PCI1_MEM_PHYS) \ | BATL_PP_RW | BATL_CACHEINHIBIT \ | BATL_GUARDEDSTORAGE) -#define CONFIG_SYS_DBAT2U (CONFIG_SYS_PCI1_MEM_BASE | BATU_BL_1G \ +#define CONFIG_SYS_DBAT2U (CONFIG_SYS_PCI1_MEM_VIRT | BATU_BL_1G \ | BATU_VS | BATU_VP) #define CONFIG_SYS_IBAT2L (BAT_PHYS_ADDR(CONFIG_SYS_PCI1_MEM_PHYS) \ | BATL_PP_RW | BATL_CACHEINHIBIT)

Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- include/configs/MPC8641HPCN.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 1d287ec..7f69611 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -39,6 +39,7 @@ #define CONFIG_NUM_CPUS 2 /* Number of CPUs in the system */ #define CONFIG_LINUX_RESET_VEC 0x100 /* Reset vector used by Linux */ /*#define CONFIG_PHYS_64BIT 1*/ /* Place devices in 36-bit space */ +#define CONFIG_ADDR_MAP 1 /* Use addr map */
#ifdef RUN_DIAG #define CONFIG_SYS_DIAG_ADDR CONFIG_SYS_FLASH_BASE @@ -70,6 +71,7 @@ #define CONFIG_ENV_OVERWRITE
#define CONFIG_HIGH_BATS 1 /* High BATs supported and enabled */ +#define CONFIG_SYS_NUM_ADDR_MAP 8 /* Number of addr map slots = 8 dbats */
#define CONFIG_ALTIVEC 1

The code assumes that the pci bus address and the virtual address used to access a region are the same, but they might not be. Fix this assumption.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- drivers/block/ahci.c | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 2445e8c..e1b66fd 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -251,7 +251,6 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
static int ahci_init_one(pci_dev_t pdev) { - u32 iobase; u16 vendor; int rc;
@@ -261,9 +260,6 @@ static int ahci_init_one(pci_dev_t pdev) memset(probe_ent, 0, sizeof(struct ahci_probe_ent)); probe_ent->dev = pdev;
- pci_read_config_dword(pdev, AHCI_PCI_BAR, &iobase); - iobase &= ~0xf; - probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO @@ -272,7 +268,8 @@ static int ahci_init_one(pci_dev_t pdev) probe_ent->pio_mask = 0x1f; probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
- probe_ent->mmio_base = iobase; + probe_ent->mmio_base = (u32)pci_map_bar(pdev, AHCI_PCI_BAR, + PCI_REGION_MEM);
/* Take from kernel: * JMicron-specific fixup:

On Dec 3, 2008, at 11:04 PM, Becky Bruce wrote:
The code assumes that the pci bus address and the virtual address used to access a region are the same, but they might not be. Fix this assumption.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org
drivers/block/ahci.c | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-)
Wolfgang,
What about picking this up?
- k

Now that the rest of u-boot can support it, change the PCI bus address of the PCI MEM regions from 0x80000000 to 0xc0000000, and use the same bus address for both PCI1 and PCI2. This will maximize the amount of PCI address space left over to map RAM on systems with large amounts of memory.
Signed-off-by: Becky Bruce beckyb@kernel.crashing.org --- include/configs/MPC8641HPCN.h | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 7f69611..a54e7d0 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -346,7 +346,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
#define CONFIG_SYS_PCI1_MEM_VIRT 0x80000000 #ifdef CONFIG_PHYS_64BIT -#define CONFIG_SYS_PCI1_MEM_BUS CONFIG_SYS_PCI1_MEM_VIRT +#define CONFIG_SYS_PCI1_MEM_BUS 0xc0000000 #define CONFIG_SYS_PCI1_MEM_PHYS 0x0000000c00000000ULL #else #define CONFIG_SYS_PCI1_MEM_BUS CONFIG_SYS_PCI1_MEM_VIRT @@ -363,8 +363,17 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define KSEG1ADDR(x) ({u32 _x=le32_to_cpu(*(u32 *)(x)); (&_x);}) #define _IO_BASE 0x00000000
+#ifdef CONFIG_PHYS_64BIT +/* + * Use the same PCI bus address on PCI1 and PCI2 if we have PHYS_64BIT. + * This will increase the amount of PCI address space available for + * for mapping RAM. + */ +#define CONFIG_SYS_PCI2_MEM_BUS CONFIG_SYS_PCI1_MEM_BUS +#else #define CONFIG_SYS_PCI2_MEM_BUS (CONFIG_SYS_PCI1_MEM_BUS \ + CONFIG_SYS_PCI1_MEM_SIZE) +#endif #define CONFIG_SYS_PCI2_MEM_VIRT (CONFIG_SYS_PCI1_MEM_VIRT \ + CONFIG_SYS_PCI1_MEM_SIZE) #define CONFIG_SYS_PCI2_MEM_PHYS (CONFIG_SYS_PCI1_MEM_PHYS \
participants (5)
-
Becky Bruce
-
Haavard Skinnemoen
-
Kumar Gala
-
Stefan Roese
-
Wolfgang Denk