Changeset a71c158 in mainline for kernel/arch


Ignore:
Timestamp:
2009-08-21T14:12:45Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e6dce8, b50b5af2, e5792d1
Parents:
90c8b8d
Message:

kernel output devices now suport multiple instances (except ski and sgcn, which respect the same interface, but behave as singletons)
if more than one output device gets initialized, the output is cloned to all of them
get rid of arch_grab_console() and arch_release_console() (output devices can implement a generic "redraw" method, input devices respect the "silent" global variable)
related cleanups and modifications

Location:
kernel/arch
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/amd64.c

    r90c8b8d ra71c158  
    151151                i8254_init();
    152152               
     153#if (defined(CONFIG_FB) || defined(CONFIG_EGA))
     154                bool vesa = false;
     155#endif
     156               
    153157#ifdef CONFIG_FB
    154                 if (vesa_present())
    155                         vesa_init();
    156                 else
    157 #endif
     158                vesa = vesa_init();
     159#endif
     160               
    158161#ifdef CONFIG_EGA
    159                         ega_init(EGA_BASE, EGA_VIDEORAM);  /* video */
    160 #else
    161                         {}
     162                if (!vesa) {
     163                        outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
     164                        if (egadev)
     165                                stdout_wire(egadev);
     166                }
    162167#endif
    163168               
     
    249254}
    250255
    251 /** Acquire console back for kernel
    252  *
    253  */
    254 void arch_grab_console(void)
    255 {
    256 #ifdef CONFIG_FB
    257         if (vesa_present())
    258                 vesa_redraw();
    259         else
    260 #endif
    261 #ifdef CONFIG_EGA
    262                 ega_redraw();
    263 #else
    264                 {}
    265 #endif
    266 }
    267 
    268 /** Return console to userspace
    269  *
    270  */
    271 void arch_release_console(void)
    272 {
    273 }
    274 
    275256/** Construct function pointer
    276257 *
  • kernel/arch/arm32/include/mach/integratorcp/integratorcp.h

    r90c8b8d ra71c158  
    9898
    9999extern void icp_init(void);
    100 extern void icp_fb_init(void);
    101100extern void icp_output_init(void);
    102101extern void icp_input_init(void);
    103 extern void icp_release_console(void);
    104 extern void icp_grab_console(void);
    105102extern void icp_timer_irq_start(void);
    106103extern void icp_cpu_halt(void);
    107104extern void icp_irq_exception(int exc_no, istate_t *istate);
    108105extern uintptr_t icp_get_memory_size(void);
    109 extern uintptr_t icp_get_fb_address(void);
    110 extern void icp_fb_init(void);
    111106extern void icp_frame_init(void);
    112107
  • kernel/arch/arm32/include/mach/testarm/testarm.h

    r90c8b8d ra71c158  
    6868
    6969extern void gxemul_init(void);
    70 extern void gxemul_fb_init(void);
    7170extern void gxemul_output_init(void);
    7271extern void gxemul_input_init(void);
    73 extern void gxemul_release_console(void);
    74 extern void gxemul_grab_console(void);
    7572extern void gxemul_timer_irq_start(void);
    7673extern void gxemul_cpu_halt(void);
    7774extern void gxemul_irq_exception(int exc_no, istate_t *istate);
    7875extern uintptr_t gxemul_get_memory_size(void);
    79 extern uintptr_t gxemul_get_fb_address(void);
    80 extern void gxemul_fb_init(void);
    8176extern void gxemul_frame_init(void);
    8277
  • kernel/arch/arm32/include/machine_func.h

    r90c8b8d ra71c158  
    4949
    5050struct arm_machine_ops {
    51         void            (*machine_grab_console)(void);
    52         void            (*machine_release_console)(void);
    5351        void            (*machine_init)(void);
    5452        void            (*machine_timer_irq_start)(void);
    5553        void            (*machine_cpu_halt)(void);
    5654        uintptr_t       (*machine_get_memory_size)(void);
    57         void            (*machine_fb_init)(void);
    5855        void            (*machine_irq_exception)(int, istate_t*);
    59         uintptr_t       (*machine_get_fb_address)(void);
    6056        void            (*machine_frame_init)(void);
    6157        void            (*machine_output_init)(void);
     
    6460
    6561extern struct arm_machine_ops machine_ops;
    66 
    67 
    68 /** Acquire console back for kernel. */
    69 extern void machine_grab_console(void);
    70 
    71 /** Return console to userspace. */
    72 extern void machine_release_console(void);
    7362
    7463
     
    9180extern uintptr_t machine_get_memory_size(void);
    9281
    93 /** Initializes the Frame Buffer
    94  *
    95  */
    96 extern void machine_fb_init(void);
    97 
    9882
    9983/** Interrupt exception handler.
     
    10488extern void machine_irq_exception(int exc_no, istate_t *istate);
    10589
    106 
    107 /** Returns address of framebuffer device.
    108  *
    109  *  @return Address of framebuffer device.
    110  */
    111 extern uintptr_t machine_get_fb_address(void);
    11290
    11391/*
  • kernel/arch/arm32/src/arm32.c

    r90c8b8d ra71c158  
    8989        interrupt_init();
    9090       
    91 #ifdef CONFIG_FB
    92         machine_fb_init();
    93 #else
    94 #ifdef CONFIG_ARM_PRN
    9591        machine_output_init();
    96 #endif /* CONFIG_ARM_PRN */
    97 #endif /* CONFIG_FB */
    9892}
    9993
     
    182176}
    183177
    184 /** Acquire console back for kernel. */
    185 void arch_grab_console(void)
    186 {
    187         machine_grab_console();
    188 #ifdef CONFIG_FB
    189         fb_redraw();
    190 #endif
    191 }
    192 
    193 /** Return console to userspace. */
    194 void arch_release_console(void)
    195 {
    196         machine_release_console();
    197 }
    198 
    199178/** @}
    200179 */
  • kernel/arch/arm32/src/mach/integratorcp/integratorcp.c

    r90c8b8d ra71c158  
    5757static irq_t icp_timer_irq;
    5858struct arm_machine_ops machine_ops = {
    59         MACHINE_GENFUNC,
    60         MACHINE_GENFUNC,
    6159        icp_init,
    6260        icp_timer_irq_start,
    6361        icp_cpu_halt,
    6462        icp_get_memory_size,
    65         icp_fb_init,
    6663        icp_irq_exception,
    67         icp_get_fb_address,
    6864        icp_frame_init,
    6965        icp_output_init,
     
    128124}
    129125
    130 /** Initializes the icp frame buffer */
    131 void icp_fb_init(void)
    132 {
    133         fb_properties_t prop = {
    134                 .addr = 0,
    135                 .offset = 0,
    136                 .x = 640,
    137                 .y = 480,
    138                 .scan = 2560,
    139                 .visual = VISUAL_BGR_0_8_8_8,
    140         };
    141         prop.addr = icp_get_fb_address();
    142         fb_init(&prop);
    143         fb_parea.pbase = ICP_FB;
    144         fb_parea.frames = 300;
    145         ddi_parea_register(&fb_parea);
    146 }
    147 
    148126/** Initializes icp_hw_map. */
    149127void icp_init(void)
     
    172150}
    173151
    174 
    175 /** Acquire console back for kernel. */
    176 void icp_grab_console(void)
    177 {
    178 }
    179 
    180 /** Return console to userspace. */
    181 void icp_release_console(void)
    182 {
    183 }
    184 
    185152/** Starts icp Real Time Clock device, which asserts regular interrupts.
    186  * 
     153 *
    187154 * @param frequency Interrupts frequency (0 disables RTC).
    188155 */
     
    296263}
    297264
    298 /** Returns address of framebuffer device.
    299  *
    300  *  @return Address of framebuffer device.
    301  */
    302 uintptr_t icp_get_fb_address(void)
    303 {
     265/*
     266 * Integrator specific frame initialization
     267 */
     268void
     269icp_frame_init(void)
     270{
     271        frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
     272        frame_mark_unavailable(0, 256);
     273}
     274
     275void icp_output_init(void)
     276{
     277#ifdef CONFIG_FB
    304278        if (!vga_init) {
    305279                icp_vga_init();
    306280                vga_init = true;
    307281        }
    308         return (uintptr_t) ICP_FB;
    309 }
    310 
    311 /*
    312  * Integrator specific frame initialization
    313  */
    314 void
    315 icp_frame_init(void)
    316 {
    317         frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
    318         frame_mark_unavailable(0, 256);
    319 }
    320 
    321 void icp_output_init(void)
    322 {
     282       
     283        fb_properties_t prop = {
     284                .addr = ICP_FB,
     285                .offset = 0,
     286                .x = 640,
     287                .y = 480,
     288                .scan = 2560,
     289                .visual = VISUAL_BGR_0_8_8_8,
     290        };
     291       
     292        outdev_t *fbdev = fb_init(&prop);
     293        if (fbdev) {
     294                stdout_wire(fbdev);
     295                fb_parea.pbase = ICP_FB;
     296                fb_parea.frames = 300;
     297                ddi_parea_register(&fb_parea);
     298        }
     299#endif
    323300}
    324301
  • kernel/arch/arm32/src/mach/testarm/testarm.c

    r90c8b8d ra71c158  
    5757
    5858struct arm_machine_ops machine_ops = {
    59         MACHINE_GENFUNC,
    60         MACHINE_GENFUNC,
    6159        gxemul_init,
    6260        gxemul_timer_irq_start,
    6361        gxemul_cpu_halt,
    6462        gxemul_get_memory_size,
    65         gxemul_fb_init,
    6663        gxemul_irq_exception,
    67         gxemul_get_fb_address,
    6864        gxemul_frame_init,
    6965        gxemul_output_init,
     
    7874}
    7975
    80 void gxemul_fb_init(void)
    81 {
     76void gxemul_output_init(void)
     77{
     78#ifdef CONFIG_FB
    8279        fb_properties_t prop = {
    8380                .addr = GXEMUL_FB_ADDRESS,
     
    8885                .visual = VISUAL_RGB_8_8_8,
    8986        };
    90         fb_init(&prop);
    91 }
    92 
    93 void gxemul_output_init(void)
    94 {
    95         dsrlnout_init((ioport8_t *) gxemul_kbd);
     87       
     88        outdev_t *fbdev = fb_init(&prop);
     89        if (fbdev)
     90                stdout_wire(fbdev);
     91#endif
     92       
     93#ifdef CONFIG_ARM_PRN
     94        outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) gxemul_kbd);
     95        if (dsrlndev)
     96                stdout_wire(dsrlndev);
     97#endif
    9698}
    9799
     
    233235}
    234236
    235 uintptr_t gxemul_get_fb_address()
    236 {
    237         return ((uintptr_t)GXEMUL_FB_ADDRESS);
    238 }
    239 
    240 
    241237/** @}
    242238 */
  • kernel/arch/arm32/src/machine_func.c

    r90c8b8d ra71c158  
    4141
    4242
    43 /** Acquire console back for kernel. */
    44 void machine_grab_console(void)
    45 {
    46         (machine_ops.machine_grab_console)();
    47 }
    48 
    49 /** Return console to userspace. */
    50 void machine_release_console(void)
    51 {
    52         (machine_ops.machine_release_console)();
    53 }
    54 
    55 
    5643/** Maps HW devices to the kernel address space using #hw_map. */
    5744void machine_init(void)
     
    8471}
    8572
    86 /** Initializes the Frame Buffer
    87  *
    88  */
    89 void machine_fb_init(void)
    90 {
    91         (machine_ops.machine_fb_init)();
    92 }
    93 
    94 
    9573/** Interrupt exception handler.
    9674 *
     
    10381}
    10482
    105 
    106 /** Returns address of framebuffer device.
    107  *
    108  *  @return Address of framebuffer device.
    109  */
    110 uintptr_t machine_get_fb_address(void)
    111 {
    112         return (machine_ops.machine_get_fb_address)();
    113 }
    11483
    11584/*
  • kernel/arch/ia32/include/drivers/vesa.h

    r90c8b8d ra71c158  
    3636#define KERN_ia32_VESA_H_
    3737
    38 extern int vesa_present(void);
    39 extern void vesa_redraw(void);
    40 extern void vesa_init(void);
     38#include <arch/types.h>
     39
     40extern bool vesa_init(void);
    4141
    4242#endif
  • kernel/arch/ia32/src/drivers/vesa.c

    r90c8b8d ra71c158  
    2727 */
    2828
    29 /** @addtogroup ia32   
     29/** @addtogroup ia32
    3030 * @{
    3131 */
     
    4040#include <genarch/fb/visuals.h>
    4141#include <arch/drivers/vesa.h>
     42#include <console/chardev.h>
     43#include <console/console.h>
    4244#include <putchar.h>
    4345#include <mm/page.h>
     
    6668uint8_t vesa_blue_pos;
    6769
    68 int vesa_present(void)
     70bool vesa_init(void)
    6971{
    70         if ((vesa_width != 0xffff) && (vesa_height != 0xffff))
    71                 return true;
     72        if ((vesa_width == 0xffff) || (vesa_height == 0xffff))
     73                return false;
    7274       
    73         return false;
    74 }
    75 
    76 void vesa_init(void)
    77 {
    78         unsigned int visual;
     75        visual_t visual;
    7976       
    8077        switch (vesa_bpp) {
     
    9794                break;
    9895        default:
    99                 panic("Unsupported bits per pixel.");
     96                LOG("Unsupported bits per pixel.");
     97                return false;
    10098        }
    10199       
     
    108106                .visual = visual,
    109107        };
    110         fb_init(&vesa_props);
    111 }
    112 
    113 void vesa_redraw(void)
    114 {
    115         fb_redraw();
     108       
     109        outdev_t *fbdev = fb_init(&vesa_props);
     110        if (!fbdev)
     111                return false;
     112       
     113        stdout_wire(fbdev);
     114        return true;
    116115}
    117116
  • kernel/arch/ia32/src/ia32.c

    r90c8b8d ra71c158  
    112112                i8254_init();
    113113               
     114#if (defined(CONFIG_FB) || defined(CONFIG_EGA))
     115                bool vesa = false;
     116#endif
     117               
    114118#ifdef CONFIG_FB
    115                 if (vesa_present())
    116                         vesa_init();
    117                 else
    118 #endif
     119                vesa = vesa_init();
     120#endif
     121               
    119122#ifdef CONFIG_EGA
    120                         ega_init(EGA_BASE, EGA_VIDEORAM);  /* video */
    121 #else
    122                         {}
     123                if (!vesa) {
     124                        outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
     125                        if (egadev)
     126                                stdout_wire(egadev);
     127                }
    123128#endif
    124129               
     
    201206        THREAD->arch.tls = addr;
    202207        set_tls_desc(addr);
    203 
     208       
    204209        return 0;
    205 }
    206 
    207 /** Acquire console back for kernel
    208  *
    209  */
    210 void arch_grab_console(void)
    211 {
    212 #ifdef CONFIG_FB
    213         if (vesa_present())
    214                 vesa_redraw();
    215         else
    216 #endif
    217 #ifdef CONFIG_EGA
    218                 ega_redraw();
    219 #else
    220                 {}
    221 #endif
    222 }
    223 
    224 /** Return console to userspace
    225  *
    226  */
    227 void arch_release_console(void)
    228 {
    229210}
    230211
  • kernel/arch/ia64/include/drivers/ski.h

    r90c8b8d ra71c158  
    4444} ski_instance_t;
    4545
    46 extern void skiout_init(void);
     46extern outdev_t *skiout_init(void);
    4747
    4848extern ski_instance_t *skiin_init(void);
    4949extern void skiin_wire(ski_instance_t *, indev_t *);
    50 extern void ski_kbd_grab(void);
    51 extern void ski_kbd_release(void);
    5250
    5351#endif
  • kernel/arch/ia64/src/drivers/ski.c

    r90c8b8d ra71c158  
    4747enum {
    4848        /** Interval between polling in microseconds */
    49         POLL_INTERVAL =  10000,  /* 0.01 s */
    50 
     49        POLL_INTERVAL = 10000,  /* 0.01 s */
     50       
    5151        /** Max. number of characters to pull out at a time */
    52         POLL_LIMIT    =    30,
    53 
    54         SKI_INIT_CONSOLE  = 20,
    55         SKI_GETCHAR       = 21,
    56         SKI_PUTCHAR       = 31
     52        POLL_LIMIT = 30,
     53       
     54        SKI_INIT_CONSOLE = 20,
     55        SKI_GETCHAR      = 21,
     56        SKI_PUTCHAR      = 31
    5757};
    5858
    5959static void ski_putchar(outdev_t *, const wchar_t, bool);
    6060
    61 static outdev_operations_t skiout_ops = {
    62         .write = ski_putchar
     61static outdev_operations_t skidev_ops = {
     62        .write = ski_putchar,
     63        .redraw = NULL
    6364};
    6465
    65 static outdev_t skiout;            /**< Ski output device. */
    66 static bool initialized = false;
    67 static bool kbd_disabled = false;
     66static ski_instance_t *instance = NULL;
     67
     68/** Ask debug console if a key was pressed.
     69 *
     70 * Use SSC (Simulator System Call) to
     71 * get character from debug console.
     72 *
     73 * This call is non-blocking.
     74 *
     75 * @return ASCII code of pressed key or 0 if no key pressed.
     76 *
     77 */
     78static wchar_t ski_getchar(void)
     79{
     80        uint64_t ch;
     81       
     82        asm volatile (
     83                "mov r15 = %1\n"
     84                "break 0x80000;;\n"  /* modifies r8 */
     85                "mov %0 = r8;;\n"
     86               
     87                : "=r" (ch)
     88                : "i" (SKI_GETCHAR)
     89                : "r15", "r8"
     90        );
     91       
     92        return (wchar_t) ch;
     93}
     94
     95/** Ask keyboard if a key was pressed.
     96 *
     97 * If so, it will repeat and pull up to POLL_LIMIT characters.
     98 */
     99static void poll_keyboard(ski_instance_t *instance)
     100{
     101        if (silent)
     102                return;
     103       
     104        int count = POLL_LIMIT;
     105       
     106        while (count > 0) {
     107                wchar_t ch = ski_getchar();
     108               
     109                if (ch == '\0')
     110                        break;
     111               
     112                indev_push_character(instance->srlnin, ch);
     113                --count;
     114        }
     115}
     116
     117/** Kernel thread for polling keyboard. */
     118static void kskipoll(void *arg)
     119{
     120        ski_instance_t *instance = (ski_instance_t *) arg;
     121       
     122        while (true) {
     123                if (!silent)
     124                        poll_keyboard(instance);
     125               
     126                thread_usleep(POLL_INTERVAL);
     127        }
     128}
    68129
    69130/** Initialize debug console
     
    75136static void ski_init(void)
    76137{
    77         if (initialized)
     138        if (instance)
    78139                return;
    79140       
     
    86147        );
    87148       
    88         initialized = true;
     149        instance = malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
     150       
     151        if (instance) {
     152                instance->thread = thread_create(kskipoll, instance, TASK, 0,
     153                    "kskipoll", true);
     154               
     155                if (!instance->thread) {
     156                        free(instance);
     157                        instance = NULL;
     158                        return;
     159                }
     160               
     161                instance->srlnin = NULL;
     162        }
    89163}
    90164
     
    124198}
    125199
    126 void skiout_init(void)
     200outdev_t *skiout_init(void)
    127201{
    128202        ski_init();
    129        
    130         outdev_initialize("skiout", &skiout, &skiout_ops);
    131         stdout_wire(&skiout);
    132        
    133         sysinfo_set_item_val("fb", NULL, false);
    134 }
    135 
    136 /** Ask debug console if a key was pressed.
    137  *
    138  * Use SSC (Simulator System Call) to
    139  * get character from debug console.
    140  *
    141  * This call is non-blocking.
    142  *
    143  * @return ASCII code of pressed key or 0 if no key pressed.
    144  *
    145  */
    146 static wchar_t ski_getchar(void)
    147 {
    148         uint64_t ch;
    149        
    150         asm volatile (
    151                 "mov r15 = %1\n"
    152                 "break 0x80000;;\n"  /* modifies r8 */
    153                 "mov %0 = r8;;\n"
    154                
    155                 : "=r" (ch)
    156                 : "i" (SKI_GETCHAR)
    157                 : "r15", "r8"
    158         );
    159        
    160         return (wchar_t) ch;
    161 }
    162 
    163 /** Ask keyboard if a key was pressed.
    164  *
    165  * If so, it will repeat and pull up to POLL_LIMIT characters.
    166  */
    167 static void poll_keyboard(ski_instance_t *instance)
    168 {
    169         wchar_t ch;
    170         int count;
    171 
    172         if (kbd_disabled)
    173                 return;
    174 
    175         count = POLL_LIMIT;
    176 
    177         while (count > 0) {
    178                 ch = ski_getchar();
    179 
    180                 if (ch == '\0')
    181                         break;
    182 
    183                 indev_push_character(instance->srlnin, ch);
    184                 --count;
    185         }
    186 }
    187 
    188 /** Kernel thread for polling keyboard. */
    189 static void kskipoll(void *arg)
    190 {
    191         ski_instance_t *instance = (ski_instance_t *) arg;
    192        
    193         while (true) {
    194                 if (!silent)
    195                         poll_keyboard(instance);
    196                
    197                 thread_usleep(POLL_INTERVAL);
    198         }
     203        if (!instance)
     204                return NULL;
     205       
     206        outdev_t *skidev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
     207        if (!skidev)
     208                return NULL;
     209       
     210        outdev_initialize("skidev", skidev, &skidev_ops);
     211        skidev->data = instance;
     212       
     213        if (!fb_exported) {
     214                /*
     215                 * This is the necessary evil until the userspace driver is entirely
     216                 * self-sufficient.
     217                 */
     218                sysinfo_set_item_val("fb", NULL, false);
     219               
     220                fb_exported = true;
     221        }
     222       
     223        return skidev;
    199224}
    200225
     
    202227{
    203228        ski_init();
    204        
    205         ski_instance_t *instance =
    206             malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
    207        
    208         if (instance) {
    209                 instance->thread = thread_create(kskipoll, instance, TASK, 0,
    210                     "kskipoll", true);
    211                
    212                 if (!instance->thread) {
    213                         free(instance);
    214                         return NULL;
    215                 }
    216                
    217                 instance->srlnin = NULL;
    218         }
    219        
    220229        return instance;
    221230}
     
    233242}
    234243
    235 void ski_kbd_grab(void)
    236 {
    237         kbd_disabled = false;
    238 }
    239 
    240 void ski_kbd_release(void)
    241 {
    242         kbd_disabled = true;
    243 }
    244 
    245244/** @}
    246245 */
  • kernel/arch/ia64/src/ia64.c

    r90c8b8d ra71c158  
    160160        }
    161161       
    162         skiout_init();
     162        outdev_t *skidev = skiout_init();
     163        if (skidev)
     164                stdout_wire(skidev);
    163165#endif
    164166       
    165167#ifdef CONFIG_EGA
    166         ega_init(EGA_BASE, EGA_VIDEORAM);
     168        outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
     169        if (egadev)
     170                stdout_wire(egadev);
    167171#endif
    168172       
     
    249253unative_t sys_tls_set(unative_t addr)
    250254{
    251         return 0;
    252 }
    253 
    254 /** Acquire console back for kernel
    255  *
    256  */
    257 void arch_grab_console(void)
    258 {
    259 #ifdef MACHINE_ski
    260         ski_kbd_grab();
    261 #endif
    262 }
    263 
    264 /** Return console to userspace
    265  *
    266  */
    267 void arch_release_console(void)
    268 {
    269 #ifdef MACHINE_ski
    270         ski_kbd_release();
    271 #endif
     255        return 0;
    272256}
    273257
  • kernel/arch/mips32/src/mips32.c

    r90c8b8d ra71c158  
    144144                .visual = VISUAL_RGB_8_8_8,
    145145        };
    146         fb_init(&gxemul_prop);
    147 #else
     146       
     147        outdev_t *fbdev = fb_init(&gxemul_prop);
     148        if (fbdev)
     149                stdout_wire(fbdev);
     150#endif
     151
    148152#ifdef CONFIG_MIPS_PRN
    149         dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
    150 #endif /* CONFIG_MIPS_PRN */
    151 #endif /* CONFIG_FB */
     153        outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
     154        if (dsrlndev)
     155                stdout_wire(dsrlndev);
     156#endif
    152157}
    153158
     
    252257}
    253258
    254 void arch_grab_console(void)
    255 {
    256 #ifdef CONFIG_FB
    257         fb_redraw();
    258 #endif
    259 }
    260 
    261 /** Return console to userspace
    262  *
    263  */
    264 void arch_release_console(void)
    265 {
    266 }
    267 
    268259/** @}
    269260 */
  • kernel/arch/ppc32/src/ppc32.c

    r90c8b8d ra71c158  
    143143                        .visual = visual,
    144144                };
    145                 fb_init(&fb_prop);
    146         }
    147        
    148         /* Consider only a single device for now */
    149         return false;
     145               
     146                outdev_t *fbdev = fb_init(&fb_prop);
     147                if (fbdev)
     148                        stdout_wire(fbdev);
     149        }
     150       
     151        return true;
    150152}
    151153
     
    235237}
    236238
    237 /** Acquire console back for kernel
    238  *
    239  */
    240 void arch_grab_console(void)
    241 {
    242 #ifdef CONFIG_FB
    243         fb_redraw();
    244 #endif
    245 }
    246 
    247 /** Return console to userspace
    248  *
    249  */
    250 void arch_release_console(void)
    251 {
    252 }
    253 
    254239/** Construct function pointer
    255240 *
  • kernel/arch/sparc64/include/drivers/scr.h

    r90c8b8d ra71c158  
    2727 */
    2828
    29 /** @addtogroup sparc64 
     29/** @addtogroup sparc64
    3030 * @{
    3131 */
     
    5050
    5151extern void scr_init(ofw_tree_node_t *node);
    52 extern void scr_redraw(void);
    5352
    5453#endif
  • kernel/arch/sparc64/include/drivers/sgcn.h

    r90c8b8d ra71c158  
    3939#include <console/chardev.h>
    4040#include <proc/thread.h>
     41#include <synch/spinlock.h>
    4142
    4243/* number of bytes in the TOC magic, including the NULL-terminator */
    43 #define TOC_MAGIC_BYTES         8
     44#define TOC_MAGIC_BYTES  8
    4445
    4546/* number of bytes in the TOC key, including the NULL-terminator */
    46 #define TOC_KEY_SIZE            8
     47#define TOC_KEY_SIZE  8
    4748
    4849/* maximum number of entries in the SRAM table of contents */
    49 #define MAX_TOC_ENTRIES         32
     50#define MAX_TOC_ENTRIES  32
    5051
    5152/* number of bytes in the SGCN buffer magic, including the NULL-terminator */
    52 #define SGCN_MAGIC_BYTES        4
     53#define SGCN_MAGIC_BYTES  4
    5354
    5455/**
    5556 * Entry in the SRAM table of contents. Describes one segment of the SRAM
    5657 * which serves a particular purpose (e.g. OBP serial console, Solaris serial
    57  * console, Solaris mailbox,...). 
     58 * console, Solaris mailbox,...).
    5859 */
    5960typedef struct {
     
    8485/**
    8586 * SGCN buffer header. It is placed at the very beginning of the SGCN
    86  * buffer. 
     87 * buffer.
    8788 */
    8889typedef struct {
     
    104105        /** offset within the SGCN buffer of the input buffer write pointer */
    105106        uint32_t in_wrptr;
    106 
     107       
    107108        /** offset within the SGCN buffer of the output buffer start */
    108109        uint32_t out_begin;
     
    119120
    120121typedef struct {
     122        /** Starting address of SRAM */
     123        uintptr_t sram_begin;
     124       
     125        /** Starting address of the SGCN buffer */
     126        uintptr_t buffer_begin;
     127       
     128        /**
     129         * Ensure that writing to the buffer and consequent
     130         * update of the write pointer are one atomic operation.
     131         */
     132        SPINLOCK_DECLARE(output_lock);
     133       
     134        /**
     135         * Prevent the input buffer read/write pointers from
     136         * getting to inconsistent state.
     137         */
     138        SPINLOCK_DECLARE(input_lock);
     139       
    121140        thread_t *thread;
    122141        indev_t *srlnin;
    123142} sgcn_instance_t;
    124143
    125 extern void sgcn_grab(void);
    126 extern void sgcn_release(void);
    127144extern sgcn_instance_t *sgcnin_init(void);
    128145extern void sgcnin_wire(sgcn_instance_t *, indev_t *);
    129 extern void sgcnout_init(void);
     146extern outdev_t *sgcnout_init(void);
    130147
    131148#endif
  • kernel/arch/sparc64/src/console.c

    r90c8b8d ra71c158  
    103103        }
    104104#endif
     105       
    105106#ifdef CONFIG_SGCN_PRN
    106         sgcnout_init();
     107        outdev_t *sgcndev = sgcnout_init();
     108        if (sgcndev)
     109                stdout_wire(sgcndev);
    107110#endif
    108111}
     
    131134}
    132135
    133 
    134 /** Acquire console back for kernel
    135  *
    136  */
    137 void arch_grab_console(void)
    138 {
    139 #ifdef CONFIG_FB
    140         scr_redraw();
    141 #endif
    142        
    143 #ifdef CONFIG_SGCN_KBD
    144         sgcn_grab();
    145 #endif
    146 }
    147 
    148 /** Return console to userspace
    149  *
    150  */
    151 void arch_release_console(void)
    152 {
    153 #ifdef CONFIG_SGCN_KBD
    154         sgcn_release();
    155 #endif
    156 }
    157 
    158136/** @}
    159137 */
  • kernel/arch/sparc64/src/drivers/scr.c

    r90c8b8d ra71c158  
    4040#include <genarch/fb/fb.h>
    4141#include <genarch/fb/visuals.h>
     42#include <console/chardev.h>
     43#include <console/console.h>
    4244#include <arch/types.h>
    4345#include <string.h>
     
    238240                .visual = visual,
    239241        };
    240         fb_init(&props);
     242       
     243        outdev_t *fbdev = fb_init(&props);
     244        if (fbdev)
     245                stdout_wire(fbdev);
    241246}
    242247
    243 void scr_redraw(void)
    244 {
    245         fb_redraw();
    246 }
    247 
    248248/** @}
    249249 */
  • kernel/arch/sparc64/src/drivers/sgcn.c

    r90c8b8d ra71c158  
    4949#include <synch/spinlock.h>
    5050
    51 #define POLL_INTERVAL           10000
     51#define POLL_INTERVAL  10000
    5252
    5353/*
     
    5757 * not sure whether this value is valid generally.
    5858 */
    59 #define SBBC_START              0x63000000000
     59#define SBBC_START  0x63000000000
    6060
    6161/* offset of SRAM within the SBBC memory */
    62 #define SBBC_SRAM_OFFSET        0x900000
     62#define SBBC_SRAM_OFFSET  0x900000
    6363
    6464/* size (in bytes) of the physical memory area which will be mapped */
    65 #define MAPPED_AREA_SIZE        (128 * 1024)
     65#define MAPPED_AREA_SIZE  (128 * 1024)
    6666
    6767/* magic string contained at the beginning of SRAM */
    68 #define SRAM_TOC_MAGIC          "TOCSRAM"
     68#define SRAM_TOC_MAGIC  "TOCSRAM"
    6969
    7070/*
     
    7878 * Therefore HelenOS needs to make no such arrangements any more.
    7979 */
    80 #define CONSOLE_KEY             "OBPCONS"
     80#define CONSOLE_KEY  "OBPCONS"
    8181
    8282/* magic string contained at the beginning of the console buffer */
    83 #define SGCN_BUFFER_MAGIC       "CON"
     83#define SGCN_BUFFER_MAGIC  "CON"
    8484
    8585/*
     
    8787 * offset from the SRAM beginning.
    8888 */
    89 #define SRAM(type, offset)      ((type *) (sram_begin + (offset)))
     89#define SRAM(type, offset)  ((type *) (instance->sram_begin + (offset)))
    9090
    9191/* Returns a pointer to the SRAM table of contents. */
    92 #define SRAM_TOC                (SRAM(iosram_toc_t, 0))
     92#define SRAM_TOC  (SRAM(iosram_toc_t, 0))
    9393
    9494/*
     
    9797 */
    9898#define SGCN_BUFFER(type, offset) \
    99         ((type *) (sgcn_buffer_begin + (offset)))
     99        ((type *) (instance->buffer_begin + (offset)))
    100100
    101101/** Returns a pointer to the console buffer header. */
    102 #define SGCN_BUFFER_HEADER      (SGCN_BUFFER(sgcn_buffer_header_t, 0))
    103 
    104 /** starting address of SRAM, will be set by the init_sram_begin function */
    105 static uintptr_t sram_begin;
    106 
    107 /**
    108  * starting address of the SGCN buffer, will be set by the
    109  * init_sgcn_buffer_begin function
    110  */
    111 static uintptr_t sgcn_buffer_begin;
    112 
    113 /* true iff the kernel driver should ignore pressed keys */
    114 static bool kbd_disabled;
    115 
    116 /*
    117  * Ensures that writing to the buffer and consequent update of the write pointer
    118  * are together one atomic operation.
    119  */
    120 SPINLOCK_INITIALIZE(sgcn_output_lock);
    121 
    122 /*
    123  * Prevents the input buffer read/write pointers from getting to inconsistent
    124  * state.
    125  */
    126 SPINLOCK_INITIALIZE(sgcn_input_lock);
    127 
    128 
    129 /* functions referenced from definitions of I/O operations structures */
     102#define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
     103
    130104static void sgcn_putchar(outdev_t *, const wchar_t, bool);
    131105
    132 /** SGCN output device operations */
    133 static outdev_operations_t sgcnout_ops = {
    134         .write = sgcn_putchar
     106static outdev_operations_t sgcndev_ops = {
     107        .write = sgcn_putchar,
     108        .redraw = NULL
    135109};
    136110
    137 static outdev_t sgcnout;        /**< SGCN output device. */
     111static sgcn_instance_t *instance = NULL;
    138112
    139113/**
     
    158132static void init_sram_begin(void)
    159133{
    160         ofw_tree_node_t *chosen;
    161         ofw_tree_property_t *iosram_toc;
    162         uintptr_t sram_begin_physical;
    163 
    164         chosen = ofw_tree_lookup("/chosen");
     134        ASSERT(instance)
     135       
     136        ofw_tree_node_t *chosen = ofw_tree_lookup("/chosen");
    165137        if (!chosen)
    166138                panic("Cannot find '/chosen'.");
    167 
    168         iosram_toc = ofw_tree_getprop(chosen, "iosram-toc");
     139       
     140        ofw_tree_property_t *iosram_toc =
     141            ofw_tree_getprop(chosen, "iosram-toc");
    169142        if (!iosram_toc)
    170143                panic("Cannot find property 'iosram-toc'.");
    171144        if (!iosram_toc->value)
    172145                panic("Cannot find SRAM TOC.");
    173 
    174         sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
     146       
     147        uintptr_t sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
    175148            + *((uint32_t *) iosram_toc->value);
    176         sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
     149        instance->sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
    177150       
    178151        register_sram(sram_begin_physical);
     152}
     153
     154/**
     155 * Function regularly called by the keyboard polling thread. Finds out whether
     156 * there are some unread characters in the input queue. If so, it picks them up
     157 * and sends them to the upper layers of HelenOS.
     158 */
     159static void sgcn_poll(sgcn_instance_t *instance)
     160{
     161        uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
     162        uint32_t end = SGCN_BUFFER_HEADER->in_end;
     163        uint32_t size = end - begin;
     164       
     165        if (silent)
     166                return;
     167       
     168        spinlock_lock(&instance->input_lock);
     169       
     170        /* we need pointers to volatile variables */
     171        volatile char *buf_ptr = (volatile char *)
     172            SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
     173        volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
     174        volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
     175       
     176        while (*in_rdptr_ptr != *in_wrptr_ptr) {
     177                buf_ptr = (volatile char *)
     178                    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
     179                char c = *buf_ptr;
     180                *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
     181               
     182                indev_push_character(instance->srlnin, c);
     183        }
     184       
     185        spinlock_unlock(&instance->input_lock);
     186}
     187
     188/**
     189 * Polling thread function.
     190 */
     191static void ksgcnpoll(void *instance) {
     192        while (true) {
     193                if (!silent)
     194                        sgcn_poll(instance);
     195               
     196                thread_usleep(POLL_INTERVAL);
     197        }
    179198}
    180199
     
    190209 * under the sram.buffer.offset sysinfo key.
    191210 */
    192 static void sgcn_buffer_begin_init(void)
    193 {
    194         static bool initialized;
    195        
    196         if (initialized)
     211static void sgcn_init(void)
     212{
     213        if (instance)
    197214                return;
    198 
    199         init_sram_begin();
    200                
    201         ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
    202        
    203         /* lookup TOC entry with the correct key */
    204         uint32_t i;
    205         for (i = 0; i < MAX_TOC_ENTRIES; i++) {
    206                 if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
    207                         break;
    208         }
    209         ASSERT(i < MAX_TOC_ENTRIES);
    210        
    211         sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
    212        
    213         sysinfo_set_item_val("sram.buffer.offset", NULL,
    214             SRAM_TOC->keys[i].offset);
    215        
    216         initialized = true;
     215       
     216        instance = malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
     217       
     218        if (instance) {
     219                instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
     220                    "ksgcnpoll", true);
     221               
     222                if (!instance->thread) {
     223                        free(instance);
     224                        instance = NULL;
     225                        return;
     226                }
     227               
     228                init_sram_begin();
     229               
     230                ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
     231               
     232                /* Lookup TOC entry with the correct key */
     233                uint32_t i;
     234                for (i = 0; i < MAX_TOC_ENTRIES; i++) {
     235                        if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
     236                                break;
     237                }
     238                ASSERT(i < MAX_TOC_ENTRIES);
     239               
     240                instance->buffer_begin =
     241                    instance->sram_begin + SRAM_TOC->keys[i].offset;
     242               
     243                sysinfo_set_item_val("sram.buffer.offset", NULL,
     244                    SRAM_TOC->keys[i].offset);
     245               
     246                instance->srlnin = NULL;
     247        }
    217248}
    218249
     
    228259        uint32_t size = end - begin;
    229260       
    230         /* we need pointers to volatile variables */
     261        /* We need pointers to volatile variables */
    231262        volatile char *buf_ptr = (volatile char *)
    232263            SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
    233264        volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
    234265        volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
    235 
     266       
    236267        /*
    237268         * Write the character and increment the write pointer modulo the
     
    249280         */
    250281        uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
    251         while (*out_rdptr_ptr == new_wrptr)
    252                 ;
     282        while (*out_rdptr_ptr == new_wrptr);
     283       
    253284        *buf_ptr = c;
    254285        *out_wrptr_ptr = new_wrptr;
     
    259290 * character is converted to CRLF.
    260291 */
    261 static void sgcn_putchar(outdev_t *od, const wchar_t ch, bool silent)
     292static void sgcn_putchar(outdev_t *dev, const wchar_t ch, bool silent)
    262293{
    263294        if (!silent) {
    264                 spinlock_lock(&sgcn_output_lock);
     295                spinlock_lock(&instance->output_lock);
    265296               
    266297                if (ascii_check(ch)) {
     
    271302                        sgcn_do_putchar(U_SPECIAL);
    272303               
    273                 spinlock_unlock(&sgcn_output_lock);
    274         }
    275 }
    276 
    277 /**
    278  * Grabs the input for kernel.
    279  */
    280 void sgcn_grab(void)
    281 {
    282         kbd_disabled = false;
    283 }
    284 
    285 /**
    286  * Releases the input so that userspace can use it.
    287  */
    288 void sgcn_release(void)
    289 {
    290         kbd_disabled = true;
    291 }
    292 
    293 /**
    294  * Function regularly called by the keyboard polling thread. Finds out whether
    295  * there are some unread characters in the input queue. If so, it picks them up
    296  * and sends them to the upper layers of HelenOS.
    297  */
    298 static void sgcn_poll(sgcn_instance_t *instance)
    299 {
    300         uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
    301         uint32_t end = SGCN_BUFFER_HEADER->in_end;
    302         uint32_t size = end - begin;
    303 
    304         if (kbd_disabled)
    305                 return;
    306 
    307         spinlock_lock(&sgcn_input_lock);
    308        
    309         /* we need pointers to volatile variables */
    310         volatile char *buf_ptr = (volatile char *)
    311             SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
    312         volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
    313         volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
    314        
    315         while (*in_rdptr_ptr != *in_wrptr_ptr) {
    316                 buf_ptr = (volatile char *)
    317                     SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
    318                 char c = *buf_ptr;
    319                 *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
    320                        
    321                 indev_push_character(instance->srlnin, c);     
    322         }       
    323 
    324         spinlock_unlock(&sgcn_input_lock);
    325 }
    326 
    327 /**
    328  * Polling thread function.
    329  */
    330 static void ksgcnpoll(void *instance) {
    331         while (1) {
    332                 if (!silent)
    333                         sgcn_poll(instance);
    334                 thread_usleep(POLL_INTERVAL);
     304                spinlock_unlock(&instance->output_lock);
    335305        }
    336306}
     
    341311sgcn_instance_t *sgcnin_init(void)
    342312{
    343         sgcn_buffer_begin_init();
    344        
    345         sgcn_instance_t *instance =
    346             malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
    347        
    348         if (instance) {
    349                 instance->srlnin = NULL;
    350                 instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
    351                     "ksgcnpoll", true);
    352                
    353                 if (!instance->thread) {
    354                         free(instance);
    355                         return NULL;
    356                 }
    357         }
    358        
     313        sgcn_init();
    359314        return instance;
    360315}
     
    364319        ASSERT(instance);
    365320        ASSERT(srlnin);
    366 
     321       
    367322        instance->srlnin = srlnin;
    368323        thread_ready(instance->thread);
    369 
     324       
    370325        sysinfo_set_item_val("kbd", NULL, true);
    371326}
     
    374329 * A public function which initializes output to the Serengeti console.
    375330 */
    376 void sgcnout_init(void)
    377 {
    378         sgcn_buffer_begin_init();
    379 
    380         sysinfo_set_item_val("fb.kind", NULL, 4);
    381 
    382         outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);
    383         stdout_wire(&sgcnout);
     331outdev_t *sgcnout_init(void)
     332{
     333        sgcn_init();
     334        if (!instance)
     335                return NULL;
     336       
     337        outdev_t *sgcndev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
     338        if (!sgcndev)
     339                return NULL;
     340       
     341        outdev_initialize("sgcndev", sgcndev, &sgcndev_ops);
     342        sgcndev->data = instance;
     343       
     344        if (!fb_exported) {
     345                /*
     346                 * This is the necessary evil until the userspace driver is entirely
     347                 * self-sufficient.
     348                 */
     349                sysinfo_set_item_val("fb.kind", NULL, 4);
     350               
     351                fb_exported = true;
     352        }
     353       
     354        return sgcndev;
    384355}
    385356
Note: See TracChangeset for help on using the changeset viewer.