1/* 2 * linux/arch/arm/kernel/compat.c 3 * 4 * Copyright (C) 2001 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * We keep the old params compatibility cruft in one place (here) 11 * so we don't end up with lots of mess around other places. 12 * 13 * NOTE: 14 * The old struct param_struct is deprecated, but it will be kept in 15 * the kernel for 5 years from now (2001). This will allow boot loaders 16 * to convert to the new struct tag way. 17 */ 18#include <linux/types.h> 19#include <linux/kernel.h> 20#include <linux/string.h> 21#include <linux/init.h> 22 23#include <asm/setup.h> 24#include <asm/mach-types.h> 25#include <asm/page.h> 26 27#include <asm/mach/arch.h> 28 29#include "compat.h" 30 31/* 32 * Usage: 33 * - do not go blindly adding fields, add them at the end 34 * - when adding fields, don't rely on the address until 35 * a patch from me has been released 36 * - unused fields should be zero (for future expansion) 37 * - this structure is relatively short-lived - only 38 * guaranteed to contain useful data in setup_arch() 39 * 40 * This is the old deprecated way to pass parameters to the kernel 41 */ 42struct param_struct { 43 union { 44 struct { 45 unsigned long page_size; /* 0 */ 46 unsigned long nr_pages; /* 4 */ 47 unsigned long ramdisk_size; /* 8 */ 48 unsigned long flags; /* 12 */ 49#define FLAG_READONLY 1 50#define FLAG_RDLOAD 4 51#define FLAG_RDPROMPT 8 52 unsigned long rootdev; /* 16 */ 53 unsigned long video_num_cols; /* 20 */ 54 unsigned long video_num_rows; /* 24 */ 55 unsigned long video_x; /* 28 */ 56 unsigned long video_y; /* 32 */ 57 unsigned long memc_control_reg; /* 36 */ 58 unsigned char sounddefault; /* 40 */ 59 unsigned char adfsdrives; /* 41 */ 60 unsigned char bytes_per_char_h; /* 42 */ 61 unsigned char bytes_per_char_v; /* 43 */ 62 unsigned long pages_in_bank[4]; /* 44 */ 63 unsigned long pages_in_vram; /* 60 */ 64 unsigned long initrd_start; /* 64 */ 65 unsigned long initrd_size; /* 68 */ 66 unsigned long rd_start; /* 72 */ 67 unsigned long system_rev; /* 76 */ 68 unsigned long system_serial_low; /* 80 */ 69 unsigned long system_serial_high; /* 84 */ 70 unsigned long mem_fclk_21285; /* 88 */ 71 } s; 72 char unused[256]; 73 } u1; 74 union { 75 char paths[8][128]; 76 struct { 77 unsigned long magic; 78 char n[1024 - sizeof(unsigned long)]; 79 } s; 80 } u2; 81 char commandline[COMMAND_LINE_SIZE]; 82}; 83 84static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size) 85{ 86 tag = tag_next(tag); 87 tag->hdr.tag = ATAG_MEM; 88 tag->hdr.size = tag_size(tag_mem32); 89 tag->u.mem.size = size; 90 tag->u.mem.start = start; 91 92 return tag; 93} 94 95static void __init build_tag_list(struct param_struct *params, void *taglist) 96{ 97 struct tag *tag = taglist; 98 99 if (params->u1.s.page_size != PAGE_SIZE) { 100 printk(KERN_WARNING "Warning: bad configuration page, " 101 "trying to continue\n"); 102 return; 103 } 104 105 printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); 106 107#ifdef CONFIG_ARCH_NETWINDER 108 if (params->u1.s.nr_pages != 0x02000 && 109 params->u1.s.nr_pages != 0x04000 && 110 params->u1.s.nr_pages != 0x08000 && 111 params->u1.s.nr_pages != 0x10000) { 112 printk(KERN_WARNING "Warning: bad NeTTrom parameters " 113 "detected, using defaults\n"); 114 115 params->u1.s.nr_pages = 0x1000; /* 16MB */ 116 params->u1.s.ramdisk_size = 0; 117 params->u1.s.flags = FLAG_READONLY; 118 params->u1.s.initrd_start = 0; 119 params->u1.s.initrd_size = 0; 120 params->u1.s.rd_start = 0; 121 } 122#endif 123 124 tag->hdr.tag = ATAG_CORE; 125 tag->hdr.size = tag_size(tag_core); 126 tag->u.core.flags = params->u1.s.flags & FLAG_READONLY; 127 tag->u.core.pagesize = params->u1.s.page_size; 128 tag->u.core.rootdev = params->u1.s.rootdev; 129 130 tag = tag_next(tag); 131 tag->hdr.tag = ATAG_RAMDISK; 132 tag->hdr.size = tag_size(tag_ramdisk); 133 tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) | 134 (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0); 135 tag->u.ramdisk.size = params->u1.s.ramdisk_size; 136 tag->u.ramdisk.start = params->u1.s.rd_start; 137 138 tag = tag_next(tag); 139 tag->hdr.tag = ATAG_INITRD; 140 tag->hdr.size = tag_size(tag_initrd); 141 tag->u.initrd.start = params->u1.s.initrd_start; 142 tag->u.initrd.size = params->u1.s.initrd_size; 143 144 tag = tag_next(tag); 145 tag->hdr.tag = ATAG_SERIAL; 146 tag->hdr.size = tag_size(tag_serialnr); 147 tag->u.serialnr.low = params->u1.s.system_serial_low; 148 tag->u.serialnr.high = params->u1.s.system_serial_high; 149 150 tag = tag_next(tag); 151 tag->hdr.tag = ATAG_REVISION; 152 tag->hdr.size = tag_size(tag_revision); 153 tag->u.revision.rev = params->u1.s.system_rev; 154 155#ifdef CONFIG_ARCH_ACORN 156 if (machine_is_riscpc()) { 157 int i; 158 for (i = 0; i < 4; i++) 159 tag = memtag(tag, PHYS_OFFSET + (i << 26), 160 params->u1.s.pages_in_bank[i] * PAGE_SIZE); 161 } else 162#endif 163 tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); 164 165#ifdef CONFIG_FOOTBRIDGE 166 if (params->u1.s.mem_fclk_21285) { 167 tag = tag_next(tag); 168 tag->hdr.tag = ATAG_MEMCLK; 169 tag->hdr.size = tag_size(tag_memclk); 170 tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285; 171 } 172#endif 173 174#ifdef CONFIG_ARCH_EBSA285 175 if (machine_is_ebsa285()) { 176 tag = tag_next(tag); 177 tag->hdr.tag = ATAG_VIDEOTEXT; 178 tag->hdr.size = tag_size(tag_videotext); 179 tag->u.videotext.x = params->u1.s.video_x; 180 tag->u.videotext.y = params->u1.s.video_y; 181 tag->u.videotext.video_page = 0; 182 tag->u.videotext.video_mode = 0; 183 tag->u.videotext.video_cols = params->u1.s.video_num_cols; 184 tag->u.videotext.video_ega_bx = 0; 185 tag->u.videotext.video_lines = params->u1.s.video_num_rows; 186 tag->u.videotext.video_isvga = 1; 187 tag->u.videotext.video_points = 8; 188 } 189#endif 190 191#ifdef CONFIG_ARCH_ACORN 192 tag = tag_next(tag); 193 tag->hdr.tag = ATAG_ACORN; 194 tag->hdr.size = tag_size(tag_acorn); 195 tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg; 196 tag->u.acorn.vram_pages = params->u1.s.pages_in_vram; 197 tag->u.acorn.sounddefault = params->u1.s.sounddefault; 198 tag->u.acorn.adfsdrives = params->u1.s.adfsdrives; 199#endif 200 201 tag = tag_next(tag); 202 tag->hdr.tag = ATAG_CMDLINE; 203 tag->hdr.size = (strlen(params->commandline) + 3 + 204 sizeof(struct tag_header)) >> 2; 205 strcpy(tag->u.cmdline.cmdline, params->commandline); 206 207 tag = tag_next(tag); 208 tag->hdr.tag = ATAG_NONE; 209 tag->hdr.size = 0; 210 211 memmove(params, taglist, ((int)tag) - ((int)taglist) + 212 sizeof(struct tag_header)); 213} 214 215void __init convert_to_tag_list(struct tag *tags) 216{ 217 struct param_struct *params = (struct param_struct *)tags; 218 build_tag_list(params, ¶ms->u2); 219} 220 221void __init squash_mem_tags(struct tag *tag) 222{ 223 for (; tag->hdr.size; tag = tag_next(tag)) 224 if (tag->hdr.tag == ATAG_MEM) 225 tag->hdr.tag = ATAG_NONE; 226} 227