setup.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1995 Linus Torvalds
  7.  * Copyright (C) 1995 Waldorf Electronics
  8.  * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle
  9.  * Copyright (C) 1996 Stoned Elipot
  10.  * Copyright (C) 1999 Silicon Graphics, Inc.
  11.  * Copyright (C) 2002  Maciej W. Rozycki
  12.  */
  13. #include <linux/config.h>
  14. #include <linux/errno.h>
  15. #include <linux/init.h>
  16. #include <linux/sched.h>
  17. #include <linux/kernel.h>
  18. #include <linux/mm.h>
  19. #include <linux/module.h>
  20. #include <linux/stddef.h>
  21. #include <linux/string.h>
  22. #include <linux/unistd.h>
  23. #include <linux/ptrace.h>
  24. #include <linux/slab.h>
  25. #include <linux/user.h>
  26. #include <linux/utsname.h>
  27. #include <linux/a.out.h>
  28. #include <linux/tty.h>
  29. #include <linux/bootmem.h>
  30. #ifdef CONFIG_BLK_DEV_RAM
  31. #include <linux/blk.h>
  32. #endif
  33. #include <asm/addrspace.h>
  34. #include <asm/bootinfo.h>
  35. #include <asm/cpu.h>
  36. #include <asm/mipsregs.h>
  37. #include <asm/stackframe.h>
  38. #include <asm/system.h>
  39. #include <asm/pgalloc.h>
  40. #ifndef CONFIG_SMP
  41. struct cpuinfo_mips cpu_data[1];
  42. #endif
  43. #ifdef CONFIG_VT
  44. struct screen_info screen_info;
  45. #endif
  46. /*
  47.  * Not all of the MIPS CPUs have the "wait" instruction available.  This
  48.  * is set to true if it is available.  The wait instruction stops the
  49.  * pipeline and reduces the power consumption of the CPU very much.
  50.  */
  51. char wait_available;
  52. /*
  53.  * Set if box has EISA slots.
  54.  */
  55. #ifdef CONFIG_EISA
  56. int EISA_bus = 0;
  57. #endif
  58. #ifdef CONFIG_BLK_DEV_FD
  59. extern struct fd_ops no_fd_ops;
  60. struct fd_ops *fd_ops;
  61. #endif
  62. #ifdef CONFIG_BLK_DEV_IDE
  63. extern struct ide_ops no_ide_ops;
  64. struct ide_ops *ide_ops;
  65. #endif
  66. extern struct rtc_ops no_rtc_ops;
  67. struct rtc_ops *rtc_ops;
  68. extern struct kbd_ops no_kbd_ops;
  69. struct kbd_ops *kbd_ops;
  70. /*
  71.  * Setup information
  72.  *
  73.  * These are initialized so they are in the .data section
  74.  */
  75. unsigned long mips_machtype = MACH_UNKNOWN;
  76. unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
  77. struct boot_mem_map boot_mem_map;
  78. unsigned char aux_device_present;
  79. extern void load_mmu(void);
  80. static char command_line[CL_SIZE] = { 0, };
  81.        char saved_command_line[CL_SIZE];
  82. extern char arcs_cmdline[CL_SIZE];
  83. /*
  84.  * mips_io_port_base is the begin of the address space to which x86 style
  85.  * I/O ports are mapped.
  86.  */
  87. const unsigned long mips_io_port_base = -1;
  88. EXPORT_SYMBOL(mips_io_port_base);
  89. extern void ip22_setup(void);
  90. extern void ip27_setup(void);
  91. extern void ip32_setup(void);
  92. /*
  93.  * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
  94.  * for the processor.
  95.  */
  96. unsigned long isa_slot_offset;
  97. EXPORT_SYMBOL(isa_slot_offset);
  98. extern void sgi_sysinit(void);
  99. extern void SetUpBootInfo(void);
  100. extern void load_mmu(void);
  101. extern ATTRIB_NORET asmlinkage void start_kernel(void);
  102. extern void prom_init(int, char **, char **, int *);
  103. asmlinkage void __init init_arch(int argc, char **argv, char **envp,
  104. int *prom_vec)
  105. {
  106. /* Determine which MIPS variant we are running on. */
  107. cpu_probe();
  108. prom_init(argc, argv, envp, prom_vec);
  109. #ifdef CONFIG_SGI_IP22
  110. sgi_sysinit();
  111. #endif
  112. cpu_report();
  113. /*
  114.  * Determine the mmu/cache attached to this machine, then flush the
  115.  * tlb and caches.  On the r4xx0 variants this also sets CP0_WIRED to
  116.  * zero.
  117.  */
  118. load_mmu();
  119. /*
  120.  * On IP27, I am seeing the TS bit set when the kernel is loaded.
  121.  * Maybe because the kernel is in ckseg0 and not xkphys? Clear it
  122.  * anyway ...
  123.  */
  124. clear_cp0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3);
  125. set_cp0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR);
  126. start_kernel();
  127. }
  128. void __init add_memory_region(phys_t start, phys_t size,
  129.       long type)
  130. {
  131. int x = boot_mem_map.nr_map;
  132. if (x == BOOT_MEM_MAP_MAX) {
  133. printk("Ooops! Too many entries in the memory map!n");
  134. return;
  135. }
  136. boot_mem_map.map[x].addr = start;
  137. boot_mem_map.map[x].size = size;
  138. boot_mem_map.map[x].type = type;
  139. boot_mem_map.nr_map++;
  140. }
  141. static void __init print_memory_map(void)
  142. {
  143. int i;
  144. for (i = 0; i < boot_mem_map.nr_map; i++) {
  145. printk(" memory: %016Lx @ %016Lx ",
  146. (unsigned long long) boot_mem_map.map[i].size,
  147. (unsigned long long) boot_mem_map.map[i].addr);
  148. switch (boot_mem_map.map[i].type) {
  149. case BOOT_MEM_RAM:
  150. printk("(usable)n");
  151. break;
  152. case BOOT_MEM_ROM_DATA:
  153. printk("(ROM data)n");
  154. break;
  155. case BOOT_MEM_RESERVED:
  156. printk("(reserved)n");
  157. break;
  158. default:
  159. printk("type %lun", boot_mem_map.map[i].type);
  160. break;
  161. }
  162. }
  163. }
  164. static inline void parse_mem_cmdline(void)
  165. {
  166. char c = ' ', *to = command_line, *from = saved_command_line;
  167. unsigned long start_at, mem_size;
  168. int len = 0;
  169. int usermem = 0;
  170. printk("Determined physical RAM map:n");
  171. print_memory_map();
  172. for (;;) {
  173. /*
  174.  * "mem=XXX[kKmM]" defines a memory region from
  175.  * 0 to <XXX>, overriding the determined size.
  176.  * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from
  177.  * <YYY> to <YYY>+<XXX>, overriding the determined size.
  178.  */
  179. if (c == ' ' && !memcmp(from, "mem=", 4)) {
  180. if (to != command_line)
  181. to--;
  182. /*
  183.  * If a user specifies memory size, we
  184.  * blow away any automatically generated
  185.  * size.
  186.  */
  187. if (usermem == 0) {
  188. boot_mem_map.nr_map = 0;
  189. usermem = 1;
  190. }
  191. mem_size = memparse(from + 4, &from);
  192. if (*from == '@')
  193. start_at = memparse(from + 1, &from);
  194. else
  195. start_at = 0;
  196. add_memory_region(start_at, mem_size, BOOT_MEM_RAM);
  197. }
  198. c = *(from++);
  199. if (!c)
  200. break;
  201. if (CL_SIZE <= ++len)
  202. break;
  203. *(to++) = c;
  204. }
  205. *to = '';
  206. if (usermem) {
  207. printk("User-defined physical RAM map:n");
  208. print_memory_map();
  209. }
  210. }
  211. void bootmem_init(void)
  212. {
  213. #ifdef CONFIG_BLK_DEV_INITRD
  214. unsigned long tmp;
  215. unsigned long *initrd_header;
  216. #endif
  217. unsigned long bootmap_size;
  218. unsigned long start_pfn, max_pfn;
  219. int i;
  220. extern int _end;
  221. #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
  222. #define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
  223. #define PFN_PHYS(x) ((x) << PAGE_SHIFT)
  224. /*
  225.  * Partially used pages are not usable - thus
  226.  * we are rounding upwards.
  227.  * start_pfn = PFN_UP(__pa(&_end));
  228.  */
  229. start_pfn = PFN_UP((unsigned long)&_end - KSEG0);
  230. /* Find the highest page frame number we have available.  */
  231. max_pfn = 0;
  232. for (i = 0; i < boot_mem_map.nr_map; i++) {
  233. unsigned long start, end;
  234. if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
  235. continue;
  236. start = PFN_UP(boot_mem_map.map[i].addr);
  237. end = PFN_DOWN(boot_mem_map.map[i].addr
  238.       + boot_mem_map.map[i].size);
  239. if (start >= end)
  240. continue;
  241. if (end > max_pfn)
  242. max_pfn = end;
  243. }
  244. /* Initialize the boot-time allocator.  */
  245. bootmap_size = init_bootmem(start_pfn, max_pfn);
  246. /*
  247.  * Register fully available low RAM pages with the bootmem allocator.
  248.  */
  249. for (i = 0; i < boot_mem_map.nr_map; i++) {
  250. unsigned long curr_pfn, last_pfn, size;
  251. /*
  252.  * Reserve usable memory.
  253.  */
  254. if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
  255. continue;
  256. /*
  257.  * We are rounding up the start address of usable memory:
  258.  */
  259. curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
  260. if (curr_pfn >= max_pfn)
  261. continue;
  262. if (curr_pfn < start_pfn)
  263. curr_pfn = start_pfn;
  264. /*
  265.  * ... and at the end of the usable range downwards:
  266.  */
  267. last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
  268.     + boot_mem_map.map[i].size);
  269. if (last_pfn > max_pfn)
  270. last_pfn = max_pfn;
  271. /*
  272.  * ... finally, did all the rounding and playing
  273.  * around just make the area go away?
  274.  */
  275. if (last_pfn <= curr_pfn)
  276. continue;
  277. size = last_pfn - curr_pfn;
  278. free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
  279. }
  280. /* Reserve the bootmap memory.  */
  281. reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
  282. #ifdef CONFIG_BLK_DEV_INITRD
  283. #error "Initrd is broken, please fit it."
  284. tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
  285. if (tmp < (unsigned long)&_end)
  286. tmp += PAGE_SIZE;
  287. initrd_header = (unsigned long *)tmp;
  288. if (initrd_header[0] == 0x494E5244) {
  289. initrd_start = (unsigned long)&initrd_header[2];
  290. initrd_end = initrd_start + initrd_header[1];
  291. initrd_below_start_ok = 1;
  292. if (initrd_end > memory_end) {
  293. printk("initrd extends beyond end of memory "
  294.        "(0x%08lx > 0x%08lx)ndisabling initrdn",
  295.        initrd_end,memory_end);
  296. initrd_start = 0;
  297. } else
  298. *memory_start_p = initrd_end;
  299. }
  300. #endif
  301. #undef PFN_UP
  302. #undef PFN_DOWN
  303. #undef PFN_PHYS
  304. }
  305. void __init setup_arch(char **cmdline_p)
  306. {
  307. #ifdef CONFIG_SGI_IP22
  308. ip22_setup();
  309. #endif
  310. #ifdef CONFIG_SGI_IP27
  311. ip27_setup();
  312. #endif
  313. #ifdef CONFIG_SGI_IP32
  314. ip32_setup();
  315. #endif
  316. #ifdef CONFIG_SIBYTE_SWARM
  317. swarm_setup();
  318. #endif
  319. #ifdef CONFIG_MIPS_MALTA
  320. malta_setup();
  321. #endif
  322. strncpy(command_line, arcs_cmdline, CL_SIZE);
  323. memcpy(saved_command_line, command_line, CL_SIZE);
  324. saved_command_line[CL_SIZE-1] = '';
  325. *cmdline_p = command_line;
  326. parse_mem_cmdline();
  327. bootmem_init();
  328. paging_init();
  329. }
  330. int __init fpu_disable(char *s)
  331. {
  332. mips_cpu.options &= ~MIPS_CPU_FPU;
  333. return 1;
  334. }
  335. __setup("nofpu", fpu_disable);