1 /* 2 * memory.c: PROM library functions for acquiring/using memory descriptors 3 * given to us from the ARCS firmware. 4 * 5 * Copyright (C) 1996 by David S. Miller 6 * Copyright (C) 1999, 2000, 2001 by Ralf Baechle 7 * Copyright (C) 1999, 2000 by Silicon Graphics, Inc. 8 * 9 * PROM library functions for acquiring/using memory descriptors given to us 10 * from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set 11 * because on some machines like SGI IP27 the ARC memory configuration data 12 * completly bogus and alternate easier to use mechanisms are available. 13 */ 14 #include <linux/init.h> 15 #include <linux/kernel.h> 16 #include <linux/types.h> 17 #include <linux/sched.h> 18 #include <linux/mm.h> 19 #include <linux/bootmem.h> 20 #include <linux/swap.h> 21 22 #include <asm/sgialib.h> 23 #include <asm/page.h> 24 #include <asm/pgtable.h> 25 #include <asm/bootinfo.h> 26 27 #undef DEBUG 28 29 /* 30 * For ARC firmware memory functions the unit of meassuring memory is always 31 * a 4k page of memory 32 */ 33 #define ARC_PAGE_SHIFT 12 34 35 struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current) 36 { 37 return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); 38 } 39 40 #ifdef DEBUG /* convenient for debugging */ 41 static char *arcs_mtypes[8] = { 42 "Exception Block", 43 "ARCS Romvec Page", 44 "Free/Contig RAM", 45 "Generic Free RAM", 46 "Bad Memory", 47 "Standalone Program Pages", 48 "ARCS Temp Storage Area", 49 "ARCS Permanent Storage Area" 50 }; 51 52 static char *arc_mtypes[8] = { 53 "Exception Block", 54 "SystemParameterBlock", 55 "FreeMemory", 56 "Bad Memory", 57 "LoadedProgram", 58 "FirmwareTemporary", 59 "FirmwarePermanent", 60 "FreeContiguous" 61 }; 62 #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \ 63 : arc_mtypes[a.arc] 64 #endif 65 66 static inline int memtype_classify_arcs(union linux_memtypes type) 67 { 68 switch (type.arcs) { 69 case arcs_fcontig: 70 case arcs_free: 71 return BOOT_MEM_RAM; 72 case arcs_atmp: 73 return BOOT_MEM_ROM_DATA; 74 case arcs_eblock: 75 case arcs_rvpage: 76 case arcs_bmem: 77 case arcs_prog: 78 case arcs_aperm: 79 return BOOT_MEM_RESERVED; 80 default: 81 BUG(); 82 } 83 while(1); /* Nuke warning. */ 84 } 85 86 static inline int memtype_classify_arc(union linux_memtypes type) 87 { 88 switch (type.arc) { 89 case arc_free: 90 case arc_fcontig: 91 return BOOT_MEM_RAM; 92 case arc_atmp: 93 return BOOT_MEM_ROM_DATA; 94 case arc_eblock: 95 case arc_rvpage: 96 case arc_bmem: 97 case arc_prog: 98 case arc_aperm: 99 return BOOT_MEM_RESERVED; 100 default: 101 BUG(); 102 } 103 while(1); /* Nuke warning. */ 104 } 105 106 static int __init prom_memtype_classify(union linux_memtypes type) 107 { 108 if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */ 109 return memtype_classify_arcs(type); 110 111 return memtype_classify_arc(type); 112 } 113 114 void __init prom_meminit(void) 115 { 116 struct linux_mdesc *p; 117 118 #ifdef DEBUG 119 int i = 0; 120 121 printk("ARCS MEMORY DESCRIPTOR dump:\n"); 122 p = ArcGetMemoryDescriptor(PROM_NULL_MDESC); 123 while(p) { 124 printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n", 125 i, p, p->base, p->pages, mtypes(p->type)); 126 p = ArcGetMemoryDescriptor(p); 127 i++; 128 } 129 #endif 130 131 p = PROM_NULL_MDESC; 132 while ((p = ArcGetMemoryDescriptor(p))) { 133 unsigned long base, size; 134 long type; 135 136 base = p->base << ARC_PAGE_SHIFT; 137 size = p->pages << ARC_PAGE_SHIFT; 138 type = prom_memtype_classify(p->type); 139 140 add_memory_region(base, size, type); 141 } 142 } 143 144 void __init prom_free_prom_memory(void) 145 { 146 unsigned long addr; 147 int i; 148 149 if (prom_flags & PROM_FLAG_DONT_FREE_TEMP) 150 return; 151 152 for (i = 0; i < boot_mem_map.nr_map; i++) { 153 if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) 154 continue; 155 156 addr = boot_mem_map.map[i].addr; 157 free_init_pages("prom memory", 158 addr, addr + boot_mem_map.map[i].size); 159 } 160 } 161