Changeset b446b02 in mainline for uspace/drv/intctl/i8259/i8259.c
- Timestamp:
- 2017-10-17T17:47:11Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b1efe3e
- Parents:
- a416d070
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/intctl/i8259/i8259.c
ra416d070 rb446b02 40 40 #include <sysinfo.h> 41 41 #include <as.h> 42 #include <ddf/log.h> 42 43 #include <ddi.h> 43 44 #include <align.h> … … 47 48 #include <stdio.h> 48 49 50 #include "i8259.h" 51 49 52 #define NAME "i8259" 50 53 51 #define IO_RANGE0_START ((ioport8_t *) 0x0020U)52 54 #define IO_RANGE0_SIZE 2 53 54 #define IO_RANGE1_START ((ioport8_t *) 0x00a0U)55 55 #define IO_RANGE1_SIZE 2 56 57 static ioport8_t *io_range0;58 static ioport8_t *io_range1;59 56 60 57 #define PIC_PIC0PORT1 0 … … 66 63 #define PIC_MAX_IRQ 15 67 64 68 static int pic_enable_irq( sysarg_t irq)65 static int pic_enable_irq(i8259_t *i8259, sysarg_t irq) 69 66 { 70 67 if (irq > PIC_MAX_IRQ) … … 75 72 76 73 if (irqmask & 0xff) { 77 val = pio_read_8(i o_range0 + PIC_PIC0PORT2);78 pio_write_8(i o_range0 + PIC_PIC0PORT2,74 val = pio_read_8(i8259->regs0 + PIC_PIC0PORT2); 75 pio_write_8(i8259->regs0 + PIC_PIC0PORT2, 79 76 (uint8_t) (val & (~(irqmask & 0xff)))); 80 77 } 81 78 82 79 if (irqmask >> 8) { 83 val = pio_read_8(i o_range1 + PIC_PIC1PORT2);84 pio_write_8(i o_range1 + PIC_PIC1PORT2,80 val = pio_read_8(i8259->regs1 + PIC_PIC1PORT2); 81 pio_write_8(i8259->regs1 + PIC_PIC1PORT2, 85 82 (uint8_t) (val & (~(irqmask >> 8)))); 86 83 } … … 99 96 ipc_callid_t callid; 100 97 ipc_call_t call; 98 i8259_t *i8259 = NULL /* XXX */; 101 99 102 100 /* … … 104 102 */ 105 103 async_answer_0(iid, EOK); 104 105 i8259 = (i8259_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg)); 106 106 107 107 while (true) { … … 116 116 switch (IPC_GET_IMETHOD(call)) { 117 117 case IRC_ENABLE_INTERRUPT: 118 async_answer_0(callid, pic_enable_irq(IPC_GET_ARG1(call))); 118 async_answer_0(callid, pic_enable_irq(i8259, 119 IPC_GET_ARG1(call))); 119 120 break; 120 121 case IRC_DISABLE_INTERRUPT: … … 133 134 } 134 135 135 /** Initialize the i8259 driver. 136 * 137 */ 138 static bool i8259_init(void) 139 { 140 sysarg_t i8259; 141 category_id_t irc_cat; 142 service_id_t svc_id; 136 /** Add i8259 device. */ 137 int i8259_add(i8259_t *i8259, i8259_res_t *res) 138 { 139 sysarg_t have_i8259; 140 ioport8_t *regs0; 141 ioport8_t *regs1; 142 ddf_fun_t *fun_a = NULL; 143 143 int rc; 144 144 145 if ((sysinfo_get_value("i8259", & i8259) != EOK) || (!i8259)) {145 if ((sysinfo_get_value("i8259", &have_i8259) != EOK) || (!have_i8259)) { 146 146 printf("%s: No i8259 found\n", NAME); 147 return false;148 } 149 150 if ((pio_enable((void *) IO_RANGE0_START, IO_RANGE0_SIZE,151 (void **) & io_range0) != EOK) ||152 (pio_enable((void *) IO_RANGE1_START, IO_RANGE1_SIZE,153 (void **) & io_range1) != EOK)) {147 return ENOTSUP; 148 } 149 150 if ((pio_enable((void *) res->base0, IO_RANGE0_SIZE, 151 (void **) ®s0) != EOK) || 152 (pio_enable((void *) res->base1, IO_RANGE1_SIZE, 153 (void **) ®s1) != EOK)) { 154 154 printf("%s: i8259 not accessible\n", NAME); 155 return false; 156 } 157 158 async_set_fallback_port_handler(i8259_connection, NULL); 159 160 rc = loc_server_register(NAME); 155 return EIO; 156 } 157 158 i8259->regs0 = regs0; 159 i8259->regs1 = regs1; 160 161 fun_a = ddf_fun_create(i8259->dev, fun_exposed, "a"); 162 if (fun_a == NULL) { 163 ddf_msg(LVL_ERROR, "Failed creating function 'a'."); 164 rc = ENOMEM; 165 goto error; 166 } 167 168 ddf_fun_set_conn_handler(fun_a, i8259_connection); 169 170 rc = ddf_fun_bind(fun_a); 161 171 if (rc != EOK) { 162 printf("%s: Failed registering server. (%d)\n", NAME, rc); 163 return false; 164 } 165 166 rc = loc_service_register("irc/" NAME, &svc_id); 167 if (rc != EOK) { 168 printf("%s: Failed registering service. (%d)\n", NAME, rc); 169 return false; 170 } 171 172 rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING); 173 if (rc != EOK) { 174 printf("%s: Failed resolving category 'iplink' (%d).\n", NAME, 175 rc); 176 return false; 177 } 178 179 rc = loc_service_add_to_cat(svc_id, irc_cat); 180 if (rc != EOK) { 181 printf("%s: Failed adding service to category (%d).\n", NAME, 182 rc); 183 return false; 184 } 185 186 return true; 187 } 188 189 int main(int argc, char **argv) 190 { 191 printf("%s: HelenOS i8259 driver\n", NAME); 192 193 if (!i8259_init()) 194 return -1; 195 196 printf("%s: Accepting connections\n", NAME); 197 task_retval(0); 198 async_manager(); 199 200 /* Never reached */ 201 return 0; 172 ddf_msg(LVL_ERROR, "Failed binding function 'a'. (%d)", rc); 173 goto error; 174 } 175 176 rc = ddf_fun_add_to_category(fun_a, "irc"); 177 if (rc != EOK) 178 goto error; 179 180 return EOK; 181 error: 182 if (fun_a != NULL) 183 ddf_fun_destroy(fun_a); 184 return rc; 185 } 186 187 /** Remove i8259 device */ 188 int i8259_remove(i8259_t *i8259) 189 { 190 return ENOTSUP; 191 } 192 193 /** i8259 device gone */ 194 int i8259_gone(i8259_t *i8259) 195 { 196 return ENOTSUP; 202 197 } 203 198
Note:
See TracChangeset
for help on using the changeset viewer.