11#include "../test_helper.h"
22
3+ #include <../os/hard/idt.h>
34#include <../os/paging.h>
45
56// 1st megabyte is a safe place to read from, but not to write to
@@ -158,6 +159,59 @@ void test_modify_in_place(PageDirectory *base) {
158159 serialWrite (COM1 , (uint8_t * )(done ), sizeof (done ) - 1 );
159160}
160161
162+ volatile uint32_t errCode = -1 ;
163+
164+ void test_handler (isr_registers_t * regs ) {
165+ errCode = regs -> err_code ;
166+
167+ // We are manually incrementing the instruction pointer.
168+ // This is to avoid faulting on the same instruction forever.
169+ // But it can cause some unexpected things to happen.
170+ regs -> eip ++ ;
171+ }
172+
173+ void assert_on_fault_code (uint32_t expected ) {
174+ InterruptState iprev = disableInterrupts ();
175+ uint32_t got = errCode ;
176+ errCode = -1 ;
177+ setInterrupts (iprev );
178+
179+ // ASSERT must be called with interrupts enabled!
180+ ASSERT_M (expected == got , "Expected %i but got %i as fault error code." , expected , got );
181+ }
182+
183+ void test_entry_not_present (PageDirectory * base ) {
184+ // steal the 3MiB page and 2 more
185+ PageDirectory * newDir = (PageDirectory * )(MiB3 );
186+ PageTable * tables = (PageTable * )(MiB3 + sizeof (PageDirectory ));
187+
188+ // setup identity paged dir
189+ addTableToDirectory (newDir , 0 , tables , DEFAULT_ENTRY_FLAGS );
190+ addTableToDirectory (newDir , 1 , tables + 1 , DEFAULT_ENTRY_FLAGS );
191+
192+ identityMapTable (newDir , 0 , DEFAULT_ENTRY_FLAGS );
193+ identityMapTable (newDir , 1 , ENTRY_RW | ENTRY_US );
194+
195+ setActivePageDir (newDir );
196+
197+ volatile uint32_t * faulter = (uint32_t * )(BOUND );
198+
199+ // cause a page fault
200+ * faulter ;
201+
202+ // this nop helps eip++ not do bad things
203+ __asm__ volatile ("nop" );
204+
205+ // confusingly, the not present error code is 0.
206+ assert_on_fault_code (0 );
207+
208+ // swap back
209+ setActivePageDir (base );
210+
211+ char done [] = "test_entry_not_present done\n" ;
212+ serialWrite (COM1 , (uint8_t * )(done ), sizeof (done ) - 1 );
213+ }
214+
161215void test_main () {
162216 test_composition ();
163217
@@ -169,4 +223,9 @@ void test_main() {
169223 test_swap_page (idDir );
170224
171225 test_modify_in_place (idDir );
226+
227+ // beware the page fault handler is overriden from this point on.
228+ isrSetHandler (14 , test_handler );
229+
230+ test_entry_not_present (idDir );
172231}
0 commit comments