Changes in / [7c506ced:ca3d77a] in mainline
- Files:
-
- 1 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/src/ras.c
r7c506ced rca3d77a 38 38 #include <mm/frame.h> 39 39 #include <mm/page.h> 40 #include <mm/km.h>41 40 #include <mm/tlb.h> 42 41 #include <mm/asid.h> … … 51 50 void ras_init(void) 52 51 { 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); 63 54 ras_page[RAS_START] = 0; 64 55 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); 65 66 } 66 67 -
kernel/genarch/src/acpi/acpi.c
r7c506ced rca3d77a 39 39 #include <genarch/acpi/madt.h> 40 40 #include <arch/bios/bios.h> 41 #include <mm/as.h> 41 42 #include <mm/page.h> 42 #include <mm/km.h>43 43 #include <print.h> 44 44 … … 96 96 } 97 97 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; 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); 114 105 } 115 106 … … 127 118 (struct acpi_sdt_header *) (sysarg_t) acpi_rsdt->entry[i]; 128 119 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)) 132 123 break; 133 124 134 *signature_map[j].sdt_ptr = vhdr;125 *signature_map[j].sdt_ptr = hdr; 135 126 LOG("%p: ACPI %s", *signature_map[j].sdt_ptr, 136 127 signature_map[j].description); … … 153 144 (struct acpi_sdt_header *) ((uintptr_t) acpi_xsdt->entry[i]); 154 145 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)) 158 149 break; 159 150 160 *signature_map[j].sdt_ptr = vhdr;151 *signature_map[j].sdt_ptr = hdr; 161 152 LOG("%p: ACPI %s", *signature_map[j].sdt_ptr, 162 153 signature_map[j].description); … … 196 187 LOG("%p: ACPI Root System Description Pointer", acpi_rsdp); 197 188 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); 201 190 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); 211 198 212 199 if ((acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) { -
kernel/generic/include/mm/km.h
r7c506ced rca3d77a 50 50 51 51 extern uintptr_t km_map(uintptr_t, size_t, unsigned int); 52 extern uintptr_t km_map_structure(uintptr_t, size_t, unsigned int);53 52 54 53 extern uintptr_t km_temporary_page_get(uintptr_t *, frame_flags_t); -
kernel/generic/include/mm/page.h
r7c506ced rca3d77a 64 64 extern pte_t *page_table_create(unsigned int); 65 65 extern void page_table_destroy(pte_t *); 66 extern void map_structure(uintptr_t, size_t); 66 67 67 68 extern int page_find_mapping(uintptr_t, void **); -
kernel/generic/src/mm/km.c
r7c506ced rca3d77a 145 145 } 146 146 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 }155 147 156 148 /** Unmap kernen non-identity page. -
kernel/generic/src/mm/page.c
r7c506ced rca3d77a 84 84 } 85 85 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 86 110 /** Insert mapping of page to frame. 87 111 * -
kernel/test/mm/mapping1.c
r7c506ced rca3d77a 31 31 #include <mm/page.h> 32 32 #include <mm/frame.h> 33 #include <mm/as.h> 33 34 #include <arch/mm/page.h> 34 #include <mm/km.h>35 35 #include <typedefs.h> 36 36 #include <debug.h> 37 37 #include <arch.h> 38 38 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) 40 44 41 45 const char *test_mapping1(void) 42 46 { 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; 47 49 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); 49 62 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); 58 66 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); 61 70 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); 67 72 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); 72 79 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"; 76 84 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; 78 88 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"; 84 105 85 106 return NULL; -
uspace/lib/drv/Makefile
r7c506ced rca3d77a 35 35 generic/driver.c \ 36 36 generic/dev_iface.c \ 37 generic/interrupt.c \38 37 generic/log.c \ 39 38 generic/logbuf.c \ -
uspace/lib/drv/generic/driver.c
r7c506ced rca3d77a 70 70 FIBRIL_MUTEX_INITIALIZE(functions_mutex); 71 71 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 72 86 static ddf_dev_t *create_device(void); 73 87 static void delete_device(ddf_dev_t *); … … 78 92 static remote_handler_t *function_get_default_handler(ddf_fun_t *); 79 93 static 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 } 80 222 81 223 static void add_to_functions_list(ddf_fun_t *fun) … … 850 992 driver = drv; 851 993 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); 854 999 855 1000 /* -
uspace/lib/drv/include/ddf/interrupt.h
r7c506ced rca3d77a 64 64 } interrupt_context_list_t; 65 65 66 extern void interrupt_init(void); 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 67 78 extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *, 68 79 irq_code_t *);
Note:
See TracChangeset
for help on using the changeset viewer.