Changeset 3e828ea in mainline for kernel/genarch/src


Ignore:
Timestamp:
2019-09-23T12:49:29Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9be2358
Parents:
9259d20 (diff), 1a4ec93f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiri Svoboda <jiri@…> (2019-09-22 12:49:07)
git-committer:
Jiri Svoboda <jiri@…> (2019-09-23 12:49:29)
Message:

Merge changes from master, especially Meson build

Location:
kernel/genarch/src
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/drivers/i8259/i8259.c

    r9259d20 r3e828ea  
    3232/**
    3333 * @file
    34  * @brief PIC driver.
     34 * @brief i8259 driver.
    3535 *
    3636 * Programmable Interrupt Controller for UP systems based on i8259 chip.
     
    4343#include <interrupt.h>
    4444
    45 static void pic_spurious(unsigned int n, istate_t *istate);
     45/* ICW1 bits */
     46#define I8259_ICW1           (1 << 4)
     47#define I8259_ICW1_NEEDICW4  (1 << 0)
     48
     49/* OCW3 bits */
     50#define I8259_OCW3           (1 << 3)
     51#define I8259_OCW3_READ_ISR  (3 << 0)
     52
     53/* OCW4 bits */
     54#define I8259_OCW4           (0 << 3)
     55#define I8259_OCW4_NSEOI     (1 << 5)
     56
     57#define I8259_IRQ_COUNT 8
     58
     59#define I8259_IRQ_SLAVE 2
     60
     61static const char *i8259_get_name(void);
     62
     63pic_ops_t i8259_pic_ops = {
     64        .get_name = i8259_get_name,
     65        .enable_irqs = i8259_enable_irqs,
     66        .disable_irqs = i8259_disable_irqs,
     67        .eoi = i8259_eoi,
     68        .is_spurious = i8259_is_spurious,
     69        .handle_spurious = i8259_handle_spurious
     70};
    4671
    4772// XXX: need to change pic_* API to get rid of these
     
    4974static i8259_t *saved_pic1;
    5075
    51 void i8259_init(i8259_t *pic0, i8259_t *pic1, inr_t pic1_irq,
    52     unsigned int irq0_int, unsigned int irq8_int)
     76void i8259_init(i8259_t *pic0, i8259_t *pic1, unsigned int irq0_vec)
    5377{
    5478        saved_pic0 = pic0;
     
    5680
    5781        /* ICW1: this is ICW1, ICW4 to follow */
    58         pio_write_8(&pic0->port1, PIC_ICW1 | PIC_ICW1_NEEDICW4);
     82        pio_write_8(&pic0->port1, I8259_ICW1 | I8259_ICW1_NEEDICW4);
    5983
    60         /* ICW2: IRQ 0 maps to INT irq0_int */
    61         pio_write_8(&pic0->port2, irq0_int);
     84        /* ICW2: IRQ 0 maps to interrupt vector address irq0_vec */
     85        pio_write_8(&pic0->port2, irq0_vec);
    6286
    63         /* ICW3: pic1 using IRQ IRQ_PIC1 */
    64         pio_write_8(&pic0->port2, 1 << pic1_irq);
     87        /* ICW3: pic1 using IRQ I8259_IRQ_SLAVE */
     88        pio_write_8(&pic0->port2, 1 << I8259_IRQ_SLAVE);
    6589
    6690        /* ICW4: i8086 mode */
     
    6892
    6993        /* ICW1: ICW1, ICW4 to follow */
    70         pio_write_8(&pic1->port1, PIC_ICW1 | PIC_ICW1_NEEDICW4);
     94        pio_write_8(&pic1->port1, I8259_ICW1 | I8259_ICW1_NEEDICW4);
    7195
    72         /* ICW2: IRQ 8 maps to INT irq8_int */
    73         pio_write_8(&pic1->port2, irq8_int);
     96        /* ICW2: IRQ 8 maps to interrupt vector address irq0_vec + 8 */
     97        pio_write_8(&pic1->port2, irq0_vec + I8259_IRQ_COUNT);
    7498
    75         /* ICW3: pic1 is known as IRQ_PIC1 */
    76         pio_write_8(&pic1->port2, pic1_irq);
     99        /* ICW3: pic1 is known as I8259_IRQ_SLAVE */
     100        pio_write_8(&pic1->port2, I8259_IRQ_SLAVE);
    77101
    78102        /* ICW4: i8086 mode */
    79103        pio_write_8(&pic1->port2, 1);
    80104
    81         /*
    82          * Register interrupt handler for the PIC spurious interrupt.
    83          *
    84          * XXX: This is currently broken. Both IRQ 7 and IRQ 15 can be spurious
    85          *      or can be actual interrupts. This needs to be detected when
    86          *      the interrupt happens by inspecting ISR.
    87          */
    88         exc_register(irq0_int + 7, "pic_spurious", false,
    89             (iroutine_t) pic_spurious);
    90 
    91         pic_disable_irqs(0xffff);               /* disable all irq's */
    92         pic_enable_irqs(1 << pic1_irq);         /* but enable pic1_irq */
     105        /* disable all irq's */
     106        i8259_disable_irqs(0xffff);
     107        /* but enable I8259_IRQ_SLAVE */
     108        i8259_enable_irqs(1 << I8259_IRQ_SLAVE);
    93109}
    94110
    95 void pic_enable_irqs(uint16_t irqmask)
     111const char *i8259_get_name(void)
     112{
     113        return "i8259";
     114}
     115
     116void i8259_enable_irqs(uint16_t irqmask)
    96117{
    97118        uint8_t x;
     
    102123                    (uint8_t) (x & (~(irqmask & 0xff))));
    103124        }
    104         if (irqmask >> 8) {
     125        if (irqmask >> I8259_IRQ_COUNT) {
    105126                x = pio_read_8(&saved_pic1->port2);
    106127                pio_write_8(&saved_pic1->port2,
    107                     (uint8_t) (x & (~(irqmask >> 8))));
     128                    (uint8_t) (x & (~(irqmask >> I8259_IRQ_COUNT))));
    108129        }
    109130}
    110131
    111 void pic_disable_irqs(uint16_t irqmask)
     132void i8259_disable_irqs(uint16_t irqmask)
    112133{
    113134        uint8_t x;
     
    118139                    (uint8_t) (x | (irqmask & 0xff)));
    119140        }
    120         if (irqmask >> 8) {
     141        if (irqmask >> I8259_IRQ_COUNT) {
    121142                x = pio_read_8(&saved_pic1->port2);
    122                 pio_write_8(&saved_pic1->port2, (uint8_t) (x | (irqmask >> 8)));
     143                pio_write_8(&saved_pic1->port2,
     144                    (uint8_t) (x | (irqmask >> I8259_IRQ_COUNT)));
    123145        }
    124146}
    125147
    126 void pic_eoi(void)
     148void i8259_eoi(unsigned int irq)
    127149{
    128         pio_write_8(&saved_pic0->port1, PIC_OCW4 | PIC_OCW4_NSEOI);
    129         pio_write_8(&saved_pic1->port1, PIC_OCW4 | PIC_OCW4_NSEOI);
     150        if (irq >= I8259_IRQ_COUNT)
     151                pio_write_8(&saved_pic1->port1, I8259_OCW4 | I8259_OCW4_NSEOI);
     152        pio_write_8(&saved_pic0->port1, I8259_OCW4 | I8259_OCW4_NSEOI);
    130153}
    131154
    132 void pic_spurious(unsigned int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
     155bool i8259_is_spurious(unsigned int irq)
    133156{
    134 #ifdef CONFIG_DEBUG
    135         log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt", CPU->id);
    136 #endif
     157        pio_write_8(&saved_pic0->port1, I8259_OCW3 | I8259_OCW3_READ_ISR);
     158        pio_write_8(&saved_pic1->port1, I8259_OCW3 | I8259_OCW3_READ_ISR);
     159        uint8_t isr_lo = pio_read_8(&saved_pic0->port1);
     160        uint8_t isr_hi = pio_read_8(&saved_pic1->port1);
     161        return !(((isr_hi << I8259_IRQ_COUNT) | isr_lo) & (1 << irq));
     162}
     163
     164void i8259_handle_spurious(unsigned int irq)
     165{
     166        /* For spurious IRQs from pic1, we need to isssue an EOI to pic0 */
     167        if (irq >= I8259_IRQ_COUNT)
     168                pio_write_8(&saved_pic0->port1, I8259_OCW4 | I8259_OCW4_NSEOI);
    137169}
    138170
  • kernel/genarch/src/drivers/ns16550/ns16550.c

    r9259d20 r3e828ea  
    3939#include <genarch/drivers/ns16550/ns16550.h>
    4040#include <ddi/irq.h>
     41#include <ddi/ddi.h>
    4142#include <arch/asm.h>
    4243#include <console/chardev.h>
    4344#include <stdlib.h>
     45#include <align.h>
    4446#include <str.h>
    4547
     
    115117
    116118        if ((!instance->parea.mapped) || (console_override)) {
     119                if (ch == '\n')
     120                        ns16550_sendb(instance, '\r');
     121
    117122                if (ascii_check(ch))
    118123                        ns16550_sendb(instance, (uint8_t) ch);
     
    143148 *
    144149 */
    145 ns16550_instance_t *ns16550_init(ioport8_t *dev, unsigned reg_shift, inr_t inr,
    146     cir_t cir, void *cir_arg, outdev_t **output)
    147 {
    148         ns16550_instance_t *instance =
    149             malloc(sizeof(ns16550_instance_t));
     150ns16550_instance_t *ns16550_init(ioport8_t *dev_phys, unsigned reg_shift,
     151    inr_t inr, cir_t cir, void *cir_arg, outdev_t **output)
     152{
     153        size_t size = 6 * (1U << reg_shift);
     154        ioport8_t *dev = pio_map((void *) dev_phys, size);
     155
     156        ns16550_instance_t *instance = malloc(sizeof(ns16550_instance_t));
    150157        if (instance) {
    151158                instance->ns16550 = dev;
     
    158165                        if (!instance->output) {
    159166                                free(instance);
     167                                pio_unmap((void *) dev_phys, (void *) dev,
     168                                    size);
    160169                                return NULL;
    161170                        }
     
    176185
    177186                ddi_parea_init(&instance->parea);
    178                 instance->parea.pbase = (uintptr_t) dev;
    179                 instance->parea.frames = 1;
     187                instance->parea.pbase = ALIGN_DOWN((uintptr_t) dev_phys,
     188                    PAGE_SIZE);
     189                instance->parea.frames = ALIGN_UP(size, PAGE_SIZE);
    180190                instance->parea.unpriv = false;
    181191                instance->parea.mapped = false;
  • kernel/genarch/src/drivers/pl011/pl011.c

    r9259d20 r3e828ea  
    6060        pl011_uart_t *uart = dev->data;
    6161
    62         if (!ascii_check(ch)) {
     62        /* If the userspace owns the console, do not output anything. */
     63        if (uart->parea.mapped && !console_override)
     64                return;
     65
     66        if (!ascii_check(ch))
    6367                pl011_uart_sendb(uart, U_SPECIAL);
    64         } else {
     68        else {
    6569                if (ch == '\n')
    6670                        pl011_uart_sendb(uart, (uint8_t) '\r');
     
    100104        assert(uart);
    101105        uart->regs = (void *)km_map(addr, sizeof(pl011_uart_regs_t),
    102             KM_NATURAL_ALIGNMENT, PAGE_NOT_CACHEABLE);
     106            KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_NOT_CACHEABLE);
    103107        assert(uart->regs);
    104108
     
    131135        uart->irq.instance = uart;
    132136
     137        ddi_parea_init(&uart->parea);
     138        uart->parea.pbase = addr;
     139        uart->parea.frames = 1;
     140        uart->parea.unpriv = false;
     141        uart->parea.mapped = false;
     142        ddi_parea_register(&uart->parea);
     143
    133144        return true;
    134145}
  • kernel/genarch/src/mm/as_pt.c

    r9259d20 r3e828ea  
    7676            PA2KA(frame_alloc(PTL0_FRAMES, FRAME_LOWMEM, PTL0_SIZE - 1));
    7777
    78         if (flags & FLAG_AS_KERNEL)
    79                 memsetb(dst_ptl0, PTL0_SIZE, 0);
    80         else {
     78        memsetb(dst_ptl0, PTL0_SIZE, 0);
     79
     80        if (!KERNEL_SEPARATE_PTL0 && !(flags & FLAG_AS_KERNEL)) {
    8181                /*
    8282                 * Copy the kernel address space portion to new PTL0.
     
    9393                    &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
    9494
    95                 memsetb(dst_ptl0, PTL0_SIZE, 0);
    9695                memcpy((void *) dst, (void *) src,
    9796                    PTL0_SIZE - (src - (uintptr_t) src_ptl0));
  • kernel/genarch/src/multiboot/multiboot2.c

    r9259d20 r3e828ea  
    6565        multiboot2_memmap_entry_t *entry = (multiboot2_memmap_entry_t *)
    6666            ((uintptr_t) memmap + sizeof(*memmap));
    67         uint32_t pos = sizeof(*memmap);
     67        uint32_t pos = offsetof(multiboot2_tag_t, memmap) + sizeof(*memmap);
    6868
    6969        while ((pos < length) && (e820counter < MEMMAP_E820_MAX_RECORDS)) {
Note: See TracChangeset for help on using the changeset viewer.