1 /* 2 * linux/arch/arm/kernel/atags_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 "atags.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 */ 42 struct 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 84 static 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 95 static 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 pr_warn("Warning: bad configuration page, trying to continue\n"); 101 return; 102 } 103 104 printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); 105 106 #ifdef CONFIG_ARCH_NETWINDER 107 if (params->u1.s.nr_pages != 0x02000 && 108 params->u1.s.nr_pages != 0x04000 && 109 params->u1.s.nr_pages != 0x08000 && 110 params->u1.s.nr_pages != 0x10000) { 111 pr_warn("Warning: bad NeTTrom parameters detected, using defaults\n"); 112 113 params->u1.s.nr_pages = 0x1000; /* 16MB */ 114 params->u1.s.ramdisk_size = 0; 115 params->u1.s.flags = FLAG_READONLY; 116 params->u1.s.initrd_start = 0; 117 params->u1.s.initrd_size = 0; 118 params->u1.s.rd_start = 0; 119 } 120 #endif 121 122 tag->hdr.tag = ATAG_CORE; 123 tag->hdr.size = tag_size(tag_core); 124 tag->u.core.flags = params->u1.s.flags & FLAG_READONLY; 125 tag->u.core.pagesize = params->u1.s.page_size; 126 tag->u.core.rootdev = params->u1.s.rootdev; 127 128 tag = tag_next(tag); 129 tag->hdr.tag = ATAG_RAMDISK; 130 tag->hdr.size = tag_size(tag_ramdisk); 131 tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) | 132 (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0); 133 tag->u.ramdisk.size = params->u1.s.ramdisk_size; 134 tag->u.ramdisk.start = params->u1.s.rd_start; 135 136 tag = tag_next(tag); 137 tag->hdr.tag = ATAG_INITRD; 138 tag->hdr.size = tag_size(tag_initrd); 139 tag->u.initrd.start = params->u1.s.initrd_start; 140 tag->u.initrd.size = params->u1.s.initrd_size; 141 142 tag = tag_next(tag); 143 tag->hdr.tag = ATAG_SERIAL; 144 tag->hdr.size = tag_size(tag_serialnr); 145 tag->u.serialnr.low = params->u1.s.system_serial_low; 146 tag->u.serialnr.high = params->u1.s.system_serial_high; 147 148 tag = tag_next(tag); 149 tag->hdr.tag = ATAG_REVISION; 150 tag->hdr.size = tag_size(tag_revision); 151 tag->u.revision.rev = params->u1.s.system_rev; 152 153 #ifdef CONFIG_ARCH_ACORN 154 if (machine_is_riscpc()) { 155 int i; 156 for (i = 0; i < 4; i++) 157 tag = memtag(tag, PHYS_OFFSET + (i << 26), 158 params->u1.s.pages_in_bank[i] * PAGE_SIZE); 159 } else 160 #endif 161 tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); 162 163 #ifdef CONFIG_FOOTBRIDGE 164 if (params->u1.s.mem_fclk_21285) { 165 tag = tag_next(tag); 166 tag->hdr.tag = ATAG_MEMCLK; 167 tag->hdr.size = tag_size(tag_memclk); 168 tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285; 169 } 170 #endif 171 172 #ifdef CONFIG_ARCH_EBSA285 173 if (machine_is_ebsa285()) { 174 tag = tag_next(tag); 175 tag->hdr.tag = ATAG_VIDEOTEXT; 176 tag->hdr.size = tag_size(tag_videotext); 177 tag->u.videotext.x = params->u1.s.video_x; 178 tag->u.videotext.y = params->u1.s.video_y; 179 tag->u.videotext.video_page = 0; 180 tag->u.videotext.video_mode = 0; 181 tag->u.videotext.video_cols = params->u1.s.video_num_cols; 182 tag->u.videotext.video_ega_bx = 0; 183 tag->u.videotext.video_lines = params->u1.s.video_num_rows; 184 tag->u.videotext.video_isvga = 1; 185 tag->u.videotext.video_points = 8; 186 } 187 #endif 188 189 #ifdef CONFIG_ARCH_ACORN 190 tag = tag_next(tag); 191 tag->hdr.tag = ATAG_ACORN; 192 tag->hdr.size = tag_size(tag_acorn); 193 tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg; 194 tag->u.acorn.vram_pages = params->u1.s.pages_in_vram; 195 tag->u.acorn.sounddefault = params->u1.s.sounddefault; 196 tag->u.acorn.adfsdrives = params->u1.s.adfsdrives; 197 #endif 198 199 tag = tag_next(tag); 200 tag->hdr.tag = ATAG_CMDLINE; 201 tag->hdr.size = (strlen(params->commandline) + 3 + 202 sizeof(struct tag_header)) >> 2; 203 strcpy(tag->u.cmdline.cmdline, params->commandline); 204 205 tag = tag_next(tag); 206 tag->hdr.tag = ATAG_NONE; 207 tag->hdr.size = 0; 208 209 memmove(params, taglist, ((int)tag) - ((int)taglist) + 210 sizeof(struct tag_header)); 211 } 212 213 void __init convert_to_tag_list(struct tag *tags) 214 { 215 struct param_struct *params = (struct param_struct *)tags; 216 build_tag_list(params, ¶ms->u2); 217 } 218