2005-04-17 02:20:36 +04:00
/* 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 )
{
2007-05-02 00:32:43 +04:00
unsigned long flags ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Disable interrupts while we mess with things */
local_irq_save ( flags ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Restore prom vbr */
asm volatile ( " movec %0,%%vbr " : : " r " ( ( void * ) sun3x_prom_vbr ) ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Restore prom NMI clock */
// sun3x_disable_intreg(5);
sun3_enable_irq ( 7 ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Let 'er rip */
asm volatile ( " trap #14 " ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Restore everything */
sun3_disable_irq ( 7 ) ;
sun3_enable_irq ( 5 ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
asm volatile ( " movec %0,%%vbr " : : " r " ( ( void * ) vectors ) ) ;
local_irq_restore ( flags ) ;
2005-04-17 02:20:36 +04:00
}
void sun3x_reboot ( void )
{
2007-05-02 00:32:43 +04:00
/* This never returns, don't bother saving things */
local_irq_disable ( ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Restore prom vbr */
asm volatile ( " movec %0,%%vbr " : : " r " ( ( void * ) sun3x_prom_vbr ) ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Restore prom NMI clock */
sun3_disable_irq ( 5 ) ;
sun3_enable_irq ( 7 ) ;
2005-04-17 02:20:36 +04:00
2007-05-02 00:32:43 +04:00
/* Let 'er rip */
( * romvec - > pv_reboot ) ( " vmlinux " ) ;
2005-04-17 02:20:36 +04:00
}
static void sun3x_prom_write ( struct console * co , const char * s ,
unsigned int count )
{
2007-05-02 00:32:43 +04:00
while ( count - - ) {
if ( * s = = ' \n ' )
sun3x_putchar ( ' \r ' ) ;
sun3x_putchar ( * s + + ) ;
}
2005-04-17 02:20:36 +04:00
}
/* debug console - write-only */
static struct console sun3x_debug = {
2007-05-02 00:32:43 +04:00
. name = " debug " ,
. write = sun3x_prom_write ,
. flags = CON_PRINTBUFFER ,
. index = - 1 ,
2005-04-17 02:20:36 +04:00
} ;
2007-07-20 07:33:28 +04:00
void __init sun3x_prom_init ( void )
2005-04-17 02:20:36 +04:00
{
2007-05-02 00:32:43 +04:00
/* 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 ;
2007-05-02 00:32:45 +04:00
}
2007-05-02 00:32:43 +04:00
2007-05-02 00:32:45 +04:00
static int __init sun3x_debug_setup ( char * arg )
{
2007-05-02 00:32:43 +04:00
/* If debug=prom was specified, start the debug console */
2007-05-02 00:32:45 +04:00
if ( MACH_IS_SUN3X & & ! strcmp ( arg , " prom " ) )
2007-05-02 00:32:43 +04:00
register_console ( & sun3x_debug ) ;
2007-05-02 00:32:45 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2007-05-02 00:32:45 +04:00
early_param ( " debug " , sun3x_debug_setup ) ;
2005-04-17 02:20:36 +04:00
/* 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 */
2007-05-02 00:32:43 +04:00
for ( i = 0 ; i < num_bytes ; i + + )
2005-04-17 02:20:36 +04:00
idbuf [ i ] = ( ( char * ) SUN3X_IDPROM ) [ i ] ;
return idbuf [ 0 ] ;
}