sylveos

Toy Operating System
Log | Files | Refs

system.zig (3818B)


      1 const mem = @import("./mem.zig");
      2 
      3 pub const SystemControlRegister = packed struct {
      4     pub const Endian = enum(u1) {
      5         LittleEndian = 0,
      6         BigEndian = 1,
      7     };
      8 
      9     pub const ExceptionVectorBaseAddress = enum(u1) {
     10         Normal = 0,
     11         High = 1,
     12     };
     13 
     14     pub const CacheReplacementStrategy = enum(u1) {
     15         Random = 0,
     16         RoundRobin = 1,
     17     };
     18 
     19     mmu_enabled: bool,
     20     strict_alignment: bool,
     21     level_one_data_cache: bool,
     22     _reserved_3: bool,
     23     _reserved_6_4: u3,
     24     endian: Endian,
     25     mmu_protection: bool,
     26     rom_protection: bool,
     27     _reserved_10: bool,
     28     branch_prediction: bool,
     29     level_one_instruction_cache: bool,
     30     exception_vector_base_address: ExceptionVectorBaseAddress,
     31     cache_replacement_strategy: CacheReplacementStrategy,
     32     set_t_bit: bool,
     33     _reserved_16: bool,
     34     _deprecated_17: bool,
     35     _reserved_18: bool,
     36     _deprecated_18: bool,
     37     _reserved_20_19: bool,
     38     low_latency_fiq: bool,
     39     unaligned_data_access: bool,
     40     extended_page_tables: bool,
     41     vic_interface: bool,
     42     cpsr_e_bit: bool,
     43     _reserved_27_26: u2,
     44     tex_remap: bool,
     45     force_access_protection: bool,
     46     _reserved_31_30: u2,
     47 
     48     pub inline fn get() @This() {
     49         return asm volatile ("MRC p15, 0, %[result], c1, c0, 0"
     50             : [result] "=r" (-> @This()),
     51         );
     52     }
     53 
     54     pub inline fn set(reg: *const @This()) void {
     55         return asm volatile ("MCR p15, 0, %[value], c1, c0, 0"
     56             :
     57             : [value] "r" (@as(u32, @bitCast(reg.*))),
     58         );
     59     }
     60 };
     61 
     62 inline fn invalidate_entire_instruction_cache() void {
     63     asm volatile ("MCR p15, 0, %[value], c7, c5, 0"
     64         :
     65         : [value] "r" (0),
     66     );
     67 }
     68 
     69 inline fn invalidate_entire_data_cache() void {
     70     asm volatile ("MCR p15, 0, %[value], c7, c6, 0"
     71         :
     72         : [value] "r" (0),
     73     );
     74 }
     75 
     76 pub inline fn clear_entire_data_cache() void {
     77     asm volatile ("MCR p15, 0, %[value], c7, c14, 0"
     78         :
     79         : [value] "r" (0),
     80     );
     81 }
     82 
     83 // Probably affected by ARM bug too
     84 // inline fn invalidate_both_caches() void {
     85 //     asm volatile ("MCR p15, 0, %[value], c7, c7, 0"
     86 //         :
     87 //         : [value] "r" (0),
     88 //     );
     89 // }
     90 
     91 pub inline fn invalidate_instruction_TLB() void {
     92     asm volatile ("MCR p15, 0, %[value], c8, c5, 0"
     93         :
     94         : [value] "r" (0),
     95     );
     96 }
     97 
     98 pub inline fn invalidate_data_TLB() void {
     99     asm volatile ("MCR p15, 0, %[value], c8, c6, 0"
    100         :
    101         : [value] "r" (0),
    102     );
    103 }
    104 
    105 pub inline fn invalidate_TLB() void {
    106     asm volatile ("MCR p15, 0, %[value], c8, c7, 0"
    107         :
    108         : [value] "r" (0),
    109     );
    110 }
    111 
    112 // https://elixir.bootlin.com/linux/latest/source/arch/arm/mm/cache-v6.S
    113 // How TF does this even happen
    114 pub inline fn invalidate_icache() void {
    115     invalidate_entire_instruction_cache();
    116     invalidate_entire_instruction_cache();
    117     invalidate_entire_instruction_cache();
    118     invalidate_entire_instruction_cache();
    119 
    120     asm volatile (
    121         \\ .rept 11
    122         \\ nop
    123         \\ .endr
    124     );
    125 }
    126 
    127 pub inline fn invalidate_dcache() void {
    128     invalidate_entire_data_cache();
    129 }
    130 
    131 pub inline fn invalidate_all_caches() void {
    132     invalidate_dcache();
    133     invalidate_icache();
    134 }
    135 
    136 /// 2.7.5
    137 ///
    138 /// Call after:
    139 ///
    140 /// 1. Enabling/Disabling MMU
    141 /// 2. Writing new data to instruction memory
    142 /// 3. Writing new mapping to PTE
    143 /// 4. Changing TTBR0, TTBR1, TTBCR
    144 /// 5. Changing context ID
    145 ///
    146 /// Always perform a prefetch buffer afterwards (3-74)
    147 pub inline fn flush_btb() void {
    148     asm volatile ("mcr p15, 0, %[value], c7, c5, 6"
    149         :
    150         : [value] "r" (0),
    151     );
    152 }
    153 
    154 // 2.7.2 (B2-22)
    155 pub inline fn flush_self_modifying_code() void {
    156     clear_entire_data_cache();
    157     mem.barrier(.Write);
    158     invalidate_icache();
    159     flush_btb();
    160     mem.barrier(.Write);
    161     mem.barrier(.Instruction);
    162 }