xref: /linux/arch/mips/fw/arc/memory.c (revision b7019ac550eb3916f34d79db583e9b7ea2524afa)
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/memblock.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