Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * memory.c: memory initialisation code. | |
3 | * | |
4 | * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine | |
5 | * Copyright (C) 2000, 2002 Maciej W. Rozycki | |
6 | */ | |
1da177e4 LT |
7 | #include <linux/init.h> |
8 | #include <linux/kernel.h> | |
9 | #include <linux/mm.h> | |
10 | #include <linux/bootmem.h> | |
11 | #include <linux/types.h> | |
12 | ||
13 | #include <asm/addrspace.h> | |
14 | #include <asm/bootinfo.h> | |
15 | #include <asm/dec/machtype.h> | |
16 | #include <asm/dec/prom.h> | |
17 | #include <asm/page.h> | |
18 | #include <asm/sections.h> | |
19 | ||
20 | ||
982f6ffe | 21 | volatile unsigned long mem_err; /* So we know an error occurred */ |
1da177e4 LT |
22 | |
23 | /* | |
24 | * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen | |
07217d75 | 25 | * off the end of real memory. Only suitable for the 2100/3100's (PMAX). |
1da177e4 LT |
26 | */ |
27 | ||
28 | #define CHUNK_SIZE 0x400000 | |
29 | ||
30 | static inline void pmax_setup_memory_region(void) | |
31 | { | |
32 | volatile unsigned char *memory_page, dummy; | |
33 | char old_handler[0x80]; | |
34 | extern char genexcept_early; | |
35 | ||
36 | /* Install exception handler */ | |
3bd4c902 MR |
37 | memcpy(&old_handler, (void *)(CKSEG0 + 0x80), 0x80); |
38 | memcpy((void *)(CKSEG0 + 0x80), &genexcept_early, 0x80); | |
1da177e4 LT |
39 | |
40 | /* read unmapped and uncached (KSEG1) | |
41 | * DECstations have at least 4MB RAM | |
42 | * Assume less than 480MB of RAM, as this is max for 5000/2xx | |
43 | * FIXME this should be replaced by the first free page! | |
44 | */ | |
3bd4c902 MR |
45 | for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE; |
46 | mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000; | |
a3dddd56 | 47 | memory_page += CHUNK_SIZE) { |
1da177e4 LT |
48 | dummy = *memory_page; |
49 | } | |
3bd4c902 | 50 | memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80); |
1da177e4 | 51 | |
3bd4c902 | 52 | add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE, |
1da177e4 LT |
53 | BOOT_MEM_RAM); |
54 | } | |
55 | ||
56 | /* | |
57 | * Use the REX prom calls to get hold of the memory bitmap, and thence | |
58 | * determine memory size. | |
59 | */ | |
60 | static inline void rex_setup_memory_region(void) | |
61 | { | |
62 | int i, bitmap_size; | |
63 | unsigned long mem_start = 0, mem_size = 0; | |
64 | memmap *bm; | |
65 | ||
66 | /* some free 64k */ | |
3bd4c902 | 67 | bm = (memmap *)CKSEG0ADDR(0x28000); |
1da177e4 LT |
68 | |
69 | bitmap_size = rex_getbitmap(bm); | |
70 | ||
71 | for (i = 0; i < bitmap_size; i++) { | |
72 | /* FIXME: very simplistically only add full sets of pages */ | |
73 | if (bm->bitmap[i] == 0xff) | |
74 | mem_size += (8 * bm->pagesize); | |
75 | else if (!mem_size) | |
76 | mem_start += (8 * bm->pagesize); | |
77 | else { | |
78 | add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); | |
79 | mem_start += mem_size + (8 * bm->pagesize); | |
80 | mem_size = 0; | |
81 | } | |
82 | } | |
83 | if (mem_size) | |
84 | add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); | |
85 | } | |
86 | ||
87 | void __init prom_meminit(u32 magic) | |
88 | { | |
89 | if (!prom_is_rex(magic)) | |
90 | pmax_setup_memory_region(); | |
91 | else | |
92 | rex_setup_memory_region(); | |
93 | } | |
94 | ||
c44e8d5e | 95 | void __init prom_free_prom_memory(void) |
1da177e4 | 96 | { |
c44e8d5e | 97 | unsigned long end; |
1da177e4 LT |
98 | |
99 | /* | |
100 | * Free everything below the kernel itself but leave | |
101 | * the first page reserved for the exception handlers. | |
102 | */ | |
103 | ||
baf69e27 | 104 | #if IS_ENABLED(CONFIG_DECLANCE) |
1da177e4 LT |
105 | /* |
106 | * Leave 128 KB reserved for Lance memory for | |
107 | * IOASIC DECstations. | |
108 | * | |
109 | * XXX: save this address for use in dec_lance.c? | |
110 | */ | |
111 | if (IOASIC) | |
112 | end = __pa(&_text) - 0x00020000; | |
113 | else | |
114 | #endif | |
115 | end = __pa(&_text); | |
116 | ||
c44e8d5e | 117 | free_init_pages("unused PROM memory", PAGE_SIZE, end); |
1da177e4 | 118 | } |