Changeset a996ae31 in mainline
- Timestamp:
- 2012-02-12T14:26:04Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d57122c
- Parents:
- ec12ab8
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/ddi/irq.h
rec12ab8 ra996ae31 35 35 #ifndef ABI_DDI_IRQ_H_ 36 36 #define ABI_DDI_IRQ_H_ 37 38 typedef struct { 39 uintptr_t base; 40 size_t size; 41 } irq_pio_range_t; 37 42 38 43 typedef enum { … … 97 102 98 103 typedef struct { 104 size_t rangecount; 105 irq_pio_range_t *ranges; 99 106 size_t cmdcount; 100 107 irq_cmd_t *cmds; -
kernel/generic/include/ipc/irq.h
rec12ab8 ra996ae31 36 36 #define KERN_IPC_IRQ_H_ 37 37 38 /** Maximum length of IPC IRQ program */ 38 /** Maximum number of IPC IRQ programmed I/O ranges. */ 39 #define IRQ_MAX_RANGE_COUNT 8 40 41 /** Maximum length of IPC IRQ program. */ 39 42 #define IRQ_MAX_PROG_SIZE 20 40 43 -
kernel/generic/src/ipc/irq.c
rec12ab8 ra996ae31 74 74 #include <arch.h> 75 75 #include <mm/slab.h> 76 #include <mm/page.h> 77 #include <mm/km.h> 76 78 #include <errno.h> 77 79 #include <ddi/irq.h> … … 81 83 #include <console/console.h> 82 84 #include <print.h> 85 #include <macros.h> 86 87 static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount) 88 { 89 size_t i; 90 91 for (i = 0; i < rangecount; i++) { 92 if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY) 93 km_unmap(ranges[i].base, ranges[i].size); 94 } 95 } 96 97 static int ranges_map_and_apply(irq_pio_range_t *ranges, size_t rangecount, 98 irq_cmd_t *cmds, size_t cmdcount) 99 { 100 uintptr_t *pbase; 101 size_t i, j; 102 103 /* Copy the physical base addresses aside. */ 104 pbase = malloc(rangecount * sizeof(uintptr_t), 0); 105 for (i = 0; i < rangecount; i++) 106 pbase[i] = ranges[i].base; 107 108 /* Map the PIO ranges into the kernel virtual address space. */ 109 for (i = 0; i < rangecount; i++) { 110 if ((void *) ranges[i].base < IO_SPACE_BOUNDARY) 111 continue; 112 ranges[i].base = km_map(pbase[i], ranges[i].size, 113 PAGE_READ | PAGE_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE); 114 if (!ranges[i].base) { 115 ranges_unmap(ranges, i); 116 free(pbase); 117 return ENOMEM; 118 } 119 } 120 121 /* Rewrite the pseudocode addresses from physical to kernel virtual. */ 122 for (i = 0; i < cmdcount; i++) { 123 uintptr_t addr; 124 125 /* Process only commands that use an address. */ 126 switch (cmds[i].cmd) { 127 case CMD_PIO_READ_8: 128 case CMD_PIO_READ_16: 129 case CMD_PIO_READ_32: 130 case CMD_PIO_WRITE_8: 131 case CMD_PIO_WRITE_16: 132 case CMD_PIO_WRITE_32: 133 case CMD_PIO_WRITE_A_8: 134 case CMD_PIO_WRITE_A_16: 135 case CMD_PIO_WRITE_A_32: 136 break; 137 default: 138 /* Move onto the next command. */ 139 continue; 140 } 141 142 addr = (uintptr_t) cmds[i].addr; 143 144 /* Process only memory mapped PIO addresses. */ 145 if ((void *) addr < IO_SPACE_BOUNDARY) 146 continue; 147 148 for (j = 0; j < rangecount; j++) { 149 150 /* Find the matching range. */ 151 if (!iswithin(pbase[j], ranges[j].size, addr, 1)) 152 continue; 153 154 /* Switch the command to a kernel virtual address. */ 155 addr -= pbase[j]; 156 addr += ranges[j].base; 157 158 cmds[i].addr = (void *) addr; 159 break; 160 } 161 } 162 163 free(pbase); 164 return EOK; 165 } 83 166 84 167 /** Free the top-half pseudocode. … … 90 173 { 91 174 if (code) { 175 ranges_unmap(code->ranges, code->rangecount); 176 free(code->ranges); 92 177 free(code->cmds); 93 178 free(code); … … 104 189 static irq_code_t *code_from_uspace(irq_code_t *ucode) 105 190 { 191 irq_pio_range_t *ranges = NULL; 192 irq_cmd_t *cmds = NULL; 193 106 194 irq_code_t *code = malloc(sizeof(*code), 0); 107 195 int rc = copy_from_uspace(code, ucode, sizeof(*code)); 108 if (rc != 0) { 109 free(code); 110 return NULL; 111 } 112 113 if (code->cmdcount > IRQ_MAX_PROG_SIZE) { 114 free(code); 115 return NULL; 116 } 117 118 irq_cmd_t *ucmds = code->cmds; 119 code->cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0); 120 rc = copy_from_uspace(code->cmds, ucmds, 196 if (rc != EOK) 197 goto error; 198 199 if ((code->rangecount > IRQ_MAX_RANGE_COUNT) || 200 (code->cmdcount > IRQ_MAX_PROG_SIZE)) 201 goto error; 202 203 ranges = malloc(sizeof(code->ranges[0]) * code->rangecount, 0); 204 rc = copy_from_uspace(ranges, code->ranges, 205 sizeof(code->ranges[0]) * code->rangecount); 206 if (rc != EOK) 207 goto error; 208 209 cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0); 210 rc = copy_from_uspace(cmds, code->cmds, 121 211 sizeof(code->cmds[0]) * code->cmdcount); 122 if (rc != 0) { 123 free(code->cmds); 124 free(code); 125 return NULL; 126 } 127 212 if (rc != EOK) 213 goto error; 214 215 rc = ranges_map_and_apply(ranges, code->rangecount, cmds, 216 code->cmdcount); 217 if (rc != EOK) 218 goto error; 219 220 code->ranges = ranges; 221 code->cmds = cmds; 222 128 223 return code; 224 225 error: 226 if (cmds) 227 free(cmds); 228 if (ranges) 229 free(ranges); 230 free(code); 231 return NULL; 129 232 } 130 233 … … 366 469 for (size_t i = 0; i < code->cmdcount; i++) { 367 470 uint32_t dstval; 368 void *va;369 uint8_t val8;370 uint16_t val16;371 uint32_t val32;372 471 373 472 uintptr_t srcarg = code->cmds[i].srcarg; -
kernel/generic/src/syscall/copy.c
rec12ab8 ra996ae31 56 56 * @param size Size of the data to be copied. 57 57 * 58 * @return 0on success or error code from @ref errno.h.58 * @return EOK on success or error code from @ref errno.h. 59 59 */ 60 60 int copy_from_uspace(void *dst, const void *uspace_src, size_t size) … … 94 94 95 95 interrupts_restore(ipl); 96 return !rc ? EPERM : 0;96 return !rc ? EPERM : EOK; 97 97 } 98 98 -
uspace/lib/drv/generic/driver.c
rec12ab8 ra996ae31 80 80 81 81 static irq_code_t default_pseudocode = { 82 0, 83 NULL, 82 84 sizeof(default_cmds) / sizeof(irq_cmd_t), 83 85 default_cmds -
uspace/srv/hid/input/port/gxemul.c
rec12ab8 ra996ae31 69 69 70 70 static irq_code_t gxemul_kbd = { 71 0, // FIXME 72 NULL, // FIXME 71 73 sizeof(gxemul_cmds) / sizeof(irq_cmd_t), 72 74 gxemul_cmds -
uspace/srv/hid/input/port/msim.c
rec12ab8 ra996ae31 69 69 70 70 static irq_code_t msim_kbd = { 71 0, // FIXME 72 NULL, // FIXME 71 73 sizeof(msim_cmds) / sizeof(irq_cmd_t), 72 74 msim_cmds -
uspace/srv/hid/input/port/ns16550.c
rec12ab8 ra996ae31 98 98 99 99 irq_code_t ns16550_kbd = { 100 0, 101 NULL, 100 102 sizeof(ns16550_cmds) / sizeof(irq_cmd_t), 101 103 ns16550_cmds -
uspace/srv/hid/input/port/pl050.c
rec12ab8 ra996ae31 91 91 92 92 static irq_code_t pl050_kbd = { 93 0, // FIXME 94 NULL, // FIXME 93 95 sizeof(pl050_cmds) / sizeof(irq_cmd_t), 94 96 pl050_cmds -
uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
rec12ab8 ra996ae31 62 62 63 63 static irq_code_t ts_irq_code = { 64 0, 65 NULL, 64 66 sizeof(ts_irq_cmds) / sizeof(irq_cmd_t), 65 67 ts_irq_cmds -
uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
rec12ab8 ra996ae31 60 60 61 61 static irq_code_t uart_irq_code = { 62 0, 63 NULL, 62 64 sizeof(uart_irq_cmds) / sizeof(irq_cmd_t), 63 65 uart_irq_cmds
Note:
See TracChangeset
for help on using the changeset viewer.