aboutsummaryrefslogtreecommitdiff
path: root/src/sys/core.h
blob: 9e25f9d4217a7cf3f3df5561e41c3148603023c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#ifndef SYS_CORE_H
#define SYS_CORE_H

#ifndef SYS_CORE_C
extern char* os_info_v;
#endif

extern unsigned long cntfrq;

static inline unsigned long load32(unsigned long addr)
{
	return *(volatile unsigned long*)addr;
}

static inline void store32(unsigned long value, unsigned long addr)
{
	*(volatile unsigned long*)addr = value;
}

static inline void delay(unsigned long cycles)
{
	asm volatile("__delay_%=: subs %[cycles], %[cycles], #1;bne __delay_%=\n"
			: "=r"(cycles): [cycles]"0"(cycles) : "cc");
}

static inline void preserveregs(void)
{
	asm volatile("push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11}");
}

static inline void restoreregs(void)
{
	asm volatile("pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11}");
}

static inline void* getsp(void)
{
	void* out;
	asm volatile ("mov %0, sp" : "=r"(out));
	return out;
}

static inline void setsp(void* in)
{
	asm volatile ("mov sp, %0" :: "r"(in));
}

static inline void* heap_end(void)
{
	unsigned long value;
	asm volatile ("ldr %0, =__bss_end": "=r"(value));
	return (void*)value;
}

enum
{
	// The offset for the MMIO area
#ifdef BSP23
	MMIO_BASE = 0x3F000000, // For Raspberry Pi 2 and 3
#else
	MMIO_BASE = 0xFE000000,
#endif

	// The offsets for reach register.
	GPIO_BASE = (MMIO_BASE + 0x200000),

	// Controls actuation of pull up/down to ALL GPIO pins.
	GPPUD = (GPIO_BASE + 0x94),

	// Controls actuation of pull up/down for specific GPIO pin.
	GPPUDCLK0 = (GPIO_BASE + 0x98),

	// The base address for UART.
	UART0_BASE = (GPIO_BASE + 0x1000), // for raspi4 0xFE201000, raspi2 & 3 0x3F201000, and 0x20201000 for raspi1

	// The offsets for reach register for the UART.
	UART0_DR     = (UART0_BASE + 0x00),
	UART0_RSRECR = (UART0_BASE + 0x04),
	UART0_FR     = (UART0_BASE + 0x18),
	UART0_ILPR   = (UART0_BASE + 0x20),
	UART0_IBRD   = (UART0_BASE + 0x24),
	UART0_FBRD   = (UART0_BASE + 0x28),
	UART0_LCRH   = (UART0_BASE + 0x2C),
	UART0_CR     = (UART0_BASE + 0x30),
	UART0_IFLS   = (UART0_BASE + 0x34),
	UART0_IMSC   = (UART0_BASE + 0x38),
	UART0_RIS    = (UART0_BASE + 0x3C),
	UART0_MIS    = (UART0_BASE + 0x40),
	UART0_ICR    = (UART0_BASE + 0x44),
	UART0_DMACR  = (UART0_BASE + 0x48),
	UART0_ITCR   = (UART0_BASE + 0x80),
	UART0_ITIP   = (UART0_BASE + 0x84),
	UART0_ITOP   = (UART0_BASE + 0x88),
	UART0_TDR    = (UART0_BASE + 0x8C),

	// IRQ REGISTERS
	IRQ_BASE          = (MMIO_BASE + 0xB000),
	IRQ_BASIC_PENDING = (IRQ_BASE + 0x200),
	IRQ_PENDING1      = (IRQ_BASE + 0x204),
	IRQ_PENDING2      = (IRQ_BASE + 0x208),
	FIQ_CONTROL       = (IRQ_BASE + 0x20C),
	IRQ_ENABLE1       = (IRQ_BASE + 0x210),
	IRQ_ENABLE2       = (IRQ_BASE + 0x214),
	IRQ_BASIC_ENABLE  = (IRQ_BASE + 0x218),
	IRQ_DISABLE1      = (IRQ_BASE + 0x21C),
	IRQ_DISABLE2      = (IRQ_BASE + 0x220),
	IRQ_BASIC_DISABLE = (IRQ_BASE + 0x224),

	// Peripherals Interrupts
	UART_IRQ   = 57,
	GPIO_IRQ_0 = 49,
	GPIO_IRQ_1 = 50,
	GPIO_IRQ_2 = 51,
	GPIO_IRQ_3 = 52,

	FIQ_ENABLE_FLAG = 1<<7,

	// ARM Peripheral Interrupts
	TIMER_ARM_IRQ     = 0,
	MAILBOX_ARM_IRQ   = 1,
	DOORBELL0_ARM_IRQ = 2,
	DOORBELL1_ARM_IRQ = 3,
	GPU0HALT_ARM_IRQ  = 4,
	GPU1HALT_ARM_IRQ  = 5,

	// The offsets for Mailbox registers
	MBOX_BASE    = 0xB880,
	MBOX_READ    = (MBOX_BASE + 0x00),
	MBOX_STATUS  = (MBOX_BASE + 0x18),
	MBOX_WRITE   = (MBOX_BASE + 0x20),

	GPU_INTERRUPTS_ROUTING = 0x4000000C,

	CORE0_TIMER_IRQCNTL = 0x40000040,
	CORE0_IRQ_SOURCE    = 0x40000060,

	/* Power Management, Reset controller and Watchdog registers */
	//BCM2835_PERI_BASE        = 0x3F000000,
	BCM2835_PERI_BASE        = 0x20000000,
	PM_BASE                  = (BCM2835_PERI_BASE + 0x100000), 
	PM_RSTC                  = (PM_BASE+0x1c),
	PM_WDOG                  = (PM_BASE+0x24),
	PM_WDOG_RESET            = 0x00000000,
	PM_PASSWORD              = 0x5a000000,
	PM_WDOG_TIME_SET         = 0x000fffff,
	PM_RSTC_WRCFG_CLR        = 0xffffffcf,
	PM_RSTC_WRCFG_SET        = 0x00000030,
	PM_RSTC_WRCFG_FULL_RESET = 0x00000020,
	PM_RSTC_RESET            = 0x00000102,
};

void sysinit(void);

#endif