0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mm.h>
0011 #include <linux/memblock.h>
0012 #include <linux/types.h>
0013
0014 #include <asm/addrspace.h>
0015 #include <asm/dec/machtype.h>
0016 #include <asm/dec/prom.h>
0017 #include <asm/page.h>
0018 #include <asm/sections.h>
0019
0020
0021 volatile unsigned long mem_err;
0022
0023
0024
0025
0026
0027
0028 #define CHUNK_SIZE 0x400000
0029
0030 static __init void pmax_setup_memory_region(void)
0031 {
0032 volatile unsigned char *memory_page, dummy;
0033 char old_handler[0x80];
0034 extern char genexcept_early;
0035
0036
0037 memcpy(&old_handler, (void *)(CKSEG0 + 0x80), 0x80);
0038 memcpy((void *)(CKSEG0 + 0x80), &genexcept_early, 0x80);
0039
0040
0041
0042
0043
0044
0045 for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE;
0046 mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000;
0047 memory_page += CHUNK_SIZE) {
0048 dummy = *memory_page;
0049 }
0050 memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
0051
0052 memblock_add(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE);
0053 }
0054
0055
0056
0057
0058
0059 static __init void rex_setup_memory_region(void)
0060 {
0061 int i, bitmap_size;
0062 unsigned long mem_start = 0, mem_size = 0;
0063 memmap *bm;
0064
0065
0066 bm = (memmap *)CKSEG0ADDR(0x28000);
0067
0068 bitmap_size = rex_getbitmap(bm);
0069
0070 for (i = 0; i < bitmap_size; i++) {
0071
0072 if (bm->bitmap[i] == 0xff)
0073 mem_size += (8 * bm->pagesize);
0074 else if (!mem_size)
0075 mem_start += (8 * bm->pagesize);
0076 else {
0077 memblock_add(mem_start, mem_size);
0078 mem_start += mem_size + (8 * bm->pagesize);
0079 mem_size = 0;
0080 }
0081 }
0082 if (mem_size)
0083 memblock_add(mem_start, mem_size);
0084 }
0085
0086 void __init prom_meminit(u32 magic)
0087 {
0088 if (!prom_is_rex(magic))
0089 pmax_setup_memory_region();
0090 else
0091 rex_setup_memory_region();
0092 }
0093
0094 void __init prom_free_prom_memory(void)
0095 {
0096 unsigned long end;
0097
0098
0099
0100
0101
0102
0103 #if IS_ENABLED(CONFIG_DECLANCE)
0104
0105
0106
0107
0108
0109
0110 if (IOASIC)
0111 end = __pa(&_text) - 0x00020000;
0112 else
0113 #endif
0114 end = __pa(&_text);
0115
0116 free_init_pages("unused PROM memory", PAGE_SIZE, end);
0117 }