KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
arch.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 arch/dreamcast/include/arch.h
4 Copyright (C) 2001 Megan Potter
5 Copyright (C) 2013, 2020 Lawrence Sebald
6
7*/
8
9/** \file arch/arch.h
10 \brief Dreamcast architecture specific options.
11 \ingroup arch
12
13 This file has various architecture specific options defined in it. Also, any
14 functions that start with arch_ are in here.
15
16 \author Megan Potter
17*/
18
19#ifndef __ARCH_ARCH_H
20#define __ARCH_ARCH_H
21
22#include <kos/cdefs.h>
23__BEGIN_DECLS
24
25#include <stdbool.h>
26
27#include <arch/types.h>
28
29/** \defgroup arch Architecture
30 \brief Dreamcast Architecture-Specific Options and high-level API
31 \ingroup system
32 @{
33*/
34
35/** \brief Top of memory available, depending on memory size. */
36#ifdef __KOS_GCC_32MB__
38#else
39#pragma message "Outdated toolchain: not patched for 32MB support, limiting "\
40 "KOS to 16MB-only behavior to retain maximum compatibility. Please "\
41 "update your toolchain."
42#define _arch_mem_top ((uint32) 0x8d000000)
43#endif
44
45/** \brief Start and End address for .text portion of program. */
46extern char _executable_start;
47extern char _etext;
48
49#define PAGESIZE 4096 /**< \brief Page size (for MMU) */
50#define PAGESIZE_BITS 12 /**< \brief Bits for page size */
51#define PAGEMASK (PAGESIZE - 1) /**< \brief Mask for page offset */
52
53/** \brief Page count "variable".
54
55 The number of pages is static, so we can optimize this quite a bit. */
56#define page_count ((_arch_mem_top - page_phys_base) / PAGESIZE)
57
58/** \brief Base address of available physical pages. */
59#define page_phys_base 0x8c010000
60
61#ifndef THD_SCHED_HZ
62/** \brief Scheduler interrupt frequency
63
64 Timer interrupt frequency for the KOS thread scheduler.
65
66 \note
67 This value is what KOS uses initially upon startup, but it can be
68 reconfigured at run-time.
69
70 \sa thd_get_hz(), thd_set_hz()
71*/
72#define THD_SCHED_HZ 100
73#endif
74
75/** Legacy symbol for scheduler frequency.
76 * \deprecated
77 * \sa THD_SCHED_HZ
78 */
79static const
80unsigned HZ __depr("Please use the new THD_SCHED_HZ macro.") = THD_SCHED_HZ;
81
82#ifndef THD_STACK_SIZE
83/** \brief Default thread stack size. */
84#define THD_STACK_SIZE 32768
85#endif
86
87#ifndef THD_KERNEL_STACK_SIZE
88/** \brief Main/kernel thread's stack size. */
89#define THD_KERNEL_STACK_SIZE (64 * 1024)
90#endif
91
92/** \brief Default video mode. */
93#define DEFAULT_VID_MODE DM_640x480
94
95/** \brief Default pixel mode for video. */
96#define DEFAULT_PIXEL_MODE PM_RGB565
97
98/** \brief Default serial bitrate. */
99#define DEFAULT_SERIAL_BAUD 115200
100
101/** \brief Default serial FIFO behavior. */
102#define DEFAULT_SERIAL_FIFO 1
103
104/** \brief Global symbol prefix in ELF files. */
105#define ELF_SYM_PREFIX "_"
106
107/** \brief Length of global symbol prefix in ELF files. */
108#define ELF_SYM_PREFIX_LEN 1
109
110/** \brief Panic function.
111
112 This function will cause a kernel panic, printing the specified message.
113
114 \param str The error message to print.
115 \note This function will never return!
116*/
117void arch_panic(const char *str) __noreturn;
118
119/** \brief Kernel C-level entry point.
120 \note This function will never return!
121*/
123
124/** @} */
125
126/** \defgroup arch_retpaths Exit Paths
127 \brief Potential exit paths from the kernel on
128 arch_exit()
129 \ingroup arch
130 @{
131*/
132#define ARCH_EXIT_RETURN 1 /**< \brief Return to loader */
133#define ARCH_EXIT_MENU 2 /**< \brief Return to system menu */
134#define ARCH_EXIT_REBOOT 3 /**< \brief Reboot the machine */
135/** @} */
136
137/** \brief Set the exit path.
138 \ingroup arch
139
140 The default, if you don't call this, is ARCH_EXIT_RETURN.
141
142 \param path What arch_exit() should do.
143 \see arch_retpaths
144*/
145void arch_set_exit_path(int path);
146
147/** \brief Generic kernel "exit" point.
148 \ingroup arch
149 \note This function will never return!
150*/
152
153/** \brief Kernel "return" point.
154 \ingroup arch
155 \note This function will never return!
156*/
157void arch_return(int ret_code) __noreturn;
158
159/** \brief Kernel "abort" point.
160 \ingroup arch
161 \note This function will never return!
162*/
164
165/** \brief Kernel "reboot" call.
166 \ingroup arch
167 \note This function will never return!
168*/
170
171/** \brief Kernel "exit to menu" call.
172 \ingroup arch
173 \note This function will never return!
174*/
176
177/** \defgroup hw_memsizes Memory Capacity
178 \brief Console memory sizes
179 \ingroup arch
180
181 These are the various memory sizes, in bytes, that can be returned by the
182 HW_MEMSIZE macro.
183
184 @{
185*/
186#define HW_MEM_16 16777216 /**< \brief 16M retail Dreamcast */
187#define HW_MEM_32 33554432 /**< \brief 32M NAOMI/modded Dreamcast */
188/** @} */
189
190/** \brief Determine how much memory is installed in current machine.
191 \ingroup arch
192
193 \return The total size of system memory in bytes.
194*/
195#define HW_MEMSIZE (_arch_mem_top - 0x8c000000)
196
197/** \brief Use this macro to easily determine if system has 32MB of RAM.
198 \ingroup arch
199
200 \return Non-zero if console has 32MB of RAM, zero otherwise
201*/
202#define DBL_MEM (_arch_mem_top - 0x8d000000)
203
204/* These are in mm.c */
205/** \brief Initialize the memory management system.
206 \ingroup arch
207
208 \retval 0 On success (no error conditions defined).
209*/
210int mm_init(void);
211
212/** \brief Request more core memory from the system.
213 \ingroup arch
214
215 \param increment The number of bytes requested.
216 \return A pointer to the memory.
217 \note This function will panic if no memory is available.
218*/
219void * mm_sbrk(unsigned long increment);
220
221/* Bring in the init flags for compatibility with old code that expects them
222 here. */
223#include <kos/init.h>
224
225/* Dreamcast-specific arch init things */
226/** \brief Jump back to the bootloader.
227 \ingroup arch
228
229 You generally shouldn't use this function, but rather use arch_exit() or
230 exit() instead.
231
232 \note This function will never return!
233*/
234void arch_real_exit(int ret_code) __noreturn;
235
236/** \brief Initialize bare-bones hardware systems.
237 \ingroup arch
238
239 This will be done automatically for you on start by the default arch_main(),
240 so you shouldn't have to deal with this yourself.
241
242 \retval 0 On success (no error conditions defined).
243*/
245
246/** \brief Initialize some peripheral systems.
247 \ingroup arch
248
249 This will be done automatically for you on start by the default arch_main(),
250 so you shouldn't have to deal with this yourself.
251
252 \retval 0 On success (no error conditions defined).
253*/
255
256/** \brief Shut down hardware that was initted.
257 \ingroup arch
258
259 This function will shut down anything initted with hardware_sys_init() and
260 hardware_periph_init(). This will be done for you automatically by the
261 various exit points, so you shouldn't have to do this yourself.
262*/
264
265/** \defgroup hw_consoles Console Types
266 \brief Byte values returned by hardware_sys_mode()
267 \ingroup arch
268
269 These are the various console types that can be returned by the
270 hardware_sys_mode() function.
271
272 @{
273*/
274#define HW_TYPE_RETAIL 0x0 /**< \brief A retail Dreamcast. */
275#define HW_TYPE_SET5 0x9 /**< \brief A Set5.xx devkit. */
276/** @} */
277
278/** \defgroup hw_regions Region Codes
279 \brief Values returned by hardware_sys_mode();
280 \ingroup arch
281
282 These are the various region codes that can be returned by the
283 hardware_sys_mode() function.
284
285 \note
286 A retail Dreamcast will always return 0 for the region code.
287 You must read the region of a retail device from the flashrom.
288
289 \see fr_region
290 \see flashrom_get_region()
291
292 @{
293*/
294#define HW_REGION_UNKNOWN 0x0 /**< \brief Unknown region. */
295#define HW_REGION_ASIA 0x1 /**< \brief Japan/Asia (NTSC) */
296#define HW_REGION_US 0x4 /**< \brief North America */
297#define HW_REGION_EUROPE 0xC /**< \brief Europe (PAL) */
298/** @} */
299
300/** \brief Retrieve the system mode of the console in use.
301 \ingroup arch
302
303 This function retrieves the system mode register of the console that is in
304 use. This register details the actual system type in use (and in some system
305 types the region of the device).
306
307 \param region On return, the region code (one of the
308 \ref hw_regions) of the device if the console type
309 allows reading it through the system mode register
310 -- otherwise, you must retrieve the region from the
311 flashrom.
312 \return The console type (one of the \ref hw_consoles).
313*/
314int hardware_sys_mode(int *region);
315
316/* These three aught to be in their own header file at some point, but for now,
317 they'll stay here. */
318
319/** \brief Retrieve the banner printed at program initialization.
320 \ingroup attribution
321
322 This function retrieves the banner string that is printed at initialization
323 time by the kernel. This contains the version of KOS in use and basic
324 information about the environment in which it was compiled.
325
326 \return A pointer to the banner string.
327*/
328const char *kos_get_banner(void);
329
330/** \brief Retrieve the license information for the compiled copy of KOS.
331 \ingroup attribution
332
333 This function retrieves a string containing the license terms that the
334 version of KOS in use is distributed under. This can be used to easily add
335 information to your program to be displayed at runtime.
336
337 \return A pointer to the license terms.
338*/
339const char *kos_get_license(void);
340
341/** \brief Retrieve a list of authors and the dates of their contributions.
342 \ingroup attribution
343
344 This function retrieves the copyright information for the version of KOS in
345 use. This function can be used to add such information to the credits of
346 programs using KOS to give the appropriate credit to those that have worked
347 on KOS.
348
349 \remark
350 Remember, you do need to give credit where credit is due, and this is an
351 easy way to do so. ;-)
352
353 \return A pointer to the authors' copyright information.
354*/
355const char *kos_get_authors(void);
356
357/** \brief Dreamcast specific sleep mode function.
358 \ingroup arch
359*/
360static inline void arch_sleep(void) {
361 __asm__ __volatile__("sleep\n");
362}
363
364/** \brief DC specific "function" to get the return address from the current
365 function.
366 \ingroup arch
367
368 \return The return address of the current function.
369*/
370static inline uintptr_t arch_get_ret_addr(void) {
371 uintptr_t pr;
372
373 __asm__ __volatile__("sts pr,%0\n" : "=r"(pr));
374
375 return pr;
376}
377
378/* Please note that all of the following frame pointer macros are ONLY
379 valid if you have compiled your code WITHOUT -fomit-frame-pointer. These
380 are mainly useful for getting a stack trace from an error. */
381
382/** \brief DC specific "function" to get the frame pointer from the current
383 function.
384 \ingroup arch
385
386 \return The frame pointer from the current function.
387 \note This only works if you don't disable frame pointers.
388*/
389static inline uintptr_t arch_get_fptr(void) {
390 register uintptr_t fp __asm__("r14");
391
392 return fp;
393}
394
395/** \brief Pass in a frame pointer value to get the return address for the
396 given frame.
397 \ingroup arch
398
399 \param fptr The frame pointer to look at.
400 \return The return address of the pointer.
401*/
402static inline uintptr_t arch_fptr_ret_addr(uintptr_t fptr) {
403 return *(uintptr_t *)fptr;
404}
405
406/** \brief Pass in a frame pointer value to get the previous frame pointer for
407 the given frame.
408 \ingroup arch
409
410 \param fptr The frame pointer to look at.
411 \return The previous frame pointer.
412*/
413static inline uintptr_t arch_fptr_next(uintptr_t fptr) {
414 return arch_fptr_ret_addr(fptr + 4);
415}
416
417/** \brief Returns true if the passed address is likely to be valid. Doesn't
418 have to be exact, just a sort of general idea.
419 \ingroup arch
420
421 \return Whether the address is valid or not for normal
422 memory access.
423*/
424static inline bool arch_valid_address(uintptr_t ptr) {
425 return ptr >= 0x8c010000 && ptr < _arch_mem_top;
426}
427
428/** \brief Returns true if the passed address is in the text section of your
429 program.
430 \ingroup arch
431
432 \return Whether the address is valid or not for text
433 memory access.
434*/
435static inline bool arch_valid_text_address(uintptr_t ptr) {
436 return ptr >= (uintptr_t)&_executable_start && ptr < (uintptr_t)&_etext;
437}
438
439__END_DECLS
440
441#endif /* __ARCH_ARCH_H */
Definitions for builtin attributes and compiler directives.
void arch_return(int ret_code) __noreturn
Kernel "return" point.
void hardware_shutdown(void)
Shut down hardware that was initted.
void arch_reboot(void) __noreturn
Kernel "reboot" call.
void arch_real_exit(int ret_code) __noreturn
Jump back to the bootloader.
static bool arch_valid_text_address(uintptr_t ptr)
Returns true if the passed address is in the text section of your program.
Definition arch.h:435
char _executable_start
Start and End address for .text portion of program.
static void arch_sleep(void)
Dreamcast specific sleep mode function.
Definition arch.h:360
int mm_init(void)
Initialize the memory management system.
static uintptr_t arch_get_fptr(void)
DC specific "function" to get the frame pointer from the current function.
Definition arch.h:389
void arch_main(void) __noreturn
Kernel C-level entry point.
int hardware_sys_init(void)
Initialize bare-bones hardware systems.
void * mm_sbrk(unsigned long increment)
Request more core memory from the system.
#define _arch_mem_top
Top of memory available, depending on memory size.
Definition arch.h:42
int hardware_periph_init(void)
Initialize some peripheral systems.
void arch_set_exit_path(int path)
Set the exit path.
static uintptr_t arch_fptr_ret_addr(uintptr_t fptr)
Pass in a frame pointer value to get the return address for the given frame.
Definition arch.h:402
void arch_exit(void) __noreturn
Generic kernel "exit" point.
void arch_abort(void) __noreturn
Kernel "abort" point.
void arch_menu(void) __noreturn
Kernel "exit to menu" call.
static uintptr_t arch_get_ret_addr(void)
DC specific "function" to get the return address from the current function.
Definition arch.h:370
void arch_panic(const char *str) __noreturn
Panic function.
static uintptr_t arch_fptr_next(uintptr_t fptr)
Pass in a frame pointer value to get the previous frame pointer for the given frame.
Definition arch.h:413
char _etext
#define THD_SCHED_HZ
Scheduler interrupt frequency.
Definition arch.h:72
static bool arch_valid_address(uintptr_t ptr)
Returns true if the passed address is likely to be valid.
Definition arch.h:424
int hardware_sys_mode(int *region)
Retrieve the system mode of the console in use.
const char * kos_get_license(void)
Retrieve the license information for the compiled copy of KOS.
const char * kos_get_banner(void)
Retrieve the banner printed at program initialization.
const char * kos_get_authors(void)
Retrieve a list of authors and the dates of their contributions.
#define __depr(m)
Mark something as deprecated, with an informative message.
Definition cdefs.h:119
#define __noreturn
Identify a function that will never return.
Definition cdefs.h:45
unsigned long uint32
32-bit unsigned integer
Definition types.h:33
Initialization-related flags and macros.
Common integer types.