-
Notifications
You must be signed in to change notification settings - Fork 0
/
kernel.d
107 lines (92 loc) · 2.54 KB
/
kernel.d
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
nothrow:
void mmio_write(uint reg, uint data)
{
*(cast (uint *) reg) = data;
}
uint mmio_read(uint reg)
{
return *(cast (uint *) reg);
}
// Loop <delay> times in a way that the compiler won't optimize away
extern (C)
void delay(int count);
// extern (C)
// void __aeabi_unwind_cpp_pr0 ()
// {
// }
enum
{
// The GPIO registers base address.
GPIO_BASE = 0x3F200000, // for raspi2 & 3, 0x20200000 for raspi1
GPPUD = (GPIO_BASE + 0x94),
GPPUDCLK0 = (GPIO_BASE + 0x98),
// The base address for UART.
UART0_BASE = 0x3F201000, // for raspi2 & 3, 0x20201000 for raspi1
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),
};
void uart_init()
{
mmio_write(UART0_CR, 0x00000000);
mmio_write(GPPUD, 0x00000000);
delay(150);
mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15));
delay(150);
mmio_write(GPPUDCLK0, 0x00000000);
mmio_write(UART0_ICR, 0x7FF);
mmio_write(UART0_IBRD, 1);
mmio_write(UART0_FBRD, 40);
mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));
mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10));
mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
}
void uart_putc(ubyte c)
{
while (mmio_read(UART0_FR) & (1 << 5))
{
// do nothing
}
mmio_write(UART0_DR, c);
}
ubyte uart_getc()
{
while (mmio_read(UART0_FR) & (1 << 4))
{
// do nothing
}
return cast(ubyte) mmio_read(UART0_DR);
}
void uart_puts(const char* str)
{
for (size_t i = 0; str[i] != '\0'; i++)
{
uart_putc(cast(ubyte) str[i]);
}
}
extern (C)
void kernel_main(uint r0, uint r1, uint atags)
{
uart_init();
uart_puts("Hello, Kernel World!\r\n");
while (true)
{
uart_putc(uart_getc());
uart_putc('\n');
}
}