📄 setup.c
字号:
/* $Id: setup.c,v 1.72 2002/02/09 19:49:30 davem Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */#include <linux/errno.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/stddef.h>#include <linux/unistd.h>#include <linux/ptrace.h>#include <linux/slab.h>#include <asm/smp.h>#include <linux/user.h>#include <linux/a.out.h>#include <linux/tty.h>#include <linux/delay.h>#include <linux/config.h>#include <linux/fs.h>#include <linux/seq_file.h>#include <linux/syscalls.h>#include <linux/kdev_t.h>#include <linux/major.h>#include <linux/string.h>#include <linux/init.h>#include <linux/inet.h>#include <linux/console.h>#include <linux/root_dev.h>#include <linux/interrupt.h>#include <linux/cpu.h>#include <linux/initrd.h>#include <asm/system.h>#include <asm/io.h>#include <asm/processor.h>#include <asm/oplib.h>#include <asm/page.h>#include <asm/pgtable.h>#include <asm/idprom.h>#include <asm/head.h>#include <asm/starfire.h>#include <asm/mmu_context.h>#include <asm/timer.h>#include <asm/sections.h>#include <asm/setup.h>#include <asm/mmu.h>#ifdef CONFIG_IP_PNP#include <net/ipconfig.h>#endifstruct screen_info screen_info = { 0, 0, /* orig-x, orig-y */ 0, /* unused */ 0, /* orig-video-page */ 0, /* orig-video-mode */ 128, /* orig-video-cols */ 0, 0, 0, /* unused, ega_bx, unused */ 54, /* orig-video-lines */ 0, /* orig-video-isVGA */ 16 /* orig-video-points */};/* Typing sync at the prom prompt calls the function pointed to by * the sync callback which I set to the following function. * This should sync all filesystems and return, for now it just * prints out pretty messages and returns. */void (*prom_palette)(int);void (*prom_keyboard)(void);static voidprom_console_write(struct console *con, const char *s, unsigned n){ prom_write(s, n);}static struct console prom_console = { .name = "prom", .write = prom_console_write, .flags = CON_CONSDEV | CON_ENABLED, .index = -1,};#define PROM_TRUE -1#define PROM_FALSE 0/* Pretty sick eh? */int prom_callback(long *args){ struct console *cons, *saved_console = NULL; unsigned long flags; char *cmd; extern spinlock_t prom_entry_lock; if (!args) return -1; if (!(cmd = (char *)args[0])) return -1; /* * The callback can be invoked on the cpu that first dropped * into prom_cmdline after taking the serial interrupt, or on * a slave processor that was smp_captured() if the * administrator has done a switch-cpu inside obp. In either * case, the cpu is marked as in-interrupt. Drop IRQ locks. */ irq_exit(); /* XXX Revisit the locking here someday. This is a debugging * XXX feature so it isnt all that critical. -DaveM */ local_irq_save(flags); spin_unlock(&prom_entry_lock); cons = console_drivers; while (cons) { unregister_console(cons); cons->flags &= ~(CON_PRINTBUFFER); cons->next = saved_console; saved_console = cons; cons = console_drivers; } register_console(&prom_console); if (!strcmp(cmd, "sync")) { prom_printf("PROM `%s' command...\n", cmd); show_free_areas(); if (current->pid != 0) { local_irq_enable(); sys_sync(); local_irq_disable(); } args[2] = 0; args[args[1] + 3] = -1; prom_printf("Returning to PROM\n"); } else if (!strcmp(cmd, "va>tte-data")) { unsigned long ctx, va; unsigned long tte = 0; long res = PROM_FALSE; ctx = args[3]; va = args[4]; if (ctx) { /* * Find process owning ctx, lookup mapping. */ struct task_struct *p; struct mm_struct *mm = NULL; pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; pte_t *ptep; for_each_process(p) { mm = p->mm; if (CTX_NRBITS(mm->context) == ctx) break; } if (!mm || CTX_NRBITS(mm->context) != ctx) goto done; pgdp = pgd_offset(mm, va); if (pgd_none(*pgdp)) goto done; pudp = pud_offset(pgdp, va); if (pud_none(*pudp)) goto done; pmdp = pmd_offset(pudp, va); if (pmd_none(*pmdp)) goto done; /* Preemption implicitly disabled by virtue of * being called from inside OBP. */ ptep = pte_offset_map(pmdp, va); if (pte_present(*ptep)) { tte = pte_val(*ptep); res = PROM_TRUE; } pte_unmap(ptep); goto done; } if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) { extern unsigned long sparc64_kern_pri_context; /* Spitfire Errata #32 workaround */ __asm__ __volatile__("stxa %0, [%1] %2\n\t" "flush %%g6" : /* No outputs */ : "r" (sparc64_kern_pri_context), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); /* * Locked down tlb entry. */ if (tlb_type == spitfire) tte = spitfire_get_dtlb_data(SPITFIRE_HIGHEST_LOCKED_TLBENT); else if (tlb_type == cheetah || tlb_type == cheetah_plus) tte = cheetah_get_ldtlb_data(CHEETAH_HIGHEST_LOCKED_TLBENT); res = PROM_TRUE; goto done; } if (va < PGDIR_SIZE) { /* * vmalloc or prom_inherited mapping. */ pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; pte_t *ptep; int error; if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) { tte = prom_virt_to_phys(va, &error); if (!error) res = PROM_TRUE; goto done; } pgdp = pgd_offset_k(va); if (pgd_none(*pgdp)) goto done; pudp = pud_offset(pgdp, va); if (pud_none(*pudp)) goto done; pmdp = pmd_offset(pudp, va); if (pmd_none(*pmdp)) goto done; /* Preemption implicitly disabled by virtue of * being called from inside OBP. */ ptep = pte_offset_kernel(pmdp, va); if (pte_present(*ptep)) { tte = pte_val(*ptep); res = PROM_TRUE; } goto done; } if (va < PAGE_OFFSET) { /* * No mappings here. */ goto done; } if (va & (1UL << 40)) { /* * I/O page. */ tte = (__pa(va) & _PAGE_PADDR) | _PAGE_VALID | _PAGE_SZ4MB | _PAGE_E | _PAGE_P | _PAGE_W; res = PROM_TRUE; goto done; } /* * Normal page. */ tte = (__pa(va) & _PAGE_PADDR) | _PAGE_VALID | _PAGE_SZ4MB | _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W; res = PROM_TRUE; done: if (res == PROM_TRUE) { args[2] = 3; args[args[1] + 3] = 0; args[args[1] + 4] = res; args[args[1] + 5] = tte; } else { args[2] = 2; args[args[1] + 3] = 0; args[args[1] + 4] = res; } } else if (!strcmp(cmd, ".soft1")) { unsigned long tte; tte = args[3]; prom_printf("%lx:\"%s%s%s%s%s\" ", (tte & _PAGE_SOFT) >> 7, tte & _PAGE_MODIFIED ? "M" : "-", tte & _PAGE_ACCESSED ? "A" : "-", tte & _PAGE_READ ? "W" : "-", tte & _PAGE_WRITE ? "R" : "-", tte & _PAGE_PRESENT ? "P" : "-"); args[2] = 2; args[args[1] + 3] = 0; args[args[1] + 4] = PROM_TRUE; } else if (!strcmp(cmd, ".soft2")) { unsigned long tte; tte = args[3]; prom_printf("%lx ", (tte & 0x07FC000000000000UL) >> 50); args[2] = 2; args[args[1] + 3] = 0; args[args[1] + 4] = PROM_TRUE; } else { prom_printf("unknown PROM `%s' command...\n", cmd); } unregister_console(&prom_console); while (saved_console) { cons = saved_console; saved_console = cons->next; register_console(cons); } spin_lock(&prom_entry_lock); local_irq_restore(flags); /* * Restore in-interrupt status for a resume from obp. */ irq_enter(); return 0;}unsigned int boot_flags = 0;#define BOOTME_DEBUG 0x1#define BOOTME_SINGLE 0x2/* Exported for mm/init.c:paging_init. */unsigned long cmdline_memory_size = 0;static struct console prom_debug_console = { .name = "debug", .write = prom_console_write, .flags = CON_PRINTBUFFER, .index = -1,};/* XXX Implement this at some point... */void kernel_enter_debugger(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -