diff options
author | Ilya Yanok <yanok@emcraft.com> | 2008-12-10 20:55:41 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-12-28 17:53:25 -0500 |
commit | ca9153a3a2a7556d091dfe080e42b0e67881fff6 (patch) | |
tree | 35b5ce24f190690cf7a726cbb97980da51704855 /arch/powerpc/include | |
parent | 6ca4f7494bde078b2b730e28e4ea1dc36a772f70 (diff) |
powerpc/44x: Support 16K/64K base page sizes on 44x
This adds support for 16k and 64k page sizes on PowerPC 44x processors.
The PGDIR table is much smaller than a page when using 16k or 64k
pages (512 and 32 bytes respectively) so we allocate the PGDIR with
kzalloc() instead of __get_free_pages().
One PTE table covers rather a large memory area when using 16k or 64k
pages (32MB or 512MB respectively), so we can easily put FIXMAP and
PKMAP in the area covered by one PTE table.
Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
Signed-off-by: Vladimir Panfilov <pvr@emcraft.com>
Signed-off-by: Ilya Yanok <yanok@emcraft.com>
Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r-- | arch/powerpc/include/asm/highmem.h | 19 | ||||
-rw-r--r-- | arch/powerpc/include/asm/mmu-44x.h | 17 | ||||
-rw-r--r-- | arch/powerpc/include/asm/page.h | 13 | ||||
-rw-r--r-- | arch/powerpc/include/asm/page_32.h | 7 |
4 files changed, 47 insertions, 9 deletions
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index fd97e501aa6a..04e4a620952e 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h | |||
@@ -38,9 +38,24 @@ extern pte_t *pkmap_page_table; | |||
38 | * easily, subsequent pte tables have to be allocated in one physical | 38 | * easily, subsequent pte tables have to be allocated in one physical |
39 | * chunk of RAM. | 39 | * chunk of RAM. |
40 | */ | 40 | */ |
41 | #define LAST_PKMAP (1 << PTE_SHIFT) | 41 | /* |
42 | #define LAST_PKMAP_MASK (LAST_PKMAP-1) | 42 | * We use one full pte table with 4K pages. And with 16K/64K pages pte |
43 | * table covers enough memory (32MB and 512MB resp.) that both FIXMAP | ||
44 | * and PKMAP can be placed in single pte table. We use 1024 pages for | ||
45 | * PKMAP in case of 16K/64K pages. | ||
46 | */ | ||
47 | #ifdef CONFIG_PPC_4K_PAGES | ||
48 | #define PKMAP_ORDER PTE_SHIFT | ||
49 | #else | ||
50 | #define PKMAP_ORDER 10 | ||
51 | #endif | ||
52 | #define LAST_PKMAP (1 << PKMAP_ORDER) | ||
53 | #ifndef CONFIG_PPC_4K_PAGES | ||
54 | #define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) | ||
55 | #else | ||
43 | #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) | 56 | #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) |
57 | #endif | ||
58 | #define LAST_PKMAP_MASK (LAST_PKMAP-1) | ||
44 | #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) | 59 | #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) |
45 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | 60 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) |
46 | 61 | ||
diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/mmu-44x.h index b21af32ac6d6..8a97cfb08b7e 100644 --- a/arch/powerpc/include/asm/mmu-44x.h +++ b/arch/powerpc/include/asm/mmu-44x.h | |||
@@ -4,6 +4,8 @@ | |||
4 | * PPC440 support | 4 | * PPC440 support |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <asm/page.h> | ||
8 | |||
7 | #define PPC44x_MMUCR_TID 0x000000ff | 9 | #define PPC44x_MMUCR_TID 0x000000ff |
8 | #define PPC44x_MMUCR_STS 0x00010000 | 10 | #define PPC44x_MMUCR_STS 0x00010000 |
9 | 11 | ||
@@ -74,4 +76,19 @@ typedef struct { | |||
74 | /* Size of the TLBs used for pinning in lowmem */ | 76 | /* Size of the TLBs used for pinning in lowmem */ |
75 | #define PPC_PIN_SIZE (1 << 28) /* 256M */ | 77 | #define PPC_PIN_SIZE (1 << 28) /* 256M */ |
76 | 78 | ||
79 | #if (PAGE_SHIFT == 12) | ||
80 | #define PPC44x_TLBE_SIZE PPC44x_TLB_4K | ||
81 | #elif (PAGE_SHIFT == 14) | ||
82 | #define PPC44x_TLBE_SIZE PPC44x_TLB_16K | ||
83 | #elif (PAGE_SHIFT == 16) | ||
84 | #define PPC44x_TLBE_SIZE PPC44x_TLB_64K | ||
85 | #else | ||
86 | #error "Unsupported PAGE_SIZE" | ||
87 | #endif | ||
88 | |||
89 | #define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) | ||
90 | #define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2) | ||
91 | #define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2) | ||
92 | #define PPC44x_PTE_ADD_MASK_BIT (32 - PTE_T_LOG2 - PTE_SHIFT) | ||
93 | |||
77 | #endif /* _ASM_POWERPC_MMU_44X_H_ */ | 94 | #endif /* _ASM_POWERPC_MMU_44X_H_ */ |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index c0b8d4a29a91..197d569f5bd3 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
@@ -19,12 +19,15 @@ | |||
19 | #include <asm/kdump.h> | 19 | #include <asm/kdump.h> |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software | 22 | * On regular PPC32 page size is 4K (but we support 4K/16K/64K pages |
23 | * on PPC44x). For PPC64 we support either 4K or 64K software | ||
23 | * page size. When using 64K pages however, whether we are really supporting | 24 | * page size. When using 64K pages however, whether we are really supporting |
24 | * 64K pages in HW or not is irrelevant to those definitions. | 25 | * 64K pages in HW or not is irrelevant to those definitions. |
25 | */ | 26 | */ |
26 | #ifdef CONFIG_PPC_64K_PAGES | 27 | #if defined(CONFIG_PPC_64K_PAGES) |
27 | #define PAGE_SHIFT 16 | 28 | #define PAGE_SHIFT 16 |
29 | #elif defined(CONFIG_PPC_16K_PAGES) | ||
30 | #define PAGE_SHIFT 14 | ||
28 | #else | 31 | #else |
29 | #define PAGE_SHIFT 12 | 32 | #define PAGE_SHIFT 12 |
30 | #endif | 33 | #endif |
@@ -151,7 +154,7 @@ typedef struct { pte_basic_t pte; } pte_t; | |||
151 | /* 64k pages additionally define a bigger "real PTE" type that gathers | 154 | /* 64k pages additionally define a bigger "real PTE" type that gathers |
152 | * the "second half" part of the PTE for pseudo 64k pages | 155 | * the "second half" part of the PTE for pseudo 64k pages |
153 | */ | 156 | */ |
154 | #ifdef CONFIG_PPC_64K_PAGES | 157 | #if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) |
155 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | 158 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; |
156 | #else | 159 | #else |
157 | typedef struct { pte_t pte; } real_pte_t; | 160 | typedef struct { pte_t pte; } real_pte_t; |
@@ -191,10 +194,10 @@ typedef pte_basic_t pte_t; | |||
191 | #define pte_val(x) (x) | 194 | #define pte_val(x) (x) |
192 | #define __pte(x) (x) | 195 | #define __pte(x) (x) |
193 | 196 | ||
194 | #ifdef CONFIG_PPC_64K_PAGES | 197 | #if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) |
195 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | 198 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; |
196 | #else | 199 | #else |
197 | typedef unsigned long real_pte_t; | 200 | typedef pte_t real_pte_t; |
198 | #endif | 201 | #endif |
199 | 202 | ||
200 | 203 | ||
diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h index d77072a32cc6..1458d9500381 100644 --- a/arch/powerpc/include/asm/page_32.h +++ b/arch/powerpc/include/asm/page_32.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #define PTE_FLAGS_OFFSET 0 | 19 | #define PTE_FLAGS_OFFSET 0 |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2) /* full page */ | ||
23 | |||
22 | #ifndef __ASSEMBLY__ | 24 | #ifndef __ASSEMBLY__ |
23 | /* | 25 | /* |
24 | * The basic type of a PTE - 64 bits for those CPUs with > 32 bit | 26 | * The basic type of a PTE - 64 bits for those CPUs with > 32 bit |
@@ -26,10 +28,8 @@ | |||
26 | */ | 28 | */ |
27 | #ifdef CONFIG_PTE_64BIT | 29 | #ifdef CONFIG_PTE_64BIT |
28 | typedef unsigned long long pte_basic_t; | 30 | typedef unsigned long long pte_basic_t; |
29 | #define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */ | ||
30 | #else | 31 | #else |
31 | typedef unsigned long pte_basic_t; | 32 | typedef unsigned long pte_basic_t; |
32 | #define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */ | ||
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | struct page; | 35 | struct page; |
@@ -39,6 +39,9 @@ extern void copy_page(void *to, void *from); | |||
39 | 39 | ||
40 | #include <asm-generic/page.h> | 40 | #include <asm-generic/page.h> |
41 | 41 | ||
42 | #define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) | ||
43 | #define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1) | ||
44 | |||
42 | #endif /* __ASSEMBLY__ */ | 45 | #endif /* __ASSEMBLY__ */ |
43 | 46 | ||
44 | #endif /* _ASM_POWERPC_PAGE_32_H */ | 47 | #endif /* _ASM_POWERPC_PAGE_32_H */ |