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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
/* -------------------------------------------
Copyright (C) 2024, Amlal El Mahrouss, licensed under Apache 2.0.
------------------------------------------- */
#pragma once
///
/// @file boot.h
/// @brief NeBoot types, data structures, and standard library.
///
#ifdef __unix__
#undef __unix__
#define __unix__ 7
#endif // !__unix__
#define __mpboot__ __unix__
typedef __UINTPTR_TYPE__ uintptr_t;
typedef __UINT32_TYPE__ phys_addr_t;
typedef unsigned long ulong_t;
typedef unsigned long long int uint64_t;
typedef unsigned uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef __INTPTR_TYPE__ intptr_t;
typedef __INT64_TYPE__ int64_t;
typedef __INT32_TYPE__ int32_t;
typedef __INT16_TYPE__ int16_t;
typedef char int8_t;
typedef void* voidptr_t;
typedef char* addr_t;
typedef const char* caddr_t;
typedef __UINTPTR_TYPE__ ptrtype_t;
typedef ptrtype_t size_t;
#define array_size(arr) (sizeof(arr[0]) / sizeof(arr))
#ifndef nil
#define nil ((voidptr_t) 0)
#endif // ifndef nil
#ifndef null
#define null ((voidptr_t) 0)
#endif // ifndef null
/// C23 introduces `nullptr`: https://en.cppreference.com/w/c/language/nullptr.html
#if __STDC_VERSION__ < 202311L
#define nullptr ((struct nullptr_*)null)
struct nullptr_ { char __nullv; };
typedef struct nullptr_* nullptr_t;
#endif
#define auto_type void*
#define __no 0
#define __yes 1
#define boolean char
#define no __no
#define yes __yes
#ifndef __cplusplus
#define bool boolean
#define false no
#define true yes
#endif //!_cplusplus
#define NB_RESTART 0
#define NB_SHUTDOWN 1
#ifndef asm
#define asm __asm
#endif // ifndef asm
#define __COPYRIGHT(s) /* unused */
#ifdef __COMPILE_RISCV__
#define NB_BOOT_ADDR (0x80020000)
#define NB_BOOT_ADDR_STR "0x80020000"
#define NB_FRAMEBUFFER_ADDR 0x40000000L
#define NB_UART_BASE 0x10000000
#define NB_FLASH_BASE_ADDR 0x08000000
#define cb_sync_synchronize() __sync_synchronize()
#elif defined(__COMPILE_POWERPC__)
#define NB_UART_BASE 0x10000000
#define NB_BOOT_ADDR 0x1030000
#define NB_BOOT_ADDR_STR "0x1030000"
#define NB_FRAMEBUFFER_ADDR 0x40000000L
#define NB_FLASH_BASE_ADDR 0x08000000
#define cb_sync_synchronize() __sync_synchronize()
#elif defined(__COMPILE_ARM64__)
#define NB_UART_BASE 0x09000000
#define NB_BOOT_ADDR 0x1030000
#define NB_BOOT_ADDR_STR "0x1030000"
#define NB_FRAMEBUFFER_ADDR 0x40000000L
#define NB_FLASH_BASE_ADDR 0x08000000
static inline void __sync_synchronize(void) {
/// leave it as is.
}
#define cb_sync_synchronize() __sync_synchronize()
#endif // ifndef __COMPILE_POWERPC__
#define NB_BAUDRATE_TABLE \
{ 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 }
#define NB_STRING(s) #s
#define NB_BOOT_MAG_0 'C'
#define NB_BOOT_MAG_1 'B'
#define NB_BOOT_VER 0x101
#define NB_BOOT_CALL(struct, offset) \
volatile cb_proc_t proc_##offset = (volatile cb_proc_t)(struct->offset); \
proc_##offset();
/// @brief Binary64 representation (IEE 7554) in a C structure
typedef union {
struct {
char __sign;
int32_t __mantissa;
int16_t __exponent;
};
float __fv;
} __attribute__((packed)) binary64_t;
/// \brief UTF-32 character
typedef uint32_t utf_char_t;
/// \brief ASCII character
typedef char ascii_char_t;
/// @brief panic the entire system.
/// @param reason why text.
void cb_panic(const char* reason);
/// @brief update the power status of the machine.
void cb_update_power_status(boolean restart);
/// @brief puts a string in serial
/// @param text
/// @return
size_t cb_put_string(const ascii_char_t* _Nonnull text);
/// @brief gets a char from serial
/// @param
/// @return
utf_char_t cb_get_char(void);
/// @brief puts a char in serial
/// @param ch
void cb_put_char(utf_char_t ch);
/// @brief Hangs the firmware.
/// @param void no args.
void cb_restart_machine(void);
/// @brief Flushs the TLB.
/// @param void no args.
void cb_flush_tlb(void);
/// @brief Print current kernel name.
/// @param
void cb_print_name(void);
/// @brief String length getter
/// @param str the string.
/// @return
size_t strlen(_Nonnull caddr_t str);
/// @brief Compare two strings.
/// @param src source string
/// @param cmp string to compare.
/// @return
size_t strcmp(_Nonnull caddr_t src, _Nonnull caddr_t cmp);
typedef void (*cb_proc_t)();
/// \brief ASCII character.
typedef char ascii_char_t;
/// @brief Linear Executable Header
/// @author Amlal El Mahrouss (Amlal El Mahrouss)
struct __attribute__((aligned(4))) cb_boot_header {
const ascii_char_t h_mag[2]; // magic number
const ascii_char_t h_name[10]; // operating system name
const uint32_t h_revision; // firmware revision
const uint64_t h_start_address; // start address (master/slave(s) thread)
};
// EOF.
|