Changeset 973be64e in mainline


Ignore:
Timestamp:
2005-12-10T00:19:57Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fcfac420
Parents:
705b4149
Message:

Added generic exc_register/exc_dispatch functions,
copied from ia32 architecture. Currently only mips32 uses them.

The chardev_t can now be both input & output device (was
needed for serial driver).

Broken other architectures - ia64, sparc, powerpc will not compile.

Mips32 supports input on all msim, gxemul, indy(tested emulation
in gxemul, loses characters), simics. Simics serial line
is done using polling, I was unable to make it produce
an interrupt when the key was pressed.

Files:
4 added
17 edited
2 moved

Legend:

Unmodified
Added
Removed
  • Makefile

    r705b4149 r973be64e  
    102102        generic/src/console/kconsole.c \
    103103        generic/src/cpu/cpu.c \
     104        generic/src/interrupt/interrupt.c \
    104105        generic/src/main/main.c \
    105106        generic/src/main/kinit.c \
  • arch/ia32/include/ega.h

    r705b4149 r973be64e  
    3636
    3737extern void ega_init(void);
    38 extern void ega_putchar(const char ch);
    3938
    4039#endif
  • arch/ia32/src/drivers/ega.c

    r705b4149 r973be64e  
    3535#include <arch/asm.h>
    3636#include <memstr.h>
     37#include <console/chardev.h>
     38#include <console/console.h>
    3739
    3840/*
     
    4345static spinlock_t egalock;
    4446static __u32 ega_cursor;
     47
     48static void ega_putchar(chardev_t *d, const char ch);
     49
     50chardev_t ega_console;
     51static chardev_operations_t ega_ops = {
     52        .write = ega_putchar
     53};
    4554
    4655void ega_move_cursor(void);
     
    5665        lo = inb(0x3d5);
    5766        ega_cursor = (hi<<8)|lo;
    58         ega_putchar('\n');
     67
     68        chardev_initialize("ega_out", &ega_console, &ega_ops);
     69        stdout = &ega_console;
     70
     71        putchar('\n');
    5972}
    6073
     
    7992}
    8093
    81 void ega_putchar(const char ch)
     94void ega_putchar(chardev_t *d, const char ch)
    8295{
    8396        ipl_t ipl;
     
    112125        outb(0x3d5,ega_cursor&0xff);   
    113126}
    114 
    115 void putchar(const char ch)
    116 {
    117         ega_putchar(ch);
    118 }
  • arch/ia32/src/drivers/i8042.c

    r705b4149 r973be64e  
    6767static volatile int lockflags;          /**< Tracking of multiple keys lockings. */
    6868
    69 static void i8042_suspend(void);
    70 static void i8042_resume(void);
     69static void i8042_suspend(chardev_t *);
     70static void i8042_resume(chardev_t *);
    7171
    7272static chardev_t kbrd;
     
    242242        trap_virtual_enable_irqs(1<<IRQ_KBD);
    243243        spinlock_initialize(&keylock, "i8042_lock");
    244         chardev_initialize(&kbrd, &ops);
     244        chardev_initialize("i8042_kbd", &kbrd, &ops);
    245245        stdin = &kbrd;
    246246}
     
    323323
    324324/* Called from getc(). */
    325 void i8042_resume(void)
     325void i8042_resume(chardev_t *d)
    326326{
    327327}
    328328
    329329/* Called from getc(). */
    330 void i8042_suspend(void)
    331 {
    332 }
     330void i8042_suspend(chardev_t *d)
     331{
     332}
  • arch/mips32/Makefile.inc

    r705b4149 r973be64e  
    109109        arch/$(ARCH)/src/fmath.c \
    110110        arch/$(ARCH)/src/drivers/arc.c \
    111         arch/$(ARCH)/src/drivers/keyboard.c
     111        arch/$(ARCH)/src/drivers/msim.c \
     112        arch/$(ARCH)/src/drivers/serial.c
  • arch/mips32/include/console.h

    r705b4149 r973be64e  
    3131
    3232
    33 #define VIDEORAM        0xB0000000
    34 
    35 #define SERIAL_PORT_BASE        ((char *) 0xB80003f8 )
    36 #define SERIAL_LSR              ((char *) (SERIAL_PORT_BASE + 5))
    37 #define TRANSMIT_EMPTY_BIT      5         
    38 
    3933void console_init(void);
    4034
  • arch/mips32/include/drivers/arc.h

    r705b4149 r973be64e  
    3131
    3232#include <arch/types.h>
     33#include <console/chardev.h>
    3334
    3435#define ARC_BASE_ADDR 0x1000;
     
    213214extern void arc_print_memory_map(void);
    214215extern int arc_enabled(void);
    215 extern void arc_putchar(char ch);
    216216extern void arc_print_devices(void);
    217 extern int arc_getchar(void);
    218217void arc_frame_init(void);
     218chardev_t * arc_console(void);
    219219
    220220#endif
  • arch/mips32/include/drivers/msim.h

    r705b4149 r973be64e  
    11/*
    2  * Copyright (C) 2005 Jakub Jermar
     2 * Copyright (C) 2005 Ondrej Palkovsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 #ifndef __mips32_KEYBOARD_H__
    30 #define __mips32_KEYBOARD_H__
     29#ifndef _MSIM_H_
     30#define _MSIM_H_
    3131
    32 #include <arch/types.h>
    33 #include <arch/interrupt.h>
     32#include <console/chardev.h>
    3433
     34#define MSIM_VIDEORAM            0xB0000000
    3535/** Address of 'keyboard' device. */
    36 #define KEYBOARD_ADDRESS                0xB0000000
     36#define MSIM_KBD_ADDRESS                0xB0000000
     37#define MSIM_KBD_IRQ    2
    3738
    38 extern void keyboard_init(void);
    39 extern void keyboard(void);
    40 extern void keyboard_poll(void);
     39chardev_t * msim_console(void);
    4140
    4241#endif
  • arch/mips32/include/interrupt.h

    r705b4149 r973be64e  
    3232#include <arch/exception.h>
    3333
     34#define IVT_ITEMS   32
     35
    3436#define IRQ2    2
    3537#define IRQ3    3
    3638#define IRQ7    7
    3739
    38 #define KEYBOARD_IRQ    IRQ2
    3940#define TIMER_IRQ       IRQ7
    4041
    4142extern void interrupt(struct exception_regdump *pstate);
     43extern void interrupt_init(void);
    4244
    4345#endif
  • arch/mips32/src/console.c

    r705b4149 r973be64e  
    2727 */
    2828
    29 #include <putchar.h>
    30 #include <arch/types.h>
    31 #include <arch/cp0.h>
     29#include <console/console.h>
    3230#include <arch/console.h>
    33 #include <arch.h>
    3431#include <arch/drivers/arc.h>
    35 #include <arch/arch.h>
    36 
    37 /** Putchar that works with MSIM & gxemul */
    38 static void cons_putchar(const char ch)
    39 {
    40         *((char *) VIDEORAM) = ch;
    41 }
    42 
    43 /** Putchar that works with simics */
    44 static void serial_putchar(const char ch)
    45 {
    46         int i;
    47 
    48         if (ch=='\n')
    49                 putchar('\r');
    50 
    51         /* Wait until transmit buffer empty */
    52         while (! ((*SERIAL_LSR) & (1<<TRANSMIT_EMPTY_BIT)))
    53                 ;
    54         *(SERIAL_PORT_BASE) = ch;
    55 }
    56 
    57 static void (*putchar_func)(const char ch) = cons_putchar;
     32#include <arch/drivers/serial.h>
     33#include <arch/drivers/msim.h>
    5834
    5935void console_init(void)
    6036{
    61         if (arc_enabled())
    62                 putchar_func = arc_putchar;
    63         /* The LSR on the start usually contains this value */
    64         else if (*SERIAL_LSR == 0x60)
    65                 putchar_func = serial_putchar;
    66         else
    67                 putchar_func = cons_putchar;
     37        chardev_t *console;
     38
     39        if (arc_enabled()) {
     40                console = arc_console();
     41        } else if (serial_init()) {
     42                console = serial_console();
     43        } else
     44                console = msim_console();
     45
     46        stdin = console;
     47        stdout = console;
    6848}
    69 
    70 void putchar(const char ch)
    71 {
    72         putchar_func(ch);
    73 }
  • arch/mips32/src/drivers/arc.c

    r705b4149 r973be64e  
    3434#include <arch/mm/frame.h>
    3535#include <mm/frame.h>
     36#include <interrupt.h>
    3637
    3738/* This is a good joke, SGI HAS different types than NT bioses... */
     
    9899static arc_func_vector_t *arc_entry;
    99100
    100 static void _arc_putchar(char ch);
    101 
    102 /** Initialize ARC structure
    103  *
    104  * @return 0 - ARC OK, -1 - ARC does not exist
    105  */
    106 int arc_init(void)
    107 {
    108         if (sbp->signature != ARC_MAGIC) {
    109                 sbp = NULL;
    110                 return -1;
    111         }
    112         arc_entry = sbp->firmwarevector;
    113 
    114         arc_putchar('A');
    115         arc_putchar('R');
    116         arc_putchar('C');
    117         arc_putchar('\n');
    118 }
     101
     102static void arc_putchar(char ch);
    119103
    120104/** Return true if ARC is available */
     
    130114        printf("%s: ",ctypes[c->type]);
    131115        for (i=0;i < c->identifier_len;i++)
    132                 putchar(c->identifier[i]);
    133         putchar('\n');
     116                arc_putchar(c->identifier[i]);
     117        arc_putchar('\n');
    134118}
    135119
     
    175159
    176160/** Print charactor to console */
    177 void arc_putchar(char ch)
     161static void arc_putchar(char ch)
    178162{
    179163        __u32 cnt;
     
    187171}
    188172
     173/** Initialize ARC structure
     174 *
     175 * @return 0 - ARC OK, -1 - ARC does not exist
     176 */
     177int arc_init(void)
     178{
     179        if (sbp->signature != ARC_MAGIC) {
     180                sbp = NULL;
     181                return -1;
     182        }
     183        arc_entry = sbp->firmwarevector;
     184
     185        arc_putchar('A');
     186        arc_putchar('R');
     187        arc_putchar('C');
     188        arc_putchar('\n');
     189}
     190
     191static int kbd_polling_enabled;
     192static chardev_t console;
     193
    189194/** Try to get character, return character or -1 if not available */
    190 int arc_getchar(void)
     195static void arc_keyboard_poll(void)
    191196{
    192197        char ch;
    193198        __u32 count;
    194199        long result;
     200       
     201        if (! kbd_polling_enabled)
     202                return;
    195203
    196204        if (arc_entry->getreadstatus(0))
    197                 return -1;
     205                return;
    198206        result = arc_entry->read(0, &ch, 1, &count);
    199207        if (result || count!=1) {
    200                 cpu_halt();
    201                 return -1;
     208                return;
    202209        }
    203210        if (ch == '\r')
    204                 return '\n';
    205         return ch;
     211                ch = '\n';
     212
     213        chardev_push_character(&console, ch);
     214}
     215
     216static void arc_write(chardev_t *dev, const char ch)
     217{
     218        arc_putchar(ch);
     219}
     220
     221static void arc_enable(chardev_t *dev)
     222{
     223        kbd_polling_enabled = 1;       
     224}
     225
     226static void arc_disable(chardev_t *dev)
     227{
     228        kbd_polling_enabled = 0;
     229}
     230
     231static chardev_operations_t arc_ops = {
     232        .resume = arc_enable,
     233        .suspend = arc_disable,
     234        .write = arc_write
     235};
     236
     237iroutine old_timer;
     238/** Do polling on timer interrupt */
     239static void timer_replace(int n, void *stack)
     240{
     241        arc_keyboard_poll();
     242        old_timer(n, stack);
     243        arc_keyboard_poll();
     244}
     245
     246
     247chardev_t * arc_console(void)
     248{
     249        kbd_polling_enabled = 1;
     250       
     251        chardev_initialize("arc_console", &console, &arc_ops);
     252        old_timer = exc_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
     253        return &console;
    206254}
    207255
  • arch/mips32/src/drivers/msim.c

    r705b4149 r973be64e  
    11/*
    2  * Copyright (C) 2003 Josef Cejka
    3  * Copyright (C) 2005 Jakub Jermar
     2 * Copyright (C) 2005 Ondrej Palkovsky
    43 * All rights reserved.
    54 *
     
    2827 */
    2928
    30 #include <arch/drivers/keyboard.h>
     29#include <interrupt.h>
    3130#include <console/chardev.h>
    32 #include <console/console.h>
     31#include <arch/drivers/msim.h>
    3332#include <arch/cp0.h>
    34 #include <putchar.h>
    35 #include <synch/spinlock.h>
    36 #include <synch/waitq.h>
    37 #include <typedefs.h>
    38 #include <arch/drivers/arc.h>
    3933
    40 static void keyboard_enable(void);
    41 static void keyboard_disable(void);
    42 static void arc_kb_disable(void);
    43 static void arc_kb_enable(void);
     34static chardev_t console;
    4435
    45 static chardev_t kbrd;
     36static void msim_write(chardev_t *dev, const char ch);
     37static void msim_enable(chardev_t *dev);
     38static void msim_disable(chardev_t *dev);
    4639
    47 static chardev_operations_t arc_ops = {
    48         .resume = arc_kb_enable,
    49         .suspend = arc_kb_disable
     40static chardev_operations_t msim_ops = {
     41        .resume = msim_enable,
     42        .suspend = msim_disable,
     43        .write = msim_write
    5044};
    5145
    52 static chardev_operations_t msim_ops = {
    53         .resume = keyboard_enable,
    54         .suspend = keyboard_disable
    55 };
     46/** Putchar that works with MSIM & gxemul */
     47void msim_write(chardev_t *dev, const char ch)
     48{
     49        *((char *) MSIM_VIDEORAM) = ch;
     50}
    5651
    57 static int arc_kb_enabled;
     52/* Called from getc(). */
     53void msim_enable(chardev_t *dev)
     54{
     55        cp0_unmask_int(MSIM_KBD_IRQ);
     56}
    5857
    59 /** Initialize keyboard subsystem. */
    60 void keyboard_init(void)
     58/* Called from getc(). */
     59void msim_disable(chardev_t *dev)
    6160{
    62         if (arc_enabled()) {
    63                 chardev_initialize(&kbrd, &arc_ops);
    64                 arc_kb_enabled = 1;
    65         } else {
    66                 cp0_unmask_int(KEYBOARD_IRQ);
    67                 chardev_initialize(&kbrd, &msim_ops);
    68         }
    69         stdin = &kbrd;
     61        cp0_mask_int(MSIM_KBD_IRQ);
    7062}
    7163
    7264/** Process keyboard interrupt. */
    73 void keyboard(void)
     65static void msim_interrupt(int n, void *stack)
    7466{
    7567        char ch;
    7668
    77         ch = *((char *) KEYBOARD_ADDRESS);
     69        ch = *((char *) MSIM_KBD_ADDRESS);
    7870        if (ch =='\r')
    7971                ch = '\n';
    80         chardev_push_character(&kbrd, ch);
     72        chardev_push_character(&console, ch);
    8173}
    8274
    83 /* Called from getc(). */
    84 void keyboard_enable(void)
     75
     76/* Return console object representing msim console */
     77chardev_t * msim_console(void)
    8578{
    86         cp0_unmask_int(KEYBOARD_IRQ);
     79        chardev_initialize("msim_console", &console, &msim_ops);
     80
     81        exc_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
     82
     83        cp0_unmask_int(MSIM_KBD_IRQ);
     84
     85        return &console;
    8786}
    88 
    89 /* Called from getc(). */
    90 void keyboard_disable(void)
    91 {
    92         cp0_mask_int(KEYBOARD_IRQ);
    93 }
    94 
    95 /*****************************/
    96 /* Arc keyboard */
    97 
    98 void keyboard_poll(void)
    99 {
    100         int ch;
    101 
    102         if (!arc_enabled() || !arc_kb_enabled)
    103                 return;
    104         while ((ch = arc_getchar()) != -1)
    105                 chardev_push_character(&kbrd, ch);             
    106 }
    107 
    108 static void arc_kb_enable(void)
    109 {
    110         arc_kb_enabled = 1;
    111 }
    112 
    113 /* Called from getc(). */
    114 static void arc_kb_disable(void)
    115 {
    116         arc_kb_enabled = 0;
    117 }
  • arch/mips32/src/interrupt.c

    r705b4149 r973be64e  
    2727 */
    2828
     29#include <interrupt.h>
    2930#include <arch/interrupt.h>
    3031#include <arch/types.h>
     
    3637#include <symtab.h>
    3738#include <arch/drivers/arc.h>
    38 #include <arch/drivers/keyboard.h>
    3939
    4040static void print_regdump(struct exception_regdump *pstate)
     
    9494}
    9595
     96static void unhandled_exception(int n, void *stack)
     97{
     98        struct exception_regdump *pstate = (struct exception_regdump *)stack;
     99
     100        print_regdump(pstate);
     101        panic("unhandled interrupt %d\n", n);
     102}
     103
     104static void timer_exception(int n, void *stack)
     105{
     106        cp0_compare_write(cp0_count_read() + cp0_compare_value);
     107        clock();
     108}
     109
     110static void swint0(int n, void *stack)
     111{
     112        cp0_cause_write(cp0_cause_read() & ~(1 << 8)); /* clear SW0 interrupt */
     113}
     114
     115static void swint1(int n, void *stack)
     116{
     117        cp0_cause_write(cp0_cause_read() & ~(1 << 9)); /* clear SW1 interrupt */
     118}
     119
     120/** Basic exception handler */
    96121void interrupt(struct exception_regdump *pstate)
    97122{
     
    102127        cause = (cp0_cause_read() >> 8) &0xff;
    103128       
    104         for (i = 0; i < 8; i++) {
    105                 if (cause & (1 << i)) {
    106                         switch (i) {
    107                                 case 0: /* SW0 - Software interrupt 0 */
    108                                         cp0_cause_write(cp0_cause_read() & ~(1 << 8)); /* clear SW0 interrupt */
    109                                         break;
    110                                 case 1: /* SW1 - Software interrupt 1 */
    111                                         cp0_cause_write(cp0_cause_read() & ~(1 << 9)); /* clear SW1 interrupt */
    112                                         break;
    113                                 case KEYBOARD_IRQ:
    114                                         keyboard();
    115                                         break;
    116                                 case 3:
    117                                 case 4: /* IRQ2 */
    118                                 case 5: /* IRQ3 */
    119                                 case 6: /* IRQ4 */
    120                                 default:
    121                                         print_regdump(pstate);
    122                                         panic("unhandled interrupt %d\n", i);
    123                                         break;
    124                                 case TIMER_IRQ:
    125                                         /* clear timer interrupt & set new */
    126                                         cp0_compare_write(cp0_count_read() + cp0_compare_value);
    127                                         clock();
    128                                         keyboard_poll();
    129                                         break;
    130                         }
    131                 }
    132         }
     129        for (i = 0; i < 8; i++)
     130                if (cause & (1 << i))
     131                        exc_dispatch(i, (void *)pstate);
     132}
    133133
     134/* Initialize basic tables for exception dispatching */
     135void interrupt_init(void)
     136{
     137        int i;
     138
     139        for (i=0;i < IVT_ITEMS; i++)
     140                exc_register(i, "undef", unhandled_exception);
     141
     142        exc_register(TIMER_IRQ, "timer", timer_exception);
     143        exc_register(0, "swint0", swint0);
     144        exc_register(1, "swint1", swint1);
    134145}
  • arch/mips32/src/mips32.c

    r705b4149 r973be64e  
    2727 */
    2828
     29
    2930#include <arch.h>
    3031#include <arch/cp0.h>
    3132#include <arch/exception.h>
    32 #include <arch/asm/regname.h>
    3333#include <arch/asm.h>
    3434#include <mm/vm.h>
     35
    3536#include <userspace.h>
    3637#include <arch/console.h>
    3738#include <memstr.h>
     39#include <proc/thread.h>
     40#include <print.h>
     41
    3842#include <arch/interrupt.h>
    3943#include <arch/drivers/arc.h>
    40 #include <arch/drivers/keyboard.h>
    41 #include <proc/thread.h>
    42 #include <print.h>
     44#include <console/chardev.h>
     45
     46#include <arch/asm/regname.h>
    4347
    4448/* Size of the code jumping to the exception handler code
     
    5559        /* It is not assumed by default */
    5660        interrupts_disable();
     61       
     62        /* Initialize dispatch table */
     63        interrupt_init();
    5764
    5865        arc_init();
     
    8491
    8592        console_init();
    86         keyboard_init();
    8793        arc_print_memory_map();
    8894        arc_print_devices();
  • generic/include/console/chardev.h

    r705b4149 r973be64e  
    3737#define CHARDEV_BUFLEN 512
    3838
     39struct chardev;
     40
    3941/* Character device operations interface. */
    4042struct chardev_operations {
    41         void (* suspend)(void);         /**< Suspend pushing characters. */
    42         void (* resume)(void);          /**< Resume pushing characters. */
     43        void (* suspend)(struct chardev *);/**< Suspend pushing characters. */
     44        void (* resume)(struct chardev *); /**< Resume pushing characters. */
     45        /** Write character to stream */
     46        void (* write)(struct chardev *, char c);
    4347};
    4448
     
    4751/** Character input device. */
    4852struct chardev {
     53        char *name;
     54       
    4955        waitq_t wq;
    5056        spinlock_t lock;                /**< Protects everything below. */
    5157        __u8 buffer[CHARDEV_BUFLEN];
    5258        count_t counter;
     59        chardev_operations_t *op;       /**< Implementation of chardev operations. */
    5360        index_t index;
    54         chardev_operations_t *op;       /**< Implementation of chardev operations. */
     61        void *data;
    5562};
    5663
    57 extern void chardev_initialize(chardev_t *chardev, chardev_operations_t *op);
     64extern void chardev_initialize(char *name,
     65                               chardev_t *chardev,
     66                               chardev_operations_t *op);
    5867void chardev_push_character(chardev_t *chardev, __u8 ch);
    5968
  • generic/include/console/console.h

    r705b4149 r973be64e  
    3434
    3535extern chardev_t *stdin;
     36extern chardev_t *stdout;
    3637
    3738extern __u8 getc(chardev_t *chardev);
    3839extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
     40extern void putchar(char c);
    3941
    4042#endif /* __CHARDEV_H__ */
  • generic/include/print.h

    r705b4149 r973be64e  
    3737#define INT64   8
    3838
    39 extern void putchar(const char c);
    4039extern void printf(const char *fmt, ...);
    4140
  • generic/src/console/chardev.c

    r705b4149 r973be64e  
    3737 * @param op Implementation of character device operations.
    3838 */
    39 void chardev_initialize(chardev_t *chardev, chardev_operations_t *op)
     39void chardev_initialize(char *name,chardev_t *chardev,
     40                        chardev_operations_t *op)
    4041{
     42        chardev->name = name;
     43
    4144        waitq_initialize(&chardev->wq);
    4245        spinlock_initialize(&chardev->lock, "chardev");
     
    5760        if (chardev->counter == CHARDEV_BUFLEN - 1) {
    5861                /* buffer full => disable device interrupt */
    59                 chardev->op->suspend();
     62                chardev->op->suspend(chardev);
    6063        }
    6164
  • generic/src/console/console.c

    r705b4149 r973be64e  
    3838/** Standard input character device. */
    3939chardev_t *stdin = NULL;
     40chardev_t *stdout = NULL;
    4041
    4142/** Get string from character device.
     
    8586        interrupts_restore(ipl);
    8687
    87         chardev->op->resume();
     88        chardev->op->resume(chardev);
    8889
    8990        return ch;
    9091}
     92
     93void putchar(char c)
     94{
     95        stdout->op->write(stdout, c);
     96}
Note: See TracChangeset for help on using the changeset viewer.