Changeset 7c506ced in mainline


Ignore:
Timestamp:
2012-01-29T10:27:40Z (13 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1d69c69
Parents:
ca3d77a (diff), dc9a3ba (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.
Message:

Merge with mainline

Files:
1 added
10 edited

Legend:

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

    rca3d77a r7c506ced  
    3838#include <mm/frame.h>
    3939#include <mm/page.h>
     40#include <mm/km.h>
    4041#include <mm/tlb.h>
    4142#include <mm/asid.h>
     
    5051void ras_init(void)
    5152{
    52         ras_page = frame_alloc(ONE_FRAME, FRAME_KA);
    53         memsetb(ras_page, FRAME_SIZE, 0);
     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);
    5463        ras_page[RAS_START] = 0;
    5564        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);
    6665}
    6766
  • kernel/genarch/src/acpi/acpi.c

    rca3d77a r7c506ced  
    3939#include <genarch/acpi/madt.h>
    4040#include <arch/bios/bios.h>
    41 #include <mm/as.h>
    4241#include <mm/page.h>
     42#include <mm/km.h>
    4343#include <print.h>
    4444
     
    9696}
    9797
    98 static 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);
     98static 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;
    105114}
    106115
     
    118127                            (struct acpi_sdt_header *) (sysarg_t) acpi_rsdt->entry[i];
    119128                       
    120                         map_sdt(hdr);
    121                         if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) {
    122                                 if (!acpi_sdt_check((uint8_t *) hdr))
     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))
    123132                                        break;
    124133                               
    125                                 *signature_map[j].sdt_ptr = hdr;
     134                                *signature_map[j].sdt_ptr = vhdr;
    126135                                LOG("%p: ACPI %s", *signature_map[j].sdt_ptr,
    127136                                    signature_map[j].description);
     
    144153                            (struct acpi_sdt_header *) ((uintptr_t) acpi_xsdt->entry[i]);
    145154                       
    146                         map_sdt(hdr);
    147                         if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) {
    148                                 if (!acpi_sdt_check((uint8_t *) hdr))
     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))
    149158                                        break;
    150159                               
    151                                 *signature_map[j].sdt_ptr = hdr;
     160                                *signature_map[j].sdt_ptr = vhdr;
    152161                                LOG("%p: ACPI %s", *signature_map[j].sdt_ptr,
    153162                                    signature_map[j].description);
     
    187196        LOG("%p: ACPI Root System Description Pointer", acpi_rsdp);
    188197       
    189         acpi_rsdt = (struct acpi_rsdt *) ((uintptr_t) acpi_rsdp->rsdt_address);
     198        uintptr_t acpi_rsdt_p = (uintptr_t) acpi_rsdp->rsdt_address;
     199        uintptr_t acpi_xsdt_p = 0;
     200
    190201        if (acpi_rsdp->revision)
    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);
     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);
    198211       
    199212        if ((acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) {
  • kernel/generic/include/mm/km.h

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

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

    rca3d77a r7c506ced  
    145145}
    146146
     147uintptr_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}
    147155
    148156/** Unmap kernen non-identity page.
  • kernel/generic/src/mm/page.c

    rca3d77a r7c506ced  
    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  */
    96 void 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 
    11086/** Insert mapping of page to frame.
    11187 *
  • kernel/test/mm/mapping1.c

    rca3d77a r7c506ced  
    3131#include <mm/page.h>
    3232#include <mm/frame.h>
    33 #include <mm/as.h>
    3433#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 PAGE0  0x10000000
    40 #define PAGE1  (PAGE0 + PAGE_SIZE)
    41 
    42 #define VALUE0  UINT32_C(0x01234567)
    43 #define VALUE1  UINT32_C(0x89abcdef)
     39#define TEST_MAGIC  UINT32_C(0x01234567)
    4440
    4541const char *test_mapping1(void)
    4642{
    47         uintptr_t frame0, frame1;
    48         uint32_t v0, v1;
     43        uintptr_t page0, page1;
     44        uintptr_t frame;
     45        uint32_t v;
     46        int i;
    4947       
    50         frame0 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
    51         frame1 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
     48        frame = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_NONE);
     49
     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);
    5258       
    53         TPRINTF("Writing %#" PRIx32 " to physical address %p.\n",
    54             (uint32_t) VALUE0, (void *) KA2PA(frame0));
    55         *((uint32_t *) frame0) = VALUE0;
     59        for (i = 0; i < 2; i++) {
     60                TPRINTF("Writing magic using the first virtual address.\n");
     61
     62                *((uint32_t *) page0) = TEST_MAGIC;
     63
     64                TPRINTF("Reading magic using the second virtual address.\n");
     65
     66                v = *((uint32_t *) page1);
    5667       
    57         TPRINTF("Writing %#" PRIx32 " to physical address %p.\n",
    58             (uint32_t) VALUE1, (void *) KA2PA(frame1));
    59         *((uint32_t *) frame1) = VALUE1;
     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");
    6072       
    61         page_table_lock(AS, true);
     73                *((uint32_t *) page1) = 0;
    6274
    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);
     75                TPRINTF("Reading zero using the first virtual address.\n");
    6676       
    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);
     77                v = *((uint32_t *) page0);
     78       
     79                if (v != 0)
     80                        return "Criss-cross read does not match the value written.";
     81        }
    7082
    71         page_table_unlock(AS, true);
    72        
    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);
    79        
    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";
    84        
    85         TPRINTF("Writing %#" PRIx32 " to virtual address %p.\n",
    86             (uint32_t) 0, (void *) PAGE0);
    87         *((uint32_t *) PAGE0) = 0;
    88        
    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";
     83        // FIXME: do not leak frame, page0 and page1
    10584       
    10685        return NULL;
  • uspace/lib/drv/Makefile

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

    rca3d77a r7c506ced  
    7070FIBRIL_MUTEX_INITIALIZE(functions_mutex);
    7171
    72 /** Interrupts */
    73 static interrupt_context_list_t interrupt_contexts;
    74 
    75 static irq_cmd_t default_cmds[] = {
    76         {
    77                 .cmd = CMD_ACCEPT
    78         }
    79 };
    80 
    81 static irq_code_t default_pseudocode = {
    82         sizeof(default_cmds) / sizeof(irq_cmd_t),
    83         default_cmds
    84 };
    85 
    8672static ddf_dev_t *create_device(void);
    8773static void delete_device(ddf_dev_t *);
     
    9278static remote_handler_t *function_get_default_handler(ddf_fun_t *);
    9379static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t);
    94 
    95 static 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 
    105 interrupt_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 
    116 void delete_interrupt_context(interrupt_context_t *ctx)
    117 {
    118         if (ctx != NULL)
    119                 free(ctx);
    120 }
    121 
    122 void 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 
    129 void
    130 add_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 
    138 void 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 
    146 interrupt_context_t *
    147 find_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 
    165 interrupt_context_t *
    166 find_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 
    185 int
    186 register_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 
    209 int 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 }
    22280
    22381static void add_to_functions_list(ddf_fun_t *fun)
     
    992850        driver = drv;
    993851       
    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);
     852        /* Initialize interrupt module */
     853        interrupt_init();
    999854       
    1000855        /*
  • uspace/lib/drv/include/ddf/interrupt.h

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