embox

Форк
0
117 строк · 2.6 Кб
1
/**
2
 * @file
3
 * @brief Gaisler Research IRQMP Interrupt controller driver.
4
 *
5
 * @date 14.04.09
6
 * @author Anton Bondarev
7
 * @author Eldar Abusalimov
8
 */
9

10
#include <assert.h>
11
#include <errno.h>
12
#include <stdint.h>
13
#include <sys/mman.h>
14

15
#include <drivers/common/memory.h>
16
#include <mem/page.h>
17
#include <hal/reg.h>
18
#include <drivers/irqctrl.h>
19
#include <drivers/amba_pnp.h>
20

21
#include <embox/unit.h>
22

23
struct irqmp_regs {
24
	/* 0x00 */uint32_t level;
25
	/* 0x04 */uint32_t pending;
26
	/* 0x08 */uint32_t force;
27
	/* 0x0C */uint32_t clear;
28
	/* 0x10 */uint32_t mpstatus;
29
	/* 0x14 */uint32_t broadcast;
30
	/* 0x18 */uint32_t dummy[10];
31
	/* 0x40 */uint32_t mask;
32
};
33

34
static volatile struct irqmp_regs *dev_regs;
35

36
static int dev_regs_init(void);
37

38
void irqctrl_enable(unsigned int irq) {
39
	assert(dev_regs);
40
	REG_ORIN(&dev_regs->mask, 1 << irq);
41
}
42

43
void irqctrl_disable(unsigned int irq) {
44
	assert(dev_regs);
45
	REG_ANDIN(&dev_regs->mask, ~(1 << irq));
46
}
47

48
void irqctrl_clear(unsigned int irq) {
49
	assert(dev_regs);
50
	REG_ORIN(&dev_regs->clear, 1 << irq);
51
	REG_ANDIN(&dev_regs->force, ~(1 << irq));
52
}
53

54
void irqctrl_force(unsigned int irq) {
55
	assert(dev_regs);
56
	REG_ORIN(&dev_regs->force, 1 << irq);
57
}
58

59
static int irqmp_init(void) {
60
	int error;
61

62
	assert(NULL == dev_regs);
63
	if (0 != (error = dev_regs_init())) {
64
		return error;
65
	}
66
	assert(dev_regs);
67

68
	REG_STORE(&dev_regs->level, 0x0);
69
	REG_STORE(&dev_regs->mask, 0x0);
70
	REG_STORE(&dev_regs->pending, 0x0);
71
	REG_STORE(&dev_regs->force, 0x0);
72
	REG_STORE(&dev_regs->clear, ~0x0);
73

74
	return 0;
75
}
76

77
#ifdef DRIVER_AMBAPP
78

79
static int irqctrl_memory_map(uint32_t base, size_t len) {
80
	void *ptr;
81

82
	base = ((uint32_t) base) & ~(PAGE_SIZE() - 1);
83

84
	/* 0x100 - random value */
85
	ptr = mmap_device_memory((void *) base, len, PROT_READ | PROT_WRITE | PROT_NOCACHE,
86
			MAP_FIXED, base);
87
	if (ptr == MAP_FAILED) {
88
		return -1;
89
	}
90

91
	return 0;
92
}
93

94
static int dev_regs_init(void) {
95
	amba_dev_t amba_dev;
96
	if (-1 == capture_amba_dev(&amba_dev, AMBAPP_VENDOR_GAISLER,
97
			AMBAPP_DEVICE_GAISLER_IRQMP, false, false)) {
98
		return -ENODEV;
99
	}
100
	dev_regs = (volatile struct irqmp_regs *) amba_dev.bar[0].start;
101

102
	return irqctrl_memory_map((uint32_t) dev_regs, 0x100);
103
}
104
#elif OPTION_DEFINED(NUMBER,irqmp_base)
105
static int dev_regs_init(void) {
106
	dev_regs = (volatile struct irqmp_regs *) OPTION_GET(NUMBER,irqmp_base);
107
	return 0;
108
#if 0
109
	/* TODO We can't use memory_map in this stage */
110
	return irqctrl_memory_map((uint32_t) dev_regs, 0x100);
111
#endif
112
}
113
PERIPH_MEMORY_DEFINE(irqmp, OPTION_GET(NUMBER, irqmp_base), 0x100);
114
IRQCTRL_DEF(irqmp, irqmp_init);
115
#else
116
# error "Either DRIVER_AMBAPP or irqmp_base option must be defined"
117
#endif /* DRIVER_AMBAPP */
118

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.