···11#ifndef RANDOM_H
22#define RANDOM_H
3344+#include <stdint.h>
55+46void rand_init();
55-unsigned int rand(unsigned int min, unsigned int max);
77+uint32_t rand(const uint32_t min, const uint32_t max);
6879#endif
+54
os/src/kernel/delays.c
···11+#include "kernel/delays.h"
22+33+#include "peripherals/base.h"
44+#include "kernel/mmio.h"
55+66+77+enum
88+{
99+ SYSTMR_LO = (MMIO_BASE + 0x00003004),
1010+ SYSTMR_HI = (MMIO_BASE + 0x00003008),
1111+};
1212+1313+void wait_cycles(uint32_t n)
1414+{
1515+ if(n) while(n--) { asm volatile("nop"); }
1616+}
1717+1818+#if defined(MODEL_3)
1919+void wait_msec(uint32_t n)
2020+{
2121+ register unsigned long f, t, r;
2222+ // get the current counter frequency
2323+ asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
2424+ // read the current counter
2525+ asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
2626+ // calculate required count increase
2727+ unsigned long i=((f/1000)*n)/1000;
2828+ // loop while counter increase is less than i
2929+ do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r-t<i);
3030+}
3131+#endif
3232+3333+uint64_t get_system_timer()
3434+{
3535+ unsigned int h=-1, l;
3636+ // we must read MMIO area as two separate 32 bit reads
3737+ h=mmio_read(SYSTMR_HI);
3838+ l=mmio_read(SYSTMR_LO);
3939+ // we have to repeat it if high word changed during read
4040+ if(h!=mmio_read(SYSTMR_HI)) {
4141+ h=mmio_read(SYSTMR_HI);
4242+ l=mmio_read(SYSTMR_LO);
4343+ }
4444+ // compose long int value
4545+ return ((uint64_t) h << 32) | l;
4646+}
4747+4848+void wait_msec_st(uint32_t n)
4949+{
5050+ unsigned long t=get_system_timer();
5151+ // we must check if it's non-zero, because qemu does not emulate
5252+ // system timer, and returning constant zero would mean infinite loop
5353+ if(t) while(get_system_timer()-t < n);
5454+}
+9-2
os/src/kernel/kernel.c
···44#include "common/string.h"
55#include "kernel/kerio.h"
66#include "kernel/uart.h"
77+#include "kernel/delays.h"
7889#if defined(AARCH_32)
9101011#include "kernel/atag.h"
1112#include "kernel/gpu.h"
1213#include "kernel/memory.h"
1313-1414+#include "kernel/random.h"
1415/*!
1516 * @brief Entry point for the kernel
1617 * @param r0 0
···3536#endif
36373738 puts("Welcome to piOS!\n----------------\n\n");
3939+ printf("Wait for 5 secs if it works!\n");
4040+ wait_msec_st(5000000);
38414242+ printf("%d\n", rand(100, 500));
4343+3944 uint32_t mem_size = get_mem_size((atag_t *)atags);
4045 printf("RAM size: %d MB\n\n", mem_size / 1024 / 1024);
4146···5459{
5560 printf("ATTENTION YOU ARE IN UART MODE\n\n");
5661 uart_init();
6262+ printf("Wait for 5 secs if it works!\n");
6363+ wait_msec(5000000);
5764 printf("Architecture: AARCH_%d\n\n", 64);
5865 rand_init();
5959- printf("%d", rand(100, 500));
6666+ printf("%d\n", rand(100, 500));
6067 while(1)
6168 {
6269 putc(getc());
+14-1
os/src/kernel/random.c
···33#include "kernel/mmio.h"
44#include "common/stdlib.h"
5566+#ifndef MODEL_3
77+static uint32_t next = 1;
88+99+uint32_t rand(const uint32_t min, const uint32_t max)
1010+{
1111+ next = next * 1103515245 + 12345;
1212+ divmod_t div = divmod(next / 65536, 32768);
1313+ divmod_t t = divmod(div.mod, (max - min + 1));
1414+ return t.mod + min;
1515+}
1616+1717+#else
618enum
719{
820 RNG_CTRL = (MMIO_BASE + 0x00104000),
···2840 // available for reading; require at least one
2941 while(!(mmio_read(RNG_STATUS)>>24)) asm volatile("nop");
30423131- divmod_t rand = divmod(mmio_read(RNG_DATA), (max-min));
4343+ divmod_t rand = divmod(mmio_read(RNG_DATA), (max-min+1));
3244 return rand.mod + min;
3345}
4646+#endif