61 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			61 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <sys/time.h>
 | |
| 
 | |
| #include <cstdint>
 | |
| 
 | |
| #include "itoa.h"
 | |
| #include "lock.h"
 | |
| #include "timer.h"
 | |
| #include "uart.h"
 | |
| 
 | |
| #ifndef SBRK_STATS
 | |
| #define SBRK_STATS 0
 | |
| #endif
 | |
| 
 | |
| extern unsigned char _heap_begin, _heap_end;
 | |
| 
 | |
| namespace {
 | |
| [[maybe_unused]]
 | |
| void LogStats(unsigned char* heap) {
 | |
|     char number[] = "00000000\r\n";
 | |
|     UartWriteCrash("Program break now at 0x");
 | |
|     itoa(reinterpret_cast<int>(heap), number);
 | |
|     UartWriteCrash(number);
 | |
| }
 | |
| }  // namespace
 | |
| 
 | |
| extern "C" void* _sbrk(int increment) {
 | |
|     static unsigned char* heap = &_heap_begin;
 | |
|     unsigned char* prev_heap = heap;
 | |
|     if (heap + increment >= &_heap_end) {
 | |
|         UartWriteCrash("Heap overflow!\r\n");
 | |
|         return reinterpret_cast<void*>(-1);
 | |
|     }
 | |
|     heap += increment;
 | |
| #if SBRK_STATS
 | |
|     LogStats(heap);
 | |
| #endif
 | |
|     return prev_heap;
 | |
| }
 | |
| 
 | |
| extern "C" int _gettimeofday(struct timeval* tv, void* tzvp) {
 | |
|     uint32_t ticks = timer0->GetT1Ticks();
 | |
|     tv->tv_sec = ticks / 100000000;
 | |
|     tv->tv_usec = (ticks % 100000000) / 100;
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| extern "C" uint8_t __atomic_exchange_1(volatile void* ptr, uint8_t val,
 | |
|                                        int memorder) {
 | |
|     auto* dest = reinterpret_cast<volatile uint8_t*>(ptr);
 | |
|     bool ret;
 | |
| 
 | |
|     {
 | |
|         InterruptLock lock;
 | |
|         ret = *dest;
 | |
|         *dest = val;
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 |