0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/init.h>
0016 #include <linux/kernel.h>
0017 #include <linux/types.h>
0018 #include <linux/sched.h>
0019 #include <linux/mm.h>
0020 #include <linux/memblock.h>
0021 #include <linux/swap.h>
0022
0023 #include <asm/sgialib.h>
0024 #include <asm/page.h>
0025 #include <asm/bootinfo.h>
0026
0027 #undef DEBUG
0028
0029 #define MAX_PROM_MEM 5
0030 static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
0031 static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
0032 static unsigned int nr_prom_mem __initdata;
0033
0034
0035
0036
0037
0038 #define ARC_PAGE_SHIFT 12
0039
0040 struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
0041 {
0042 return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
0043 }
0044
0045 #ifdef DEBUG
0046 static char *arcs_mtypes[8] = {
0047 "Exception Block",
0048 "ARCS Romvec Page",
0049 "Free/Contig RAM",
0050 "Generic Free RAM",
0051 "Bad Memory",
0052 "Standalone Program Pages",
0053 "ARCS Temp Storage Area",
0054 "ARCS Permanent Storage Area"
0055 };
0056
0057 static char *arc_mtypes[8] = {
0058 "Exception Block",
0059 "SystemParameterBlock",
0060 "FreeMemory",
0061 "Bad Memory",
0062 "LoadedProgram",
0063 "FirmwareTemporary",
0064 "FirmwarePermanent",
0065 "FreeContiguous"
0066 };
0067 #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
0068 : arc_mtypes[a.arc]
0069 #endif
0070
0071 enum {
0072 mem_free, mem_prom_used, mem_reserved
0073 };
0074
0075 static inline int memtype_classify_arcs(union linux_memtypes type)
0076 {
0077 switch (type.arcs) {
0078 case arcs_fcontig:
0079 case arcs_free:
0080 return mem_free;
0081 case arcs_atmp:
0082 return mem_prom_used;
0083 case arcs_eblock:
0084 case arcs_rvpage:
0085 case arcs_bmem:
0086 case arcs_prog:
0087 case arcs_aperm:
0088 return mem_reserved;
0089 default:
0090 BUG();
0091 }
0092 while(1);
0093 }
0094
0095 static inline int memtype_classify_arc(union linux_memtypes type)
0096 {
0097 switch (type.arc) {
0098 case arc_free:
0099 case arc_fcontig:
0100 return mem_free;
0101 case arc_atmp:
0102 return mem_prom_used;
0103 case arc_eblock:
0104 case arc_rvpage:
0105 case arc_bmem:
0106 case arc_prog:
0107 case arc_aperm:
0108 return mem_reserved;
0109 default:
0110 BUG();
0111 }
0112 while(1);
0113 }
0114
0115 static int __init prom_memtype_classify(union linux_memtypes type)
0116 {
0117 if (prom_flags & PROM_FLAG_ARCS)
0118 return memtype_classify_arcs(type);
0119
0120 return memtype_classify_arc(type);
0121 }
0122
0123 void __weak __init prom_meminit(void)
0124 {
0125 struct linux_mdesc *p;
0126
0127 #ifdef DEBUG
0128 int i = 0;
0129
0130 printk("ARCS MEMORY DESCRIPTOR dump:\n");
0131 p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
0132 while(p) {
0133 printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
0134 i, p, p->base, p->pages, mtypes(p->type));
0135 p = ArcGetMemoryDescriptor(p);
0136 i++;
0137 }
0138 #endif
0139
0140 nr_prom_mem = 0;
0141 p = PROM_NULL_MDESC;
0142 while ((p = ArcGetMemoryDescriptor(p))) {
0143 unsigned long base, size;
0144 long type;
0145
0146 base = p->base << ARC_PAGE_SHIFT;
0147 size = p->pages << ARC_PAGE_SHIFT;
0148 type = prom_memtype_classify(p->type);
0149
0150
0151 if (base < PHYS_OFFSET)
0152 continue;
0153
0154 memblock_add(base, size);
0155
0156 if (type == mem_reserved)
0157 memblock_reserve(base, size);
0158
0159 if (type == mem_prom_used) {
0160 memblock_reserve(base, size);
0161 if (nr_prom_mem >= 5) {
0162 pr_err("Too many ROM DATA regions");
0163 continue;
0164 }
0165 prom_mem_base[nr_prom_mem] = base;
0166 prom_mem_size[nr_prom_mem] = size;
0167 nr_prom_mem++;
0168 }
0169 }
0170 }
0171
0172 void __weak __init prom_cleanup(void)
0173 {
0174 }
0175
0176 void __init prom_free_prom_memory(void)
0177 {
0178 int i;
0179
0180 if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
0181 return;
0182
0183 for (i = 0; i < nr_prom_mem; i++) {
0184 free_init_pages("prom memory",
0185 prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
0186 }
0187
0188
0189
0190
0191 prom_cleanup();
0192 }