⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l1.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    /* otherwise, we've got a character that needs	     * to be unescaped	     */	    cq_tent_add( q, (c ^ BRL1_XOR_CH) );	    STATE_SET( sc, BRL1_BODY );	    break;	} /* end of switch( STATE_GET(sc) ) */    } /* end of while(!done) */    L1SC_RECV_UNLOCK( sc, cpl );    return result;}	    /* brl1_init initializes the Bedrock/L1 protocol layer.  This includes * zeroing out the send and receive state information. */voidbrl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ){    int i;    brl1_sch_t *subch;    bzero( sc, sizeof( *sc ) );    sc->nasid = nasid;    sc->uart = uart;    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);    sc->sol = 1;    subch = sc->subch;    /* initialize L1 subchannels     */    /* assign processor TTY channels */    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {	subch->use = BRL1_SUBCH_RSVD;	subch->packet_arrived = ATOMIC_INIT(0);	spin_lock_init( &(subch->data_lock) );	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );	subch->tx_notify = NULL;	/* (for now, drop elscuart packets in the kernel) */	subch->rx_notify = brl1_discard_packet;	subch->iqp = &sc->garbage_q;    }    /* assign system TTY channel (first free subchannel after each     * processor's individual TTY channel has been assigned)     */    subch->use = BRL1_SUBCH_RSVD;    subch->packet_arrived = ATOMIC_INIT(0);    spin_lock_init( &(subch->data_lock) );    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );    subch->tx_notify = NULL;    if( sc->uart == BRL1_LOCALHUB_UART ) {	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );	ASSERT( subch->iqp );	cq_init( subch->iqp );	subch->rx_notify = NULL;    }    else {	/* we shouldn't be getting console input from remote UARTs */	subch->iqp = &sc->garbage_q;	subch->rx_notify = brl1_discard_packet;    }    subch++; i++;    /* "reserved" subchannels (0x05-0x0F); for now, throw away     * incoming packets     */    for( ; i < 0x10; i++, subch++ ) {	subch->use = BRL1_SUBCH_FREE;	subch->packet_arrived = ATOMIC_INIT(0);	subch->tx_notify = NULL;	subch->rx_notify = brl1_discard_packet;	subch->iqp = &sc->garbage_q;    }    /* remaining subchannels are free */    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {	subch->use = BRL1_SUBCH_FREE;	subch->packet_arrived = ATOMIC_INIT(0);	subch->tx_notify = NULL;	subch->rx_notify = brl1_discard_packet;	subch->iqp = &sc->garbage_q;    }    /* initialize synchronization structures     */    spin_lock_init( &(sc->subch_lock) );    spin_lock_init( &(sc->send_lock) );    spin_lock_init( &(sc->recv_lock) );    if( sc->uart == BRL1_LOCALHUB_UART ) {	uart_init( sc, UART_BAUD_RATE );    }    else {	rtr_uart_init( sc, UART_BAUD_RATE );    }    /* Set up remaining fields using L1 command functions-- elsc_module_get     * to read the module id, elsc_debug_get to see whether or not we're     * in verbose mode.     */    {	extern int elsc_module_get(l1sc_t *);	sc->modid = elsc_module_get( sc );	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);	sc->verbose = 1;    }}/********************************************************************* * These are interrupt-related functions used in the kernel to service * the L1. *//* * brl1_intrd is the function which is called on a console interrupt. */#if defined(CONFIG_IA64_SGI_SN1)static voidbrl1_intrd(int irq, void *dev_id, struct pt_regs *stuff){    u_char isr_reg;    l1sc_t *sc = get_elsc();    int ret;    L1_collectibles[L1C_INTERRUPTS]++;    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);    /* Save for callup args in console */    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;#if	defined(SYNC_CONSOLE_WRITE)    while( isr_reg & ISR_RxRDY )#else    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )#endif    {	if( isr_reg & ISR_RxRDY ) {	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )		L1_collectibles[L1C_REC_STALLS] = ret;	}#if	!defined(SYNC_CONSOLE_WRITE)	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;	    brl1_send_cont(sc);	}#endif	/* SYNC_CONSOLE_WRITE */	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);    }}#endif	/* CONFIG_IA64_SGI_SN1 *//* * Install a callback function for the system console subchannel  * to allow an upper layer to be notified when the send buffer  * has been emptied. */static inline voidl1_tx_notif( brl1_notif_t func ){	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,			SC_CONS_SYSTEM, func );}/* * Install a callback function for the system console subchannel * to allow an upper layer to be notified when a packet has been * received. */static inline voidl1_rx_notif( brl1_notif_t func ){	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,				SC_CONS_SYSTEM, func );}/* brl1_intr is called directly from the uart interrupt; after it runs, the * interrupt "daemon" xthread is signalled to continue. */voidbrl1_intr( void ){}#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value *//* Return the current interrupt level *///#define CONSOLE_POLLING_ALSOintl1_get_intr_value( void ){#if defined(USE_SAL_CONSOLE_IO)	return(0);#else#if defined(CONSOLE_POLLING_ALSO)	return(0);#else	return(BRL1_INTERRUPT_LEVEL);#endif /* CONSOLE_POLLING_ALSO */#endif /* USE_SAL_CONSOLE_IO */}/* Disconnect the callup functions - throw away interrupts */voidl1_unconnect_intr(void){#if !defined(USE_SAL_CONSOLE_IO)	/* UnRegister the upper-level callup functions */	l1_rx_notif((brl1_notif_t)NULL);	l1_tx_notif((brl1_notif_t)NULL);	/* We do NOT unregister the interrupts */#endif /* !USE_SAL_CONSOLE_IO */}/* Set up uart interrupt handling for this node's uart */voidl1_connect_intr(void *rx_notify, void *tx_notify){#if defined(USE_SAL_CONSOLE_IO)#if 0	// Will need code here for sn2 - something like this	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());	intr_connect_level(console_nodepda->node_first_cpu,                                SGI_UART_VECTOR, INTPEND0_MAXMASK,                                dummy_intr_func);	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),                                intr_func, SA_INTERRUPT | SA_SHIRQ,                                "l1_protocol_driver", (void *)sc);#endif#else	l1sc_t *sc;	nasid_t nasid;#if defined(CONFIG_IA64_SGI_SN1)	int tmp;#endif	nodepda_t *console_nodepda;	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);	if ( L1_interrupts_connected ) {		/* Interrupts are connected, so just register the callups */		l1_rx_notif((brl1_notif_t)rx_notify);		l1_tx_notif((brl1_notif_t)tx_notify);		L1_collectibles[L1C_CONNECT_CALLS]++;		return;	}	else		L1_interrupts_connected = 1;	nasid = get_master_nasid();	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));	sc = &console_nodepda->module->elsc;	sc->intr_cpu = console_nodepda->node_first_cpu;#if defined(CONFIG_IA64_SGI_SN1)	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {		L1_interrupts_connected = 0; /* FAILS !! */	}	else {		void synergy_intr_connect(int, int);		synergy_intr_connect(UART_INTR, sc->intr_cpu);		L1_collectibles[L1C_R_IRQ]++;		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;		if ( tmp ) {			L1_interrupts_connected = 0; /* FAILS !! */		}		else {			/* Register the upper-level callup functions */			l1_rx_notif((brl1_notif_t)rx_notify);			l1_tx_notif((brl1_notif_t)tx_notify);			/* Set the uarts the way we like it */			uart_enable_recv_intr( sc );			uart_disable_xmit_intr( sc );		}	}#endif	/* CONFIG_IA64_SGI_SN1 */#endif	/* USE_SAL_CONSOLE_IO */}/* These are functions to use from serial_in/out when in protocol * mode to send and receive uart control regs. These are external * interfaces into the protocol driver. */voidl1_control_out(int offset, int value){#if defined(USE_SAL_CONSOLE_IO)	/* quietly ignore unless simulator */	if ( IS_RUNNING_ON_SIMULATOR() ) {		extern u64 master_node_bedrock_address;		if ( master_node_bedrock_address != (u64)0 ) {			writeb(value, (unsigned long)master_node_bedrock_address +				(offset<< 3));		}		return;	}#else	nasid_t nasid = get_master_nasid();	WRITE_L1_UART_REG(nasid, offset, value); #endif}/* Console input exported interface. Return a register value.  */intl1_control_in_polled(int offset){	static int l1_control_in_local(int, int);	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));}intl1_control_in(int offset){	static int l1_control_in_local(int, int);	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));}static intl1_control_in_local(int offset, int mode){#if defined(USE_SAL_CONSOLE_IO)	int sal_call_status = 0, input;	int ret = 0;	if ( offset == REG_LSR ) {		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */		sal_call_status = ia64_sn_console_check(&input);		if ( !sal_call_status && input ) {			/* input pending */			ret |= LSR_RCA;		}	}	/* If the sal call failed, do it the old-fashioned way */	if ( sal_call_status ) {		if ( IS_RUNNING_ON_SIMULATOR() ) {			extern u64 master_node_bedrock_address;			ret = readb((unsigned long)master_node_bedrock_address +					(offset<< 3));		}				else {#endif	/* USE_SAL_CONSOLE_IO */			nasid_t nasid;			int ret, input;			static int l1_poll(l1sc_t *, int);			nasid = get_master_nasid();			ret = READ_L1_UART_REG(nasid, offset); 			if ( offset == REG_LSR ) {				ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */				if ( L1_cons_is_inited ) {					if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {						input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);						if ( input ) {							ret |= LSR_RCA;						}					}				}			}#if defined(USE_SAL_CONSOLE_IO)		}	}#endif	return(ret);}/* * Console input exported interface. Return a character (if one is available) */intl1_serial_in_polled(void){	static int l1_serial_in_local(int mode);	return(l1_serial_in_local(SERIAL_POLLED_MODE));}intl1_serial_in(void){	static int l1_serial_in_local(int mode);	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));}static intl1_serial_in_local(int mode){#if defined(USE_SAL_CONSOLE_IO)	int sal_call_status;	int ch;	sal_call_status = ia64_sn_console_getc(&ch);	if ( !sal_call_status ) {		return(ch);	}	else {		/* If the sal called failed - do it the old-fashioned way */		if ( IS_RUNNING_ON_SIMULATOR() ) {			extern u64 master_node_bedrock_address;			return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));		}				else {#endif	/* USE_SAL_CONSOLE_IO */			nasid_t nasid;			l1sc_t *sc;			int value;			static int l1_getc( l1sc_t *, int );			static inline l1sc_t *early_sc_init(nasid_t);			nasid = get_master_nasid();			sc = early_sc_init(nasid);			if ( L1_cons_is_inited ) {				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {					sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;				}			}			value = l1_getc(sc, mode);			return(value);#if defined(USE_SAL_CONSOLE_IO)		}	}#endif}/* Console output exported interface. Write message to the console.  */intl1_serial_out( char *str, int len ){#if defined(USE_SAL_CONSOLE_IO)	int sal_call_status = 0;	int counter = len;	/* Attempt to write things out thru the sal */	while ( counter > 0 ) {		if ( (sal_call_status = ia64_sn_console_putc(*str)) ) {			break;		}		counter--;		str++;	}	if ( sal_call_status ) {		/* If the sal called failed - do it the old-fashioned way */		if ( IS_RUNNING_ON_SIMULATOR() ) {			extern u64 master_node_bedrock_address;                        if (!master_node_bedrock_address)                                early_sn_setup();			if ( master_node_bedrock_address != (u64)0 ) {#ifdef FLAG_DIRECT_CONSOLE_WRITES				/* This is an easy way to pre-pend the output to know whether the output				 * was done via sal or directly */				writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));				writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));				writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));				writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));#endif	/* FLAG_DIRECT_CONSOLE_WRITES */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -