Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | /* Prom access routines for the sun3x */ #include <linux/types.h> #include <linux/kernel.h> #include <linux/tty.h> #include <linux/console.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/string.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/setup.h> #include <asm/traps.h> #include <asm/sun3xprom.h> #include <asm/idprom.h> #include <asm/segment.h> #include <asm/sun3ints.h> #include <asm/openprom.h> #include <asm/machines.h> void (*sun3x_putchar)(int); int (*sun3x_getchar)(void); int (*sun3x_mayget)(void); int (*sun3x_mayput)(int); void (*sun3x_prom_reboot)(void); e_vector sun3x_prom_abort; struct linux_romvec *romvec; /* prom vector table */ e_vector *sun3x_prom_vbr; /* Handle returning to the prom */ void sun3x_halt(void) { unsigned long flags; /* Disable interrupts while we mess with things */ local_irq_save(flags); /* Restore prom vbr */ asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); /* Restore prom NMI clock */ // sun3x_disable_intreg(5); sun3_enable_irq(7); /* Let 'er rip */ asm volatile ("trap #14"); /* Restore everything */ sun3_disable_irq(7); sun3_enable_irq(5); asm volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); local_irq_restore(flags); } void sun3x_reboot(void) { /* This never returns, don't bother saving things */ local_irq_disable(); /* Restore prom vbr */ asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); /* Restore prom NMI clock */ sun3_disable_irq(5); sun3_enable_irq(7); /* Let 'er rip */ (*romvec->pv_reboot)("vmlinux"); } static void sun3x_prom_write(struct console *co, const char *s, unsigned int count) { while (count--) { if (*s == '\n') sun3x_putchar('\r'); sun3x_putchar(*s++); } } /* debug console - write-only */ static struct console sun3x_debug = { .name = "debug", .write = sun3x_prom_write, .flags = CON_PRINTBUFFER, .index = -1, }; void __init sun3x_prom_init(void) { /* Read the vector table */ sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR); sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR); sun3x_mayget = *(int (**)(void)) (SUN3X_P_MAYGET); sun3x_mayput = *(int (**)(int)) (SUN3X_P_MAYPUT); sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT); sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT); romvec = (struct linux_romvec *)SUN3X_PROM_BASE; idprom_init(); if (!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) { printk("Warning: machine reports strange type %02x\n", idprom->id_machtype); printk("Pretending it's a 3/80, but very afraid...\n"); idprom->id_machtype = SM_SUN3X | SM_3_80; } /* point trap #14 at abort. * XXX this is futile since we restore the vbr first - oops */ vectors[VEC_TRAP14] = sun3x_prom_abort; } static int __init sun3x_debug_setup(char *arg) { /* If debug=prom was specified, start the debug console */ if (MACH_IS_SUN3X && !strcmp(arg, "prom")) register_console(&sun3x_debug); return 0; } early_param("debug", sun3x_debug_setup); /* some prom functions to export */ int prom_getintdefault(int node, char *property, int deflt) { return deflt; } int prom_getbool (int node, char *prop) { return 1; } void prom_printf(char *fmt, ...) { } void prom_halt (void) { sun3x_halt(); } /* Get the idprom and stuff it into buffer 'idbuf'. Returns the * format type. 'num_bytes' is the number of bytes that your idbuf * has space for. Returns 0xff on error. */ unsigned char prom_get_idprom(char *idbuf, int num_bytes) { int i; /* make a copy of the idprom structure */ for (i = 0; i < num_bytes; i++) idbuf[i] = ((char *)SUN3X_IDPROM)[i]; return idbuf[0]; } |