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

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) 1995, 1996, 1997, 1998, 1999, 2000, 2001  Ralf Baechle
  9.  * Copyright (C) 1996  Stoned Elipot
  10.  * Copyright (C) 2000, 2001  Maciej W. Rozycki
  11.  */
  12. #include <linux/config.h>
  13. #include <linux/errno.h>
  14. #include <linux/hdreg.h>
  15. #include <linux/init.h>
  16. #include <linux/ioport.h>
  17. #include <linux/sched.h>
  18. #include <linux/kernel.h>
  19. #include <linux/mm.h>
  20. #include <linux/module.h>
  21. #include <linux/stddef.h>
  22. #include <linux/string.h>
  23. #include <linux/unistd.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. #include <linux/blk.h>
  31. #include <linux/ide.h>
  32. #include <linux/timex.h>
  33. #include <asm/asm.h>
  34. #include <asm/bootinfo.h>
  35. #include <asm/cachectl.h>
  36. #include <asm/cpu.h>
  37. #include <asm/io.h>
  38. #include <asm/ptrace.h>
  39. #include <asm/system.h>
  40. #ifndef CONFIG_SMP
  41. struct cpuinfo_mips cpu_data[1];
  42. #endif
  43. /*
  44.  * There are several bus types available for MIPS machines.  "RISC PC"
  45.  * type machines have ISA, EISA, VLB or PCI available, DECstations
  46.  * have Turbochannel or Q-Bus, SGI has GIO, there are lots of VME
  47.  * boxes ...
  48.  * This flag is set if a EISA slots are available.
  49.  */
  50. #ifdef CONFIG_EISA
  51. int EISA_bus = 0;
  52. #endif
  53. struct screen_info screen_info;
  54. extern struct fd_ops no_fd_ops;
  55. struct fd_ops *fd_ops;
  56. #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
  57. extern struct ide_ops no_ide_ops;
  58. struct ide_ops *ide_ops;
  59. #endif
  60. extern void * __rd_start, * __rd_end;
  61. extern struct rtc_ops no_rtc_ops;
  62. struct rtc_ops *rtc_ops;
  63. #ifdef CONFIG_PC_KEYB
  64. extern struct kbd_ops no_kbd_ops;
  65. struct kbd_ops *kbd_ops;
  66. #endif
  67. /*
  68.  * Setup information
  69.  *
  70.  * These are initialized so they are in the .data section
  71.  */
  72. unsigned long mips_machtype = MACH_UNKNOWN;
  73. unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
  74. struct boot_mem_map boot_mem_map;
  75. unsigned char aux_device_present;
  76. extern char _ftext, _etext, _fdata, _edata, _end;
  77. static char command_line[CL_SIZE];
  78.        char saved_command_line[CL_SIZE];
  79. extern char arcs_cmdline[CL_SIZE];
  80. /*
  81.  * mips_io_port_base is the begin of the address space to which x86 style
  82.  * I/O ports are mapped.
  83.  */
  84. const unsigned long mips_io_port_base = -1;
  85. EXPORT_SYMBOL(mips_io_port_base);
  86. /*
  87.  * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
  88.  * for the processor.
  89.  */
  90. unsigned long isa_slot_offset;
  91. EXPORT_SYMBOL(isa_slot_offset);
  92. extern void sgi_sysinit(void);
  93. extern void SetUpBootInfo(void);
  94. extern void loadmmu(void);
  95. extern asmlinkage void start_kernel(void);
  96. extern void prom_init(int, char **, char **, int *);
  97. static struct resource code_resource = { "Kernel code" };
  98. static struct resource data_resource = { "Kernel data" };
  99. asmlinkage void __init
  100. init_arch(int argc, char **argv, char **envp, int *prom_vec)
  101. {
  102. /* Determine which MIPS variant we are running on. */
  103. cpu_probe();
  104. prom_init(argc, argv, envp, prom_vec);
  105. #ifdef CONFIG_SGI_IP22
  106. sgi_sysinit();
  107. #endif
  108. cpu_report();
  109. /*
  110.  * Determine the mmu/cache attached to this machine,
  111.  * then flush the tlb and caches.  On the r4xx0
  112.  * variants this also sets CP0_WIRED to zero.
  113.  */
  114. loadmmu();
  115. /* Disable coprocessors and set FPU for 16/32 FPR register model */
  116. clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
  117. set_cp0_status(ST0_CU0);
  118. start_kernel();
  119. }
  120. void __init add_memory_region(phys_t start, phys_t size,
  121.       long type)
  122. {
  123. int x = boot_mem_map.nr_map;
  124. if (x == BOOT_MEM_MAP_MAX) {
  125. printk("Ooops! Too many entries in the memory map!n");
  126. return;
  127. }
  128. boot_mem_map.map[x].addr = start;
  129. boot_mem_map.map[x].size = size;
  130. boot_mem_map.map[x].type = type;
  131. boot_mem_map.nr_map++;
  132. }
  133. static void __init print_memory_map(void)
  134. {
  135. int i;
  136. for (i = 0; i < boot_mem_map.nr_map; i++) {
  137. printk(" memory: %08Lx @ %08Lx ",
  138. (u64) boot_mem_map.map[i].size,
  139.         (u64) boot_mem_map.map[i].addr);
  140. switch (boot_mem_map.map[i].type) {
  141. case BOOT_MEM_RAM:
  142. printk("(usable)n");
  143. break;
  144. case BOOT_MEM_ROM_DATA:
  145. printk("(ROM data)n");
  146. break;
  147. case BOOT_MEM_RESERVED:
  148. printk("(reserved)n");
  149. break;
  150. default:
  151. printk("type %lun", boot_mem_map.map[i].type);
  152. break;
  153. }
  154. }
  155. }
  156. static inline void parse_mem_cmdline(void)
  157. {
  158. char c = ' ', *to = command_line, *from = saved_command_line;
  159. unsigned long start_at, mem_size;
  160. int len = 0;
  161. int usermem = 0;
  162. printk("Determined physical RAM map:n");
  163. print_memory_map();
  164. for (;;) {
  165. /*
  166.  * "mem=XXX[kKmM]" defines a memory region from
  167.  * 0 to <XXX>, overriding the determined size.
  168.  * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from
  169.  * <YYY> to <YYY>+<XXX>, overriding the determined size.
  170.  */
  171. if (c == ' ' && !memcmp(from, "mem=", 4)) {
  172. if (to != command_line)
  173. to--;
  174. /*
  175.  * If a user specifies memory size, we
  176.  * blow away any automatically generated
  177.  * size.
  178.  */
  179. if (usermem == 0) {
  180. boot_mem_map.nr_map = 0;
  181. usermem = 1;
  182. }
  183. mem_size = memparse(from + 4, &from);
  184. if (*from == '@')
  185. start_at = memparse(from + 1, &from);
  186. else
  187. start_at = 0;
  188. add_memory_region(start_at, mem_size, BOOT_MEM_RAM);
  189. }
  190. c = *(from++);
  191. if (!c)
  192. break;
  193. if (CL_SIZE <= ++len)
  194. break;
  195. *(to++) = c;
  196. }
  197. *to = '';
  198. if (usermem) {
  199. printk("User-defined physical RAM map:n");
  200. print_memory_map();
  201. }
  202. }
  203. void __init setup_arch(char **cmdline_p)
  204. {
  205. void atlas_setup(void);
  206. void baget_setup(void);
  207. void cobalt_setup(void);
  208. void ddb_setup(void);
  209. void decstation_setup(void);
  210. void deskstation_setup(void);
  211. void jazz_setup(void);
  212. void sni_rm200_pci_setup(void);
  213. void ip22_setup(void);
  214.         void ev96100_setup(void);
  215. void malta_setup(void);
  216. void sead_setup(void);
  217. void ikos_setup(void);
  218. void momenco_ocelot_setup(void);
  219. void momenco_ocelot_g_setup(void);
  220. void nino_setup(void);
  221. void nec_osprey_setup(void);
  222. void nec_eagle_setup(void);
  223. void zao_capcella_setup(void);
  224. void jmr3927_setup(void);
  225.   void it8172_setup(void);
  226. void swarm_setup(void);
  227. void hp_setup(void);
  228. unsigned long bootmap_size;
  229. unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn;
  230. #ifdef CONFIG_BLK_DEV_INITRD
  231. unsigned long tmp;
  232. unsigned long* initrd_header;
  233. #endif
  234. int i;
  235. #ifdef CONFIG_BLK_DEV_FD
  236. fd_ops = &no_fd_ops;
  237. #endif
  238. #ifdef CONFIG_BLK_DEV_IDE
  239. ide_ops = &no_ide_ops;
  240. #endif
  241. #ifdef CONFIG_PC_KEYB
  242. kbd_ops = &no_kbd_ops;
  243. #endif
  244. rtc_ops = &no_rtc_ops;
  245. switch(mips_machgroup)
  246. {
  247. #ifdef CONFIG_BAGET_MIPS
  248. case MACH_GROUP_BAGET:
  249. baget_setup();
  250. break;
  251. #endif
  252. #ifdef CONFIG_MIPS_COBALT
  253.         case MACH_GROUP_COBALT:
  254.                 cobalt_setup();
  255.                 break;
  256. #endif
  257. #ifdef CONFIG_DECSTATION
  258. case MACH_GROUP_DEC:
  259. decstation_setup();
  260. break;
  261. #endif
  262. #ifdef CONFIG_MIPS_ATLAS
  263. case MACH_GROUP_UNKNOWN:
  264. atlas_setup();
  265. break;
  266. #endif
  267. #ifdef CONFIG_MIPS_JAZZ
  268. case MACH_GROUP_JAZZ:
  269. jazz_setup();
  270. break;
  271. #endif
  272. #ifdef CONFIG_MIPS_MALTA
  273. case MACH_GROUP_UNKNOWN:
  274. malta_setup();
  275. break;
  276. #endif
  277. #ifdef CONFIG_MOMENCO_OCELOT
  278. case MACH_GROUP_MOMENCO:
  279. momenco_ocelot_setup();
  280. break;
  281. #endif
  282. #ifdef CONFIG_MOMENCO_OCELOT_G
  283. case MACH_GROUP_MOMENCO:
  284. momenco_ocelot_g_setup();
  285. break;
  286. #endif
  287. #ifdef CONFIG_MIPS_SEAD
  288. case MACH_GROUP_UNKNOWN:
  289. sead_setup();
  290. break;
  291. #endif
  292. #ifdef CONFIG_SGI_IP22
  293. /* As of now this is only IP22.  */
  294. case MACH_GROUP_SGI:
  295. ip22_setup();
  296. break;
  297. #endif
  298. #ifdef CONFIG_SNI_RM200_PCI
  299. case MACH_GROUP_SNI_RM:
  300. sni_rm200_pci_setup();
  301. break;
  302. #endif
  303. #ifdef CONFIG_DDB5074
  304. case MACH_GROUP_NEC_DDB:
  305. ddb_setup();
  306. break;
  307. #endif
  308. #ifdef CONFIG_DDB5476
  309.        case MACH_GROUP_NEC_DDB:
  310.                ddb_setup();
  311.                break;
  312. #endif
  313. #ifdef CONFIG_DDB5477
  314.        case MACH_GROUP_NEC_DDB:
  315.                ddb_setup();
  316.                break;
  317. #endif
  318. #ifdef CONFIG_CPU_VR41XX
  319. case MACH_GROUP_NEC_VR41XX:
  320. switch (mips_machtype) {
  321. #ifdef CONFIG_NEC_OSPREY
  322. case MACH_NEC_OSPREY:
  323. nec_osprey_setup();
  324. break;
  325. #endif
  326. #ifdef CONFIG_NEC_EAGLE
  327. case MACH_NEC_EAGLE:
  328. nec_eagle_setup();
  329. break;
  330. #endif
  331. #ifdef CONFIG_ZAO_CAPCELLA
  332. case MACH_ZAO_CAPCELLA:
  333. zao_capcella_setup();
  334. break;
  335. #endif
  336. }
  337. break;
  338. #endif
  339. #ifdef CONFIG_MIPS_EV96100
  340. case MACH_GROUP_GALILEO:
  341. ev96100_setup();
  342. break;
  343. #endif
  344. #ifdef CONFIG_MIPS_EV64120
  345. case MACH_GROUP_GALILEO:
  346. ev64120_setup();
  347. break;
  348. #endif
  349. #if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172)
  350. case  MACH_GROUP_ITE:
  351. case  MACH_GROUP_GLOBESPAN:
  352. it8172_setup();
  353. break;
  354. #endif
  355. #ifdef CONFIG_NINO
  356. case MACH_GROUP_PHILIPS:
  357. nino_setup();
  358. break;
  359. #endif
  360. #ifdef CONFIG_MIPS_PB1000
  361. case MACH_GROUP_ALCHEMY:
  362. au1000_setup();
  363. break;
  364. #endif
  365. #ifdef CONFIG_MIPS_PB1100
  366. case MACH_GROUP_ALCHEMY:
  367. au1100_setup();
  368. break;
  369. #endif
  370. #ifdef CONFIG_MIPS_PB1500
  371. case MACH_GROUP_ALCHEMY:
  372. au1500_setup();
  373. break;
  374. #endif
  375. #ifdef CONFIG_TOSHIBA_JMR3927
  376. case MACH_GROUP_TOSHIBA:
  377. jmr3927_setup();
  378. break;
  379. #endif
  380. #ifdef CONFIG_SIBYTE_SWARM
  381. case MACH_GROUP_SIBYTE:
  382. swarm_setup();
  383. break;
  384. #endif
  385. #ifdef CONFIG_HP_LASERJET
  386.         case MACH_GROUP_HP_LJ:
  387.                 hp_setup();
  388.                 break;
  389. #endif
  390. default:
  391. panic("Unsupported architecture");
  392. }
  393. strncpy(command_line, arcs_cmdline, sizeof command_line);
  394. command_line[sizeof command_line - 1] = 0;
  395. strcpy(saved_command_line, command_line);
  396. *cmdline_p = command_line;
  397. parse_mem_cmdline();
  398. #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
  399. #define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
  400. #define PFN_PHYS(x) ((x) << PAGE_SHIFT)
  401. #define MAXMEM HIGHMEM_START
  402. #define MAXMEM_PFN PFN_DOWN(MAXMEM)
  403. #ifdef CONFIG_BLK_DEV_INITRD
  404. tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
  405. if (tmp < (unsigned long)&_end)
  406. tmp += PAGE_SIZE;
  407. initrd_header = (unsigned long *)tmp;
  408. if (initrd_header[0] == 0x494E5244) {
  409. initrd_start = (unsigned long)&initrd_header[2];
  410. initrd_end = initrd_start + initrd_header[1];
  411. }
  412. start_pfn = PFN_UP(__pa((&_end)+(initrd_end - initrd_start) + PAGE_SIZE));
  413. #else
  414. /*
  415.  * Partially used pages are not usable - thus
  416.  * we are rounding upwards.
  417.  */
  418. start_pfn = PFN_UP(__pa(&_end));
  419. #endif /* CONFIG_BLK_DEV_INITRD */
  420. /* Find the highest page frame number we have available.  */
  421. max_pfn = 0;
  422. first_usable_pfn = -1UL;
  423. for (i = 0; i < boot_mem_map.nr_map; i++) {
  424. unsigned long start, end;
  425. if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
  426. continue;
  427. start = PFN_UP(boot_mem_map.map[i].addr);
  428. end = PFN_DOWN(boot_mem_map.map[i].addr
  429.       + boot_mem_map.map[i].size);
  430. if (start >= end)
  431. continue;
  432. if (end > max_pfn)
  433. max_pfn = end;
  434. if (start < first_usable_pfn) {
  435. if (start > start_pfn) {
  436. first_usable_pfn = start;
  437. } else if (end > start_pfn) {
  438. first_usable_pfn = start_pfn;
  439. }
  440. }
  441. }
  442. /*
  443.  * Determine low and high memory ranges
  444.  */
  445. max_low_pfn = max_pfn;
  446. if (max_low_pfn > MAXMEM_PFN) {
  447. max_low_pfn = MAXMEM_PFN;
  448. #ifndef CONFIG_HIGHMEM
  449. /* Maximum memory usable is what is directly addressable */
  450. printk(KERN_WARNING "Warning only %ldMB will be used.n",
  451.        MAXMEM>>20);
  452. printk(KERN_WARNING "Use a HIGHMEM enabled kernel.n");
  453. #endif
  454. }
  455. #ifdef CONFIG_HIGHMEM
  456. /*
  457.  * Crude, we really should make a better attempt at detecting
  458.  * highstart_pfn
  459.  */
  460. highstart_pfn = highend_pfn = max_pfn;
  461. if (max_pfn > MAXMEM_PFN) {
  462. highstart_pfn = MAXMEM_PFN;
  463. printk(KERN_NOTICE "%ldMB HIGHMEM available.n",
  464.        (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT));
  465. }
  466. #endif
  467. /* Initialize the boot-time allocator with low memory only.  */
  468. bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
  469. /*
  470.  * Register fully available low RAM pages with the bootmem allocator.
  471.  */
  472. for (i = 0; i < boot_mem_map.nr_map; i++) {
  473. unsigned long curr_pfn, last_pfn, size;
  474. /*
  475.  * Reserve usable memory.
  476.  */
  477. if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
  478. continue;
  479. /*
  480.  * We are rounding up the start address of usable memory:
  481.  */
  482. curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
  483. if (curr_pfn >= max_low_pfn)
  484. continue;
  485. if (curr_pfn < start_pfn)
  486. curr_pfn = start_pfn;
  487. /*
  488.  * ... and at the end of the usable range downwards:
  489.  */
  490. last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
  491.     + boot_mem_map.map[i].size);
  492. if (last_pfn > max_low_pfn)
  493. last_pfn = max_low_pfn;
  494. /*
  495.  * Only register lowmem part of lowmem segment with bootmem.
  496.  */
  497. size = last_pfn - curr_pfn;
  498. if (curr_pfn > PFN_DOWN(HIGHMEM_START))
  499. continue;
  500. if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START))
  501. size = PFN_DOWN(HIGHMEM_START) - curr_pfn;
  502. if (!size)
  503. continue;
  504. /*
  505.  * ... finally, did all the rounding and playing
  506.  * around just make the area go away?
  507.  */
  508. if (last_pfn <= curr_pfn)
  509. continue;
  510. /* Register lowmem ranges */
  511. free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
  512. }
  513. /* Reserve the bootmap memory.  */
  514. reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size);
  515. #ifdef CONFIG_BLK_DEV_INITRD
  516. /* Board specific code should have set up initrd_start and initrd_end */
  517. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
  518. if (&__rd_start != &__rd_end) {
  519. initrd_start = (unsigned long)&__rd_start;
  520. initrd_end = (unsigned long)&__rd_end;
  521. }
  522. initrd_below_start_ok = 1;
  523. if (initrd_start) {
  524. unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start);
  525. printk("Initial ramdisk at: 0x%p (%lu bytes)n",
  526.        (void *)initrd_start,
  527.        initrd_size);
  528. if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
  529. printk("initrd extends beyond end of memory "
  530.        "(0x%lx > 0x%p)ndisabling initrdn",
  531.        PHYSADDR(initrd_end),
  532.        PFN_PHYS(max_low_pfn));
  533. initrd_start = initrd_end = 0;
  534. }
  535. }
  536. #endif /* CONFIG_BLK_DEV_INITRD  */
  537. paging_init();
  538. code_resource.start = virt_to_bus(&_ftext);
  539. code_resource.end = virt_to_bus(&_etext) - 1;
  540. data_resource.start = virt_to_bus(&_fdata);
  541. data_resource.end = virt_to_bus(&_edata) - 1;
  542. /*
  543.  * Request address space for all standard RAM.
  544.  */
  545. for (i = 0; i < boot_mem_map.nr_map; i++) {
  546. struct resource *res;
  547. unsigned long addr_pfn, end_pfn;
  548. res = alloc_bootmem(sizeof(struct resource));
  549. switch (boot_mem_map.map[i].type) {
  550. case BOOT_MEM_RAM:
  551. case BOOT_MEM_ROM_DATA:
  552. res->name = "System RAM";
  553. break;
  554. case BOOT_MEM_RESERVED:
  555. default:
  556. res->name = "reserved";
  557. }
  558. addr_pfn = PFN_UP(boot_mem_map.map[i].addr);
  559. end_pfn = PFN_UP(boot_mem_map.map[i].addr+boot_mem_map.map[i].size);
  560. if (addr_pfn > max_low_pfn)
  561. continue;
  562. res->start = boot_mem_map.map[i].addr;
  563. if (end_pfn < max_low_pfn) {
  564. res->end = res->start + boot_mem_map.map[i].size - 1;
  565. } else {
  566. res->end = max_low_pfn - 1;
  567. }
  568. res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  569. request_resource(&iomem_resource, res);
  570. /*
  571.  *  We dont't know which RAM region contains kernel data,
  572.  *  so we try it repeatedly and let the resource manager
  573.  *  test it.
  574.  */
  575. request_resource(res, &code_resource);
  576. request_resource(res, &data_resource);
  577. }
  578. }
  579. static int __init fpu_disable(char *s)
  580. {
  581. mips_cpu.options &= ~MIPS_CPU_FPU;
  582. return 1;
  583. }
  584. __setup("nofpu", fpu_disable);