source: trunk/kernel/kern/do_interrupt.c @ 9

Last change on this file since 9 was 5, checked in by alain, 8 years ago

Introduce the chdev_t structure in place of the device_t structure.

File size: 2.3 KB
Line 
1/*
2 * kern/do_interrupt.c - kernel unified interrupt entry-point
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <cpu.h>
24#include <task.h>
25#include <thread.h>
26#include <cpu-trace.h>
27#include <chdev.h>
28#include <system.h>
29#include <signal.h>
30
31#define irq_cpu_dmsg(c,...)                             \
32        do{                                             \
33                if(cpu_get_id() == (c))                 \
34                        isr_dmsg(INFO, __VA_ARGS__);    \
35        }while(0)
36
37void do_interrupt(struct thread_s *this, uint_t irq_num)
38{
39        register thread_state_t old_state;
40        struct irq_action_s *action;
41        struct cpu_s *cpu;
42        uint_t irq_state;
43        error_t ret;
44
45        cpu_trace_write(thread_current_cpu(this), do_interrupt);
46
47        cpu = thread_current_cpu(this);
48
49        cpu->irq_nr ++;
50        old_state = this->state;
51
52        if(old_state == S_USR)
53        {
54                this->state = S_KERNEL;
55                tm_usr_compute(this);
56        }
57
58        arch_cpu_get_irq_entry(cpu, irq_num, &action);
59        action->irq_handler(action);
60           
61        cpu_yield();
62
63        if(old_state != S_USR)//and not a kernel thread ?
64                return;
65
66        /* it is safe to migrate as we are going to user *
67         * space.                                        */
68        if(thread_migration_isActivated(this))
69        {
70                thread_clear_cap_migrate(this);
71                cpu_enable_all_irq(&irq_state);
72                ret = thread_migrate(this,-1);
73                cpu_restore_irq(irq_state);
74
75                /* this pointer has expired */
76                this = CURRENT_THREAD;
77                cpu_wbflush();
78
79                if(ret == 0)   
80                        thread_migration_deactivate(this);
81                else
82                {
83                        isr_dmsg(INFO, 
84                        "%s: cpu %d, migration failed for victim pid %d, tid %d, err %d\n", 
85                         __FUNCTION__, 
86                         cpu_get_id(),
87                         this->task->pid,
88                         this->info.order,
89                         ret);
90                }
91        }
92       
93        tm_sys_compute(this);
94        this->state = S_USR;
95        signal_notify(this);
96}
Note: See TracBrowser for help on using the repository browser.