Changes in / [7c506ced:ca3d77a] in mainline


Ignore:
Files:
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/src/ras.c

    r7c506ced rca3d77a  
    3838#include <mm/frame.h>
    3939#include <mm/page.h>
    40 #include <mm/km.h>
    4140#include <mm/tlb.h>
    4241#include <mm/asid.h>
     
    5150void ras_init(void)
    5251{
    53         uintptr_t frame;
    54 
    55         frame = (uintptr_t) frame_alloc(ONE_FRAME,
    56             FRAME_ATOMIC | FRAME_HIGHMEM);
    57         if (!frame)
    58                 frame = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_LOWMEM);
    59         ras_page = (uintptr_t *) km_map(frame,
    60             PAGE_SIZE, PAGE_READ | PAGE_WRITE | PAGE_USER | PAGE_CACHEABLE);
    61 
    62         memsetb(ras_page, PAGE_SIZE, 0);
     52        ras_page = frame_alloc(ONE_FRAME, FRAME_KA);
     53        memsetb(ras_page, FRAME_SIZE, 0);
    6354        ras_page[RAS_START] = 0;
    6455        ras_page[RAS_END] = 0xffffffff;
     56        /*
     57         * Userspace needs to be able to write to this page. The page is
     58         * cached in TLB as PAGE_KERNEL. Purge it from TLB and map it
     59         * read/write PAGE_USER.
     60         */
     61        tlb_invalidate_pages(ASID_KERNEL, (uintptr_t)ras_page, 1);
     62        page_table_lock(AS, true);
     63        page_mapping_insert(AS, (uintptr_t)ras_page, (uintptr_t)KA2PA(ras_page),
     64            PAGE_READ | PAGE_WRITE | PAGE_USER);
     65        page_table_unlock(AS, true);
    6566}
    6667
  • kernel/genarch/src/acpi/acpi.c

    r7c506ced rca3d77a  
    3939#include <genarch/acpi/madt.h>
    4040#include <arch/bios/bios.h>
     41#include <mm/as.h>
    4142#include <mm/page.h>
    42 #include <mm/km.h>
    4343#include <print.h>
    4444
     
    9696}
    9797
    98 static struct acpi_sdt_header *map_sdt(struct acpi_sdt_header *psdt)
    99 {
    100         struct acpi_sdt_header *vhdr;
    101         struct acpi_sdt_header *vsdt;
    102 
    103         /* Start with mapping the header only. */
    104         vhdr = (struct acpi_sdt_header *) km_map_structure((uintptr_t) psdt,
    105             sizeof(struct acpi_sdt_header), PAGE_READ | PAGE_NOT_CACHEABLE);
    106 
    107         /* Now we can map the entire structure. */
    108         vsdt = (struct acpi_sdt_header *) km_map_structure((uintptr_t) psdt,
    109             vhdr->length, PAGE_WRITE | PAGE_NOT_CACHEABLE);
    110        
    111         // TODO: do not leak vtmp
    112 
    113         return vsdt;
     98static void map_sdt(struct acpi_sdt_header *sdt)
     99{
     100        page_table_lock(AS_KERNEL, true);
     101        page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt,
     102            PAGE_NOT_CACHEABLE | PAGE_WRITE);
     103        map_structure((uintptr_t) sdt, sdt->length);
     104        page_table_unlock(AS_KERNEL, true);
    114105}
    115106
     
    127118                            (struct acpi_sdt_header *) (sysarg_t) acpi_rsdt->entry[i];
    128119                       
    129                         struct acpi_sdt_header *vhdr = map_sdt(hdr);
    130                         if (CMP_SIGNATURE(vhdr->signature, signature_map[j].signature)) {
    131                                 if (!acpi_sdt_check((uint8_t *) vhdr))
     120                        map_sdt(hdr);
     121                        if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) {
     122                                if (!acpi_sdt_check((uint8_t *) hdr))
    132123                                        break;
    133124                               
    134                                 *signature_map[j].sdt_ptr = vhdr;
     125                                *signature_map[j].sdt_ptr = hdr;
    135126                                LOG("%p: ACPI %s", *signature_map[j].sdt_ptr,
    136127                                    signature_map[j].description);
     
    153144                            (struct acpi_sdt_header *) ((uintptr_t) acpi_xsdt->entry[i]);
    154145                       
    155                         struct acpi_sdt_header *vhdr = map_sdt(hdr);
    156                         if (CMP_SIGNATURE(vhdr->signature, signature_map[j].signature)) {
    157                                 if (!acpi_sdt_check((uint8_t *) vhdr))
     146                        map_sdt(hdr);
     147                        if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) {
     148                                if (!acpi_sdt_check((uint8_t *) hdr))
    158149                                        break;
    159150                               
    160                                 *signature_map[j].sdt_ptr = vhdr;
     151                                *signature_map[j].sdt_ptr = hdr;
    161152                                LOG("%p: ACPI %s", *signature_map[j].sdt_ptr,
    162153                                    signature_map[j].description);
     
    196187        LOG("%p: ACPI Root System Description Pointer", acpi_rsdp);
    197188       
    198         uintptr_t acpi_rsdt_p = (uintptr_t) acpi_rsdp->rsdt_address;
    199         uintptr_t acpi_xsdt_p = 0;
    200 
     189        acpi_rsdt = (struct acpi_rsdt *) ((uintptr_t) acpi_rsdp->rsdt_address);
    201190        if (acpi_rsdp->revision)
    202                 acpi_xsdt_p = (uintptr_t) acpi_rsdp->xsdt_address;
    203        
    204         if (acpi_rsdt_p)
    205                 acpi_rsdt = (struct acpi_rsdt *) map_sdt(
    206                     (struct acpi_sdt_header *) acpi_rsdt_p);
    207        
    208         if (acpi_xsdt_p)
    209                 acpi_xsdt = (struct acpi_xsdt *) map_sdt(
    210                     (struct acpi_sdt_header *) acpi_xsdt_p);
     191                acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
     192       
     193        if (acpi_rsdt)
     194                map_sdt((struct acpi_sdt_header *) acpi_rsdt);
     195       
     196        if (acpi_xsdt)
     197                map_sdt((struct acpi_sdt_header *) acpi_xsdt);
    211198       
    212199        if ((acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) {
  • kernel/generic/include/mm/km.h

    r7c506ced rca3d77a  
    5050
    5151extern uintptr_t km_map(uintptr_t, size_t, unsigned int);
    52 extern uintptr_t km_map_structure(uintptr_t, size_t, unsigned int);
    5352
    5453extern uintptr_t km_temporary_page_get(uintptr_t *, frame_flags_t);
  • kernel/generic/include/mm/page.h

    r7c506ced rca3d77a  
    6464extern pte_t *page_table_create(unsigned int);
    6565extern void page_table_destroy(pte_t *);
     66extern void map_structure(uintptr_t, size_t);
    6667
    6768extern int page_find_mapping(uintptr_t, void **);
  • kernel/generic/src/mm/km.c

    r7c506ced rca3d77a  
    145145}
    146146
    147 uintptr_t km_map_structure(uintptr_t paddr, size_t size, unsigned int flags)
    148 {
    149         size_t offs = paddr - ALIGN_DOWN(paddr, FRAME_SIZE);
    150         uintptr_t page;
    151 
    152         page = km_map(ALIGN_DOWN(paddr, FRAME_SIZE), size + offs, flags);
    153         return page + offs;
    154 }
    155147
    156148/** Unmap kernen non-identity page.
  • kernel/generic/src/mm/page.c

    r7c506ced rca3d77a  
    8484}
    8585
     86/** Map memory structure
     87 *
     88 * Identity-map memory structure
     89 * considering possible crossings
     90 * of page boundaries.
     91 *
     92 * @param addr Address of the structure.
     93 * @param size Size of the structure.
     94 *
     95 */
     96void map_structure(uintptr_t addr, size_t size)
     97{
     98        size_t length = size + (addr - (addr & ~(PAGE_SIZE - 1)));
     99        size_t cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0);
     100       
     101        size_t i;
     102        for (i = 0; i < cnt; i++)
     103                page_mapping_insert(AS_KERNEL, addr + i * PAGE_SIZE,
     104                    addr + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE);
     105       
     106        /* Repel prefetched accesses to the old mapping. */
     107        memory_barrier();
     108}
     109
    86110/** Insert mapping of page to frame.
    87111 *
  • kernel/test/mm/mapping1.c

    r7c506ced rca3d77a  
    3131#include <mm/page.h>
    3232#include <mm/frame.h>
     33#include <mm/as.h>
    3334#include <arch/mm/page.h>
    34 #include <mm/km.h>
    3535#include <typedefs.h>
    3636#include <debug.h>
    3737#include <arch.h>
    3838
    39 #define TEST_MAGIC  UINT32_C(0x01234567)
     39#define PAGE0  0x10000000
     40#define PAGE1  (PAGE0 + PAGE_SIZE)
     41
     42#define VALUE0  UINT32_C(0x01234567)
     43#define VALUE1  UINT32_C(0x89abcdef)
    4044
    4145const char *test_mapping1(void)
    4246{
    43         uintptr_t page0, page1;
    44         uintptr_t frame;
    45         uint32_t v;
    46         int i;
     47        uintptr_t frame0, frame1;
     48        uint32_t v0, v1;
    4749       
    48         frame = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_NONE);
     50        frame0 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
     51        frame1 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
     52       
     53        TPRINTF("Writing %#" PRIx32 " to physical address %p.\n",
     54            (uint32_t) VALUE0, (void *) KA2PA(frame0));
     55        *((uint32_t *) frame0) = VALUE0;
     56       
     57        TPRINTF("Writing %#" PRIx32 " to physical address %p.\n",
     58            (uint32_t) VALUE1, (void *) KA2PA(frame1));
     59        *((uint32_t *) frame1) = VALUE1;
     60       
     61        page_table_lock(AS, true);
    4962
    50         page0 = km_map(frame, FRAME_SIZE,
    51             PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
    52         TPRINTF("Virtual address %p mapped to physical address %p.\n",
    53             (void *) page0, (void *) frame);
    54         page1 = km_map(frame, FRAME_SIZE,
    55             PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
    56         TPRINTF("Virtual address %p mapped to physical address %p.\n",
    57             (void *) page1, (void *) frame);
     63        TPRINTF("Mapping virtual address %p to physical address %p.\n",
     64            (void *) PAGE0, (void *) KA2PA(frame0));
     65        page_mapping_insert(AS_KERNEL, PAGE0, KA2PA(frame0), PAGE_PRESENT | PAGE_WRITE);
    5866       
    59         for (i = 0; i < 2; i++) {
    60                 TPRINTF("Writing magic using the first virtual address.\n");
     67        TPRINTF("Mapping virtual address %p to physical address %p.\n",
     68            (void *) PAGE1, (void *) KA2PA(frame1));
     69        page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE);
    6170
    62                 *((uint32_t *) page0) = TEST_MAGIC;
    63 
    64                 TPRINTF("Reading magic using the second virtual address.\n");
    65 
    66                 v = *((uint32_t *) page1);
     71        page_table_unlock(AS, true);
    6772       
    68                 if (v != TEST_MAGIC)
    69                         return "Criss-cross read does not match the value written.";
    70 
    71                 TPRINTF("Writing zero using the second virtual address.\n");
     73        v0 = *((uint32_t *) PAGE0);
     74        v1 = *((uint32_t *) PAGE1);
     75        TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
     76            (void *) PAGE0, v0);
     77        TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
     78            (void *) PAGE1, v1);
    7279       
    73                 *((uint32_t *) page1) = 0;
    74 
    75                 TPRINTF("Reading zero using the first virtual address.\n");
     80        if (v0 != VALUE0)
     81                return "Value at v0 not equal to VALUE0";
     82        if (v1 != VALUE1)
     83                return "Value at v1 not equal to VALUE1";
    7684       
    77                 v = *((uint32_t *) page0);
     85        TPRINTF("Writing %#" PRIx32 " to virtual address %p.\n",
     86            (uint32_t) 0, (void *) PAGE0);
     87        *((uint32_t *) PAGE0) = 0;
    7888       
    79                 if (v != 0)
    80                         return "Criss-cross read does not match the value written.";
    81         }
    82 
    83         // FIXME: do not leak frame, page0 and page1
     89        TPRINTF("Writing %#" PRIx32 " to virtual address %p.\n",
     90            (uint32_t) 0, (void *) PAGE1);
     91        *((uint32_t *) PAGE1) = 0;
     92       
     93        v0 = *((uint32_t *) PAGE0);
     94        v1 = *((uint32_t *) PAGE1);
     95       
     96        TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
     97            (void *) PAGE0, *((uint32_t *) PAGE0));
     98        TPRINTF("Value at virtual address %p is %#" PRIx32 ".\n",
     99            (void *) PAGE1, *((uint32_t *) PAGE1));
     100       
     101        if (v0 != 0)
     102                return "Value at v0 not equal to 0";
     103        if (v1 != 0)
     104                return "Value at v1 not equal to 0";
    84105       
    85106        return NULL;
  • uspace/lib/drv/Makefile

    r7c506ced rca3d77a  
    3535        generic/driver.c \
    3636        generic/dev_iface.c \
    37         generic/interrupt.c \
    3837        generic/log.c \
    3938        generic/logbuf.c \
  • uspace/lib/drv/generic/driver.c

    r7c506ced rca3d77a  
    7070FIBRIL_MUTEX_INITIALIZE(functions_mutex);
    7171
     72/** Interrupts */
     73static interrupt_context_list_t interrupt_contexts;
     74
     75static irq_cmd_t default_cmds[] = {
     76        {
     77                .cmd = CMD_ACCEPT
     78        }
     79};
     80
     81static irq_code_t default_pseudocode = {
     82        sizeof(default_cmds) / sizeof(irq_cmd_t),
     83        default_cmds
     84};
     85
    7286static ddf_dev_t *create_device(void);
    7387static void delete_device(ddf_dev_t *);
     
    7892static remote_handler_t *function_get_default_handler(ddf_fun_t *);
    7993static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t);
     94
     95static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
     96{
     97        int id = (int)IPC_GET_IMETHOD(*icall);
     98        interrupt_context_t *ctx;
     99       
     100        ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
     101        if (ctx != NULL && ctx->handler != NULL)
     102                (*ctx->handler)(ctx->dev, iid, icall);
     103}
     104
     105interrupt_context_t *create_interrupt_context(void)
     106{
     107        interrupt_context_t *ctx;
     108       
     109        ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
     110        if (ctx != NULL)
     111                memset(ctx, 0, sizeof(interrupt_context_t));
     112       
     113        return ctx;
     114}
     115
     116void delete_interrupt_context(interrupt_context_t *ctx)
     117{
     118        if (ctx != NULL)
     119                free(ctx);
     120}
     121
     122void init_interrupt_context_list(interrupt_context_list_t *list)
     123{
     124        memset(list, 0, sizeof(interrupt_context_list_t));
     125        fibril_mutex_initialize(&list->mutex);
     126        list_initialize(&list->contexts);
     127}
     128
     129void
     130add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
     131{
     132        fibril_mutex_lock(&list->mutex);
     133        ctx->id = list->curr_id++;
     134        list_append(&ctx->link, &list->contexts);
     135        fibril_mutex_unlock(&list->mutex);
     136}
     137
     138void remove_interrupt_context(interrupt_context_list_t *list,
     139    interrupt_context_t *ctx)
     140{
     141        fibril_mutex_lock(&list->mutex);
     142        list_remove(&ctx->link);
     143        fibril_mutex_unlock(&list->mutex);
     144}
     145
     146interrupt_context_t *
     147find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
     148{
     149        interrupt_context_t *ctx;
     150       
     151        fibril_mutex_lock(&list->mutex);
     152       
     153        list_foreach(list->contexts, link) {
     154                ctx = list_get_instance(link, interrupt_context_t, link);
     155                if (ctx->id == id) {
     156                        fibril_mutex_unlock(&list->mutex);
     157                        return ctx;
     158                }
     159        }
     160       
     161        fibril_mutex_unlock(&list->mutex);
     162        return NULL;
     163}
     164
     165interrupt_context_t *
     166find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
     167{
     168        interrupt_context_t *ctx;
     169       
     170        fibril_mutex_lock(&list->mutex);
     171       
     172        list_foreach(list->contexts, link) {
     173                ctx = list_get_instance(link, interrupt_context_t, link);
     174                if (ctx->irq == irq && ctx->dev == dev) {
     175                        fibril_mutex_unlock(&list->mutex);
     176                        return ctx;
     177                }
     178        }
     179       
     180        fibril_mutex_unlock(&list->mutex);
     181        return NULL;
     182}
     183
     184
     185int
     186register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,
     187    irq_code_t *pseudocode)
     188{
     189        interrupt_context_t *ctx = create_interrupt_context();
     190       
     191        ctx->dev = dev;
     192        ctx->irq = irq;
     193        ctx->handler = handler;
     194       
     195        add_interrupt_context(&interrupt_contexts, ctx);
     196       
     197        if (pseudocode == NULL)
     198                pseudocode = &default_pseudocode;
     199       
     200        int res = irq_register(irq, dev->handle, ctx->id, pseudocode);
     201        if (res != EOK) {
     202                remove_interrupt_context(&interrupt_contexts, ctx);
     203                delete_interrupt_context(ctx);
     204        }
     205
     206        return res;
     207}
     208
     209int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
     210{
     211        interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
     212            dev, irq);
     213        int res = irq_unregister(irq, dev->handle);
     214       
     215        if (ctx != NULL) {
     216                remove_interrupt_context(&interrupt_contexts, ctx);
     217                delete_interrupt_context(ctx);
     218        }
     219       
     220        return res;
     221}
    80222
    81223static void add_to_functions_list(ddf_fun_t *fun)
     
    850992        driver = drv;
    851993       
    852         /* Initialize interrupt module */
    853         interrupt_init();
     994        /* Initialize the list of interrupt contexts. */
     995        init_interrupt_context_list(&interrupt_contexts);
     996       
     997        /* Set generic interrupt handler. */
     998        async_set_interrupt_received(driver_irq_handler);
    854999       
    8551000        /*
  • uspace/lib/drv/include/ddf/interrupt.h

    r7c506ced rca3d77a  
    6464} interrupt_context_list_t;
    6565
    66 extern void interrupt_init(void);
     66extern interrupt_context_t *create_interrupt_context(void);
     67extern void delete_interrupt_context(interrupt_context_t *);
     68extern void init_interrupt_context_list(interrupt_context_list_t *);
     69extern void add_interrupt_context(interrupt_context_list_t *,
     70    interrupt_context_t *);
     71extern void remove_interrupt_context(interrupt_context_list_t *,
     72    interrupt_context_t *);
     73extern interrupt_context_t *find_interrupt_context_by_id(
     74    interrupt_context_list_t *, int);
     75extern interrupt_context_t *find_interrupt_context(
     76    interrupt_context_list_t *, ddf_dev_t *, int);
     77
    6778extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *,
    6879    irq_code_t *);
Note: See TracChangeset for help on using the changeset viewer.