Changeset 63530c62 in mainline


Ignore:
Timestamp:
2006-10-14T19:31:03Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e3890b3f
Parents:
7dcf22a
Message:

Changes in ns16550 and z8530 drivers.
Add some stuff for IRQ notifications to irq_t.

Location:
kernel
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/include/drivers/kbd.h

    r7dcf22a r63530c62  
    4747extern kbd_type_t kbd_type;
    4848
    49 extern volatile uint8_t *kbd_virt_address;
    50 
    5149extern void kbd_init(ofw_tree_node_t *node);
    5250
  • kernel/arch/sparc64/include/drivers/ns16550.h

    r7dcf22a r63530c62  
    5151#define LCR_DLAB        0x80    /** Divisor Latch Access bit. */
    5252
    53 static inline uint8_t ns16550_rbr_read(void)
     53/** Structure representing the ns16550 device. */
     54typedef struct {
     55        devno_t devno;
     56        volatile uint8_t *reg;  /** Memory mapped registers of the ns16550. */
     57} ns16550_t;
     58
     59static inline uint8_t ns16550_rbr_read(ns16550_t *dev)
    5460{
    55         return kbd_virt_address[RBR_REG];
     61        return dev->reg[RBR_REG];
    5662}
    5763
    58 static inline uint8_t ns16550_ier_read(void)
     64static inline uint8_t ns16550_ier_read(ns16550_t *dev)
    5965{
    60         return kbd_virt_address[IER_REG];
     66        return dev->reg[IER_REG];
    6167}
    6268
    63 static inline void ns16550_ier_write(uint8_t v)
     69static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v)
    6470{
    65         kbd_virt_address[IER_REG] = v;
     71        dev->reg[IER_REG] = v;
    6672}
    6773
    68 static inline uint8_t ns16550_iir_read(void)
     74static inline uint8_t ns16550_iir_read(ns16550_t *dev)
    6975{
    70         return kbd_virt_address[IIR_REG];
     76        return dev->reg[IIR_REG];
    7177}
    7278
    73 static inline void ns16550_fcr_write(uint8_t v)
     79static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v)
    7480{
    75         kbd_virt_address[FCR_REG] = v;
     81        dev->reg[FCR_REG] = v;
    7682}
    7783
    78 static inline uint8_t ns16550_lcr_read(void)
     84static inline uint8_t ns16550_lcr_read(ns16550_t *dev)
    7985{
    80         return kbd_virt_address[LCR_REG];
     86        return dev->reg[LCR_REG];
    8187}
    8288
    83 static inline void ns16550_lcr_write(uint8_t v)
     89static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v)
    8490{
    85         kbd_virt_address[LCR_REG] = v;
     91        dev->reg[LCR_REG] = v;
    8692}
    8793
    88 static inline uint8_t ns16550_lsr_read(void)
     94static inline uint8_t ns16550_lsr_read(ns16550_t *dev)
    8995{
    90         return kbd_virt_address[LSR_REG];
     96        return dev->reg[LSR_REG];
    9197}
    9298
  • kernel/arch/sparc64/include/drivers/z8530.h

    r7dcf22a r63530c62  
    9292#define RR0_RCA         (0x1<<0)        /** Receive Character Available. */
    9393
    94 static inline void z8530_write(index_t chan, uint8_t reg, uint8_t val)
     94/** Structure representing the z8530 device. */
     95typedef struct {
     96        devno_t devno;
     97        volatile uint8_t *reg;          /** Memory mapped registers of the z8530. */
     98} z8530_t;
     99
     100static inline void z8530_write(z8530_t *dev, index_t chan, uint8_t reg, uint8_t val)
    95101{
    96102        /*
     
    98104         * command as their bit 3 is 1.
    99105         */
    100         kbd_virt_address[WR0+chan] = reg;       /* select register */
    101         kbd_virt_address[WR0+chan] = val;       /* write value */
     106        dev->reg[WR0+chan] = reg;       /* select register */
     107        dev->reg[WR0+chan] = val;       /* write value */
    102108}
    103109
    104 static inline void z8530_write_a(uint8_t reg, uint8_t val)
     110static inline void z8530_write_a(z8530_t *dev, uint8_t reg, uint8_t val)
    105111{
    106         z8530_write(Z8530_CHAN_A, reg, val);
     112        z8530_write(dev, Z8530_CHAN_A, reg, val);
    107113}
    108 static inline void z8530_write_b(uint8_t reg, uint8_t val)
     114static inline void z8530_write_b(z8530_t *dev, uint8_t reg, uint8_t val)
    109115{
    110         z8530_write(Z8530_CHAN_B, reg, val);
     116        z8530_write(dev, Z8530_CHAN_B, reg, val);
    111117}
    112118
    113 static inline uint8_t z8530_read(index_t chan, uint8_t reg)
     119static inline uint8_t z8530_read(z8530_t *dev, index_t chan, uint8_t reg)
    114120{
    115121        /*
     
    117123         * command as their bit 3 is 1.
    118124         */
    119         kbd_virt_address[WR0+chan] = reg;       /* select register */
    120         return kbd_virt_address[WR0+chan];
     125        dev->reg[WR0+chan] = reg;       /* select register */
     126        return dev->reg[WR0+chan];
    121127}
    122128
    123 static inline uint8_t z8530_read_a(uint8_t reg)
     129static inline uint8_t z8530_read_a(z8530_t *dev, uint8_t reg)
    124130{
    125         return z8530_read(Z8530_CHAN_A, reg);
     131        return z8530_read(dev, Z8530_CHAN_A, reg);
    126132}
    127 static inline uint8_t z8530_read_b(uint8_t reg)
     133static inline uint8_t z8530_read_b(z8530_t *dev, uint8_t reg)
    128134{
    129         return z8530_read(Z8530_CHAN_B, reg);
     135        return z8530_read(dev, Z8530_CHAN_B, reg);
    130136}
    131137
  • kernel/arch/sparc64/src/drivers/kbd.c

    r7dcf22a r63530c62  
    5050#include <print.h>
    5151
    52 volatile uint8_t *kbd_virt_address = NULL;
    53 
    5452kbd_type_t kbd_type = KBD_UNKNOWN;
    55 
    56 static irq_t kbd_irq;
    5753
    5854/** Initialize keyboard.
     
    10399        uintptr_t pa;
    104100        size_t size;
    105         int inr;
    106        
    107         irq_initialize(&kbd_irq);
     101        inr_t inr;
     102        devno_t devno = device_assign_devno();
    108103       
    109104        switch (kbd_type) {
     
    117112                        printf("Failed to determine keyboard interrupt.\n");
    118113                        return;
    119                 } else {
    120                         kbd_irq.inr = inr;
    121                         kbd_irq.devno = device_assign_devno();
    122                         kbd_irq.trigger = IRQ_TRIGGER_LEVEL;
    123                         kbd_irq.claim = z8530_claim;
    124                         kbd_irq.handler = z8530_irq_handler;
    125                         irq_register(&kbd_irq);
    126114                }
    127115                break;
     
    136124                        printf("Failed to determine keyboard interrupt.\n");
    137125                        return;
    138                 } else {
    139                         kbd_irq.inr = inr;
    140                         kbd_irq.devno = device_assign_devno();
    141                         kbd_irq.trigger = IRQ_TRIGGER_LEVEL;
    142                         kbd_irq.claim = ns16550_claim;
    143                         kbd_irq.handler = ns16550_irq_handler;
    144                         irq_register(&kbd_irq);
    145                 }
     126                };
    146127                break;
    147128
     
    158139        aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
    159140        offset = pa - aligned_addr;
    160         kbd_virt_address = (uint8_t *) hw_map(aligned_addr, offset + size) + offset;
     141        uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset;
    161142
    162143        switch (kbd_type) {
    163144#ifdef CONFIG_Z8530
    164145        case KBD_Z8530:
    165                 z8530_init();
     146                z8530_init(devno, inr, vaddr);
    166147                break;
    167148#endif
    168149#ifdef CONFIG_NS16550
    169150        case KBD_NS16550:
    170                 ns16550_init();
     151                ns16550_init(devno, inr, vaddr);
    171152                break;
    172153#endif
  • kernel/genarch/include/kbd/ns16550.h

    r7dcf22a r63530c62  
    4141#include <ddi/irq.h>
    4242
    43 extern void ns16550_init(void);
     43extern void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr);
    4444extern void ns16550_poll(void);
    4545extern void ns16550_grab(void);
  • kernel/genarch/include/kbd/z8530.h

    r7dcf22a r63530c62  
    4343extern bool z8530_belongs_to_kernel;
    4444
    45 extern void z8530_init(void);
     45extern void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr);
    4646extern void z8530_poll(void);
    4747extern void z8530_grab(void);
  • kernel/genarch/src/kbd/ns16550.c

    r7dcf22a r63530c62  
    11/*
    2  * Copyright (C) 2001-2004 Jakub Jermar
     2 * Copyright (C) 2001-2006 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    5353#define LSR_DATA_READY  0x01
    5454
     55/** Structure representing the ns16550. */
     56static ns16550_t ns16550;
     57
     58/** Structure for ns16550's IRQ. */
     59static irq_t ns16550_irq;
     60
    5561/*
    5662 * These codes read from ns16550 data register are silently ignored.
     
    8288}
    8389
    84 /** Initialize ns16550. */
    85 void ns16550_init(void)
     90/** Initialize ns16550.
     91 *
     92 * @param devno Device number.
     93 * @param inr Interrupt number.
     94 * @param vaddr Virtual address of device's registers.
     95 */
     96void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr)
    8697{
    8798        ns16550_grab();
     
    89100        stdin = &kbrd;
    90101       
     102        ns16550.devno = devno;
     103        ns16550.reg = (uint8_t *) vaddr;
     104       
     105        irq_initialize(&ns16550_irq);
     106        ns16550_irq.devno = devno;
     107        ns16550_irq.inr = inr;
     108        ns16550_irq.claim = ns16550_claim;
     109        ns16550_irq.handler = ns16550_irq_handler;
     110        irq_register(&ns16550_irq);
     111       
    91112        sysinfo_set_item_val("kbd", NULL, true);
    92         sysinfo_set_item_val("kbd.irq", NULL, 0);
    93         sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) kbd_virt_address);
     113        sysinfo_set_item_val("kbd.devno", NULL, devno);
     114        sysinfo_set_item_val("kbd.inr", NULL, inr);
     115        sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);
    94116       
    95         ns16550_ier_write(IER_ERBFI);                           /* enable receiver interrupt */
     117        ns16550_ier_write(&ns16550, IER_ERBFI);         /* enable receiver interrupt */
    96118       
    97         while (ns16550_lsr_read() & LSR_DATA_READY)
    98                 (void) ns16550_rbr_read();
     119        while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
     120                (void) ns16550_rbr_read(&ns16550);
    99121}
    100122
     
    130152        while(!(ch = active_read_buff_read())) {
    131153                uint8_t x;
    132                 while (!(ns16550_lsr_read() & LSR_DATA_READY))
     154                while (!(ns16550_lsr_read(&ns16550) & LSR_DATA_READY))
    133155                        ;
    134                 x = ns16550_rbr_read();
     156                x = ns16550_rbr_read(&ns16550);
    135157                if (x != IGNORE_CODE) {
    136158                        if (x & KEY_RELEASE)
     
    151173        uint8_t x;
    152174
    153         while (ns16550_lsr_read() & LSR_DATA_READY) {
    154                 x = ns16550_rbr_read();
     175        while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
     176                x = ns16550_rbr_read(&ns16550);
    155177                if (x != IGNORE_CODE) {
    156178                        if (x & KEY_RELEASE)
  • kernel/genarch/src/kbd/z8530.c

    r7dcf22a r63530c62  
    6161bool z8530_belongs_to_kernel = true;
    6262
     63static z8530_t z8530;           /**< z8530 device structure. */
     64static irq_t z8530_irq;         /**< z8530's IRQ. */
     65
    6366static void z8530_suspend(chardev_t *);
    6467static void z8530_resume(chardev_t *);
     
    8588
    8689/** Initialize z8530. */
    87 void z8530_init(void)
     90void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr)
    8891{
    8992        chardev_initialize("z8530_kbd", &kbrd, &ops);
    9093        stdin = &kbrd;
    9194
     95        z8530.devno = devno;
     96        z8530.reg = (uint8_t *) vaddr;
     97
     98        irq_initialize(&z8530_irq);
     99        z8530_irq.devno = devno;
     100        z8530_irq.inr = inr;
     101        z8530_irq.claim = z8530_claim;
     102        z8530_irq.handler = z8530_irq_handler;
     103        irq_register(&z8530_irq);
     104
    92105        sysinfo_set_item_val("kbd", NULL, true);
    93         sysinfo_set_item_val("kbd.irq", NULL, 0);
    94         sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) kbd_virt_address);
    95 
    96         (void) z8530_read_a(RR8);
     106        sysinfo_set_item_val("kbd.devno", NULL, devno);
     107        sysinfo_set_item_val("kbd.inr", NULL, inr);
     108        sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);
     109
     110        (void) z8530_read_a(&z8530, RR8);
    97111
    98112        /*
     
    100114         * to set FHC UART interrupt state to idle.
    101115         */
    102         z8530_write_a(WR0, WR0_TX_IP_RST);
    103 
    104         z8530_write_a(WR1, WR1_IARCSC);         /* interrupt on all characters */
     116        z8530_write_a(&z8530, WR0, WR0_TX_IP_RST);
     117
     118        z8530_write_a(&z8530, WR1, WR1_IARCSC);         /* interrupt on all characters */
    105119
    106120        /* 8 bits per character and enable receiver */
    107         z8530_write_a(WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
     121        z8530_write_a(&z8530, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
    108122       
    109         z8530_write_a(WR9, WR9_MIE);            /* Master Interrupt Enable. */
     123        z8530_write_a(&z8530, WR9, WR9_MIE);            /* Master Interrupt Enable. */
    110124}
    111125
     
    140154        while(!(ch = active_read_buff_read())) {
    141155                uint8_t x;
    142                 while (!(z8530_read_a(RR0) & RR0_RCA))
     156                while (!(z8530_read_a(&z8530, RR0) & RR0_RCA))
    143157                        ;
    144                 x = z8530_read_a(RR8);
     158                x = z8530_read_a(&z8530, RR8);
    145159                if (x != IGNORE_CODE) {
    146160                        if (x & KEY_RELEASE)
     
    161175        uint8_t x;
    162176
    163         while (z8530_read_a(RR0) & RR0_RCA) {
    164                 x = z8530_read_a(RR8);
     177        while (z8530_read_a(&z8530, RR0) & RR0_RCA) {
     178                x = z8530_read_a(&z8530, RR8);
    165179                if (x != IGNORE_CODE) {
    166180                        if (x & KEY_RELEASE)
     
    174188irq_ownership_t z8530_claim(void)
    175189{
    176         return (z8530_read_a(RR0) & RR0_RCA);
     190        return (z8530_read_a(&z8530, RR0) & RR0_RCA);
    177191}
    178192
  • kernel/generic/include/ddi/irq.h

    r7dcf22a r63530c62  
    3838#include <arch/types.h>
    3939#include <adt/list.h>
     40#include <ipc/ipc.h>
     41#include <ipc/irq.h>
     42#include <atomic.h>
     43#include <synch/spinlock.h>
    4044
    4145typedef enum {
     
    6367        link_t link;
    6468
     69        /** Lock protecting everything in this structure
     70         *  except the link member. When both the IRQ
     71         *  hash table lock and this lock are to be acquired,
     72         *  this lock must not be taken first.
     73         */
     74        SPINLOCK_DECLARE(lock);
     75
    6576        /** Unique device number. -1 if not yet assigned. */
    6677        devno_t devno;
     
    6879        /** Actual IRQ number. -1 if not yet assigned. */
    6980        inr_t inr;
    70         /** Task ID of the task to be notified about the IRQ or 0. */
    71         task_id_t notif;
    7281        /** Trigger level of the IRQ.*/
    7382        irq_trigger_t trigger;
     
    7887        /** Argument for the handler. */
    7988        void *arg;
     89
     90        /** Answerbox of the task that wanted to be notified. */
     91        answerbox_t *notif_answerbox;
     92        /** Pseudo-code to be performed by the top-half
     93         *  before a notification is sent. */
     94        irq_code_t *code;
     95        /** Counter of IRQ notifications. */
     96        atomic_t counter;
    8097};
    8198
  • kernel/generic/src/ddi/irq.c

    r7dcf22a r63530c62  
    6464#include <typedefs.h>
    6565#include <synch/spinlock.h>
     66#include <atomic.h>
    6667#include <arch.h>
    6768
     
    128129{
    129130        link_initialize(&irq->link);
     131        spinlock_initialize(&irq->lock, "irq.lock");
    130132        irq->inr = -1;
    131133        irq->devno = -1;
    132         irq->notif = 0;
    133134        irq->trigger = 0;
    134135        irq->claim = NULL;
    135136        irq->handler = NULL;
    136137        irq->arg = NULL;
     138        irq->notif_answerbox = NULL;
     139        irq->code = NULL;
     140        atomic_set(&irq->counter, 0);
    137141}
    138142
     
    221225        irq_t *irq = hash_table_get_instance(item, irq_t, link);
    222226        inr_t *inr = (inr_t *) key;
    223        
    224         return ((irq->inr == *inr) && (irq->claim() == IRQ_ACCEPT));
     227        bool rv;
     228       
     229        spinlock_lock(&irq->lock);
     230        rv = ((irq->inr == *inr) && (irq->claim() == IRQ_ACCEPT));
     231        spinlock_unlock(&irq->lock);
     232
     233        return rv;
    225234}
    226235
     
    260269{
    261270        irq_t *irq = list_get_instance(item, irq_t, link);
    262        
    263         return (irq->claim() == IRQ_ACCEPT);
     271        bool rv;
     272       
     273        spinlock_lock(&irq->lock);
     274        rv = (irq->claim() == IRQ_ACCEPT);
     275        spinlock_unlock(&irq->lock);
     276       
     277        return rv;
    264278}
    265279
Note: See TracChangeset for help on using the changeset viewer.