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