]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/serial_io.c
xnu-792.12.6.tar.gz
[apple/xnu.git] / osfmk / ppc / serial_io.c
index 5b637ad5b2d154cfbc0577e64ebff5f8afcc7814..dd7624d099ada7f4ac4c74c886b276230855684d 100644 (file)
@@ -1,26 +1,31 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
+ * This file contains Original Code and/or Modifications of Original Code 
+ * as defined in and that are subject to the Apple Public Source License 
+ * Version 2.0 (the 'License'). You may not use this file except in 
+ * compliance with the License.  The rights granted to you under the 
+ * License may not be used to create, or enable the creation or 
+ * redistribution of, unlawful or unlicensed copies of an Apple operating 
+ * system, or to circumvent, violate, or enable the circumvention or 
+ * violation of, any terms of an Apple operating system software license 
+ * agreement.
+ *
+ * Please obtain a copy of the License at 
+ * http://www.opensource.apple.com/apsl/ and read it before using this 
  * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
+ *
+ * The Original Code and all software distributed under the License are 
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
+ * Please see the License for the specific language governing rights and 
  * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
+ *
+ * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
  */
 /*
  * @OSF_COPYRIGHT@
@@ -72,6 +77,7 @@
 #include <mach/std_types.h>
 #include <types.h>
 #include <sys/syslog.h>
+#include <kern/thread.h>
 #include <ppc/misc_protos.h>
 #include <ppc/proc_reg.h>
 #include <ppc/exception.h>
@@ -101,7 +107,7 @@ struct scc_tty scc_tty[NSCC_LINE];
 extern unsigned int disableSerialOuput;
 
 int    serial_initted = 0;
-unsigned int scc_parm_done = 0;                                /* (TEST/DEBUG) */
+unsigned int scc_parm_done = 0;
 
 extern unsigned int serialmode;
 
@@ -184,7 +190,7 @@ boolean_t scc_funnel_initted = FALSE;
  * Adapt/Probe/Attach functions
  */
 boolean_t      scc_uses_modem_control = FALSE;/* patch this with adb */
-decl_simple_lock_data(,scc_stomp)                      /* (TEST/DEBUG) */
+decl_simple_lock_data(,scc_stomp)
 
 /* This is called VERY early on in the init and therefore has to have
  * hardcoded addresses of the serial hardware control registers. The
@@ -193,7 +199,7 @@ decl_simple_lock_data(,scc_stomp)                   /* (TEST/DEBUG) */
  */
 
 void
-initialize_serial( caddr_t scc_phys_base )
+initialize_serial( caddr_t scc_phys_base, int32_t serial_baud )
 {
        int i, chan, bits;
        scc_regmap_t    regs;
@@ -212,7 +218,9 @@ initialize_serial( caddr_t scc_phys_base )
                return;
        }
 
-       simple_lock_init(&scc_stomp, FALSE);                            /* (TEST/DEBUG) */
+       simple_lock_init(&scc_stomp, FALSE);
+       
+       if (serial_baud == -1) serial_baud = DEFAULT_SPEED;
        
        scc_softc[0].full_modem = TRUE;
 
@@ -232,7 +240,7 @@ initialize_serial( caddr_t scc_phys_base )
 
        /* Call probe so we are ready very early for remote gdb and for serial
           console output if appropriate.  */
-       if (scc_probe()) {
+       if (scc_probe(serial_baud)) {
                for (i = 0; i < NSCC_LINE; i++) {
                        scc_softc[0].softr[i].wr5 = SCC_WR5_DTR | SCC_WR5_RTS;
                        scc_param(scc_tty_for(i));
@@ -241,7 +249,7 @@ initialize_serial( caddr_t scc_phys_base )
 
                        scc_read_reg_zero(regs, 0, bits);/* Clear the status */
                }
-                scc_parm_done = 1;                     /* (TEST/DEBUG) */
+               scc_parm_done = 1;
        }
 
        serial_initted = TRUE;
@@ -251,7 +259,7 @@ initialize_serial( caddr_t scc_phys_base )
 }
 
 int
-scc_probe(void)
+scc_probe(int32_t serial_baud)
 {
        scc_softc_t     scc;
        register int    val, i;
@@ -293,8 +301,8 @@ scc_probe(void)
                  tp->t_ispeed = DEFAULT_PORT0_SPEED;
                  tp->t_ospeed = DEFAULT_PORT0_SPEED;
                } else {
-                 tp->t_ispeed = DEFAULT_SPEED;
-                 tp->t_ospeed = DEFAULT_SPEED;
+                 tp->t_ispeed = serial_baud;
+                 tp->t_ospeed = serial_baud;
                }
                tp->t_flags = DEFAULT_FLAGS;
                scc->softr[i].speed = -1;
@@ -323,12 +331,14 @@ scc_getc(int unit, int line, boolean_t wait, boolean_t raw)
        register scc_regmap_t   regs;
        unsigned char   c, value;
        int             rcvalue, from_line;
+       uint32_t        fcrmunge;
        spl_t           s = splhigh();
        DECL_FUNNEL_VARS
 
        FUNNEL_ENTER(&SCC_FUNNEL);
 
-       simple_lock(&scc_stomp);                                        /* (TEST/DEBUG) */
+
+       simple_lock(&scc_stomp);
        regs = scc_softc[0].regs;
 
        /*
@@ -344,7 +354,7 @@ again:
                        break;
 
                if (!wait) {
-                       simple_unlock(&scc_stomp);                      /* (TEST/DEBUG) */
+                       simple_unlock(&scc_stomp);
                        splx(s);
                        FUNNEL_EXIT(&SCC_FUNNEL);
                        return -1;
@@ -362,14 +372,14 @@ again:
        if (console_is_serial() &&
            c == ('_' & 0x1f)) {
                /* Drop into the debugger */
-               simple_unlock(&scc_stomp);                              /* (TEST/DEBUG) */
+               simple_unlock(&scc_stomp);
                Debugger("Serial Line Request");
-               simple_lock(&scc_stomp);                                /* (TEST/DEBUG) */
+               simple_lock(&scc_stomp);
                scc_write_reg(regs, line, SCC_RR0, SCC_RESET_HIGHEST_IUS);
                if (wait) {
                        goto again;
                }
-               simple_unlock(&scc_stomp);                              /* (TEST/DEBUG) */
+               simple_unlock(&scc_stomp);
                splx(s);
                FUNNEL_EXIT(&SCC_FUNNEL);
                return -1;
@@ -390,7 +400,7 @@ again:
 
        scc_write_reg(regs, line, SCC_RR0, SCC_RESET_HIGHEST_IUS);
 
-       simple_unlock(&scc_stomp);                                      /* (TEST/DEBUG) */
+       simple_unlock(&scc_stomp);
        splx(s);
 
        FUNNEL_EXIT(&SCC_FUNNEL);
@@ -408,14 +418,16 @@ scc_putc(int unit, int line, int c)
        scc_regmap_t    regs;
        spl_t            s;
        unsigned char    value;
+       uint32_t fcrmunge;
        DECL_FUNNEL_VARS
 
+
        if (disableSerialOuput)
                return 0;
 
        s = splhigh();
        FUNNEL_ENTER(&SCC_FUNNEL);
-       simple_lock(&scc_stomp);                                /* (TEST/DEBUG) */
+       simple_lock(&scc_stomp);                
 
        regs = scc_softc[0].regs;
 
@@ -435,7 +447,7 @@ scc_putc(int unit, int line, int c)
                        break;
        } while (1);
        scc_write_reg(regs, line, SCC_RR0, SCC_RESET_HIGHEST_IUS);
-       simple_unlock(&scc_stomp);                              /* (TEST/DEBUG) */
+       simple_unlock(&scc_stomp);              
 
        splx(s);
 
@@ -485,7 +497,7 @@ scc_param(struct scc_tty *tp)
        assert(FUNNEL_IN_USE(&SCC_FUNNEL));
        
        s = splhigh();
-       simple_lock(&scc_stomp);                                /* (TEST/DEBUG) */
+       simple_lock(&scc_stomp);
 
        chan = scc_chan(tp->t_dev);
        scc = &scc_softc[0];
@@ -497,29 +509,29 @@ scc_param(struct scc_tty *tp)
        if ((sr->flags & (TF_ODDP|TF_EVENP)) == (tp->t_flags & (TF_ODDP|TF_EVENP))
            && sr->speed == tp->t_ispeed) {
                assert(FUNNEL_IN_USE(&SCC_FUNNEL));
-               simple_unlock(&scc_stomp);                                      /* (TEST/DEBUG) */
-               splx(s);                                                                                        /* (TEST/DEBUG) */
-               return 0;                                                                                       /* (TEST/DEBUG) */
+               simple_unlock(&scc_stomp);
+               splx(s);
+               return 0;
        }
 
        if(scc_parm_done)       {                                                               
                
-               scc_write_reg(regs,  chan,  3, SCC_WR3_RX_8_BITS|SCC_WR3_RX_ENABLE);    /* (TEST/DEBUG) */
-               sr->wr1 = SCC_WR1_RXI_FIRST_CHAR | SCC_WR1_EXT_IE;      /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  1, sr->wr1);                        /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan, 15, SCC_WR15_ENABLE_ESCC);   /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  7, SCC_WR7P_RX_FIFO);       /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  0, SCC_IE_NEXT_CHAR);       /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  0, SCC_RESET_EXT_IP);       /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  0, SCC_RESET_EXT_IP);       /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  9, SCC_WR9_MASTER_IE|SCC_WR9_NV);   /* (TEST/DEBUG) */
-               scc_read_reg_zero(regs, 0, bits);                                       /* (TEST/DEBUG) */
-               sr->wr1 = SCC_WR1_RXI_FIRST_CHAR | SCC_WR1_EXT_IE;      /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  1, sr->wr1);                        /* (TEST/DEBUG) */
-               scc_write_reg(regs,  chan,  0, SCC_IE_NEXT_CHAR);       /* (TEST/DEBUG) */
-               simple_unlock(&scc_stomp);                                                      /* (TEST/DEBUG) */
-               splx(s);                                                                                        /* (TEST/DEBUG) */
-               return 0;                                                                                       /* (TEST/DEBUG) */
+               scc_write_reg(regs,  chan,  3, SCC_WR3_RX_8_BITS|SCC_WR3_RX_ENABLE);
+               sr->wr1 = SCC_WR1_RXI_FIRST_CHAR | SCC_WR1_EXT_IE;
+               scc_write_reg(regs,  chan,  1, sr->wr1);
+               scc_write_reg(regs,  chan, 15, SCC_WR15_ENABLE_ESCC);
+               scc_write_reg(regs,  chan,  7, SCC_WR7P_RX_FIFO);
+               scc_write_reg(regs,  chan,  0, SCC_IE_NEXT_CHAR);
+               scc_write_reg(regs,  chan,  0, SCC_RESET_EXT_IP);
+               scc_write_reg(regs,  chan,  0, SCC_RESET_EXT_IP);
+               scc_write_reg(regs,  chan,  9, SCC_WR9_MASTER_IE|SCC_WR9_NV);
+               scc_read_reg_zero(regs, 0, bits);
+               sr->wr1 = SCC_WR1_RXI_FIRST_CHAR | SCC_WR1_EXT_IE;
+               scc_write_reg(regs,  chan,  1, sr->wr1);
+               scc_write_reg(regs,  chan,  0, SCC_IE_NEXT_CHAR);
+               simple_unlock(&scc_stomp);
+               splx(s);
+               return 0;
        }
        
        sr->flags = tp->t_flags;
@@ -529,7 +541,7 @@ scc_param(struct scc_tty *tp)
        if (tp->t_ispeed == 0) {
                sr->wr5 &= ~SCC_WR5_DTR;
                scc_write_reg(regs,  chan, 5, sr->wr5);
-               simple_unlock(&scc_stomp);                                                      /* (TEST/DEBUG) */
+               simple_unlock(&scc_stomp);
                splx(s);
 
                assert(FUNNEL_IN_USE(&SCC_FUNNEL));
@@ -635,7 +647,7 @@ scc_param(struct scc_tty *tp)
        sr->wr5 |= SCC_WR5_TX_ENABLE;
        scc_write_reg(regs,  chan,  5, sr->wr5);
 
-       simple_unlock(&scc_stomp);                      /* (TEST/DEBUG) */
+       simple_unlock(&scc_stomp);
        splx(s);
 
        assert(FUNNEL_IN_USE(&SCC_FUNNEL));
@@ -651,25 +663,28 @@ scc_param(struct scc_tty *tp)
 void
 serial_keyboard_init(void)
 {
+       kern_return_t   result;
+       thread_t                thread;
 
        if(!(serialmode & 2)) return;           /* Leave if we do not want a serial console */
 
        kprintf("Serial keyboard started\n");
-       kernel_thread_with_priority(serial_keyboard_start, MAXPRI_STANDARD);
-       return;
+       result = kernel_thread_start_priority((thread_continue_t)serial_keyboard_start, NULL, MAXPRI_KERNEL, &thread);
+       if (result != KERN_SUCCESS)
+               panic("serial_keyboard_init");
+
+       thread_deallocate(thread);
 }
 
 void
 serial_keyboard_start(void)
 {
-       thread_t cthread;
-
-       cthread = current_thread();             /* Just who the heck are we anyway? */
-       stack_privilege(cthread);               /* Make sure we don't lose our stack */
        serial_keyboard_poll();                 /* Go see if there are any characters pending now */
        panic("serial_keyboard_start: we can't get back here\n");
 }
 
+static int ptestxxx = 0;
+
 void
 serial_keyboard_poll(void)
 {
@@ -677,6 +692,7 @@ serial_keyboard_poll(void)
        uint64_t next;
        extern void cons_cinput(char ch);       /* The BSD routine that gets characters */
 
+
        while(1) {                              /* Do this for a while */
                chr = scc_getc(0, 1, 0, 1);     /* Get a character if there is one */
                if(chr < 0) break;              /* The serial buffer is empty */
@@ -685,9 +701,8 @@ serial_keyboard_poll(void)
 
        clock_interval_to_deadline(16, 1000000, &next); /* Get time of pop */
 
-       assert_wait((event_t)serial_keyboard_poll, THREAD_INTERRUPTIBLE);       /* Show we are "waiting" */
-       thread_set_timer_deadline(next);        /* Set the next time to check */
-       thread_block(serial_keyboard_poll);     /* Wait for it */
+       assert_wait_deadline((event_t)serial_keyboard_poll, THREAD_UNINT, next);        /* Show we are "waiting" */
+       thread_block((thread_continue_t)serial_keyboard_poll);  /* Wait for it */
        panic("serial_keyboard_poll: Shouldn't never ever get here...\n");
 }