- kernel ready
authorSamuel Hitz <hitzs@student.ethz.ch>
Fri, 11 May 2012 09:32:20 +0000 (11:32 +0200)
committerSamuel Hitz <hitzs@student.ethz.ch>
Fri, 11 May 2012 09:32:20 +0000 (11:32 +0200)
- added 3 new devices for development board
- temporary added debug printfs

22 files changed:
devices/Hakefile
devices/cortex_a9_pit.dev [new file with mode: 0644]
devices/pl130_gic.dev [new file with mode: 0644]
devices/sp804_pit.dev [new file with mode: 0644]
hake/Gem5.hs
kernel/Hakefile
kernel/arch/arm/exec.c
kernel/arch/arm/exn.c
kernel/arch/gem5/exceptions.S
kernel/arch/gem5/init.c
kernel/arch/gem5/integrator.c
kernel/arch/gem5/paging.c
kernel/arch/gem5/startup_arch.c [new file with mode: 0644]
kernel/include/arch/gem5/arm_hal.h
kernel/include/arch/gem5/exceptions.h
kernel/include/arch/gem5/paging_kernel_arch.h
lib/barrelfish/capabilities.c
lib/barrelfish/threads.c
lib/barrelfish/vspace/memobj_anon.c
lib/barrelfish/vspace/pinned.c
lib/barrelfish/vspace/vregion.c
lib/barrelfish/vspace/vspace.c

index 063a1a6..7cc9be8 100644 (file)
            "uhci",
            "xapic",
            "x2apic",
-           "amd64"
+           "amd64",
+           "pl130_gic",
+           "sp804_pit",
+           "cortex_a9_pit"
          ], arch <- allArchitectures
 ] ++
 
diff --git a/devices/cortex_a9_pit.dev b/devices/cortex_a9_pit.dev
new file mode 100644 (file)
index 0000000..050faab
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, ETH Zurich. All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+/*
+ * cortex_a9_pit.dev
+ *
+ * DESCRIPTION: Cortex A9 Private Timer and watchdog
+ *
+ * This is derived from:
+ *
+ * Cortex-A9 MPCore Technical Reference Manual
+ * (DDI0407G_cortex_a9_mpcore_r3p0_trm.pdf)
+ *
+ */
+ device cortex_a9_pit msbfirst ( addr base ) "Cortex A9 Private Timer and watchdog" {
+       
+       register TimerLoad addr(base, 0x0) "Private Timer Load Register" type(uint32);
+       
+       register TimerCounter addr(base, 0x4) "Private Timer Counter Register" type(uint32);
+       
+       register TimerControl addr(base, 0x8) "Private Timer Control Register" {
+               _                               16      rsvd;
+               prescale                8       rw              "Prescale factor";
+               _                               5       rsvd;
+               int_enable              1       rw              "Interrupt enable bit";
+               auto_reload             1       rw              "Single shot or reload mode";
+               timer_enable    1       rw              "Timer enable bit";
+       };
+       
+       register TimerIntStat addr(base, 0xc) "Private Timer Interrupt Status Register" {
+               _                               31      rsvd;
+               event_flag              1       rw;
+       };
+       
+       register WatchdogLoad addr(base, 0x20) "Watchdog Load Register" type(uint32);
+       
+       register WatchdogCounter addr(base, 0x24) "Watchdog Counter Register" type(uint32);
+       
+       register WatchdogControl addr(base, 0x28) "Watchdog Control Register" {
+               _                               16      rsvd;
+               prescale                8       rw              "Prescale factor";
+               _                               4       rsvd;
+               wd_mode                 1       rw              "Selects Watchdog or Timer mode";
+               int_enable              1       rw              "Interrupt enable bit";
+               auto_reload             1       rw              "Single shot or reload mode";
+               wd_enable               1       rw              "Timer enable bit";
+       };
+       
+       register WatchdogIntStat addr(base, 0x2c) "Watchdog Interrupt Status Register" {
+               _                               31      rsvd;
+               event_flag              1       rw;
+       };
+       
+       register WatchdogResStat addr(base, 0x30) "Watchdog Reset Status Register" {
+               _                               31      rsvd;
+               reset_flag              1       rw;
+       };
+       
+       //write 0x12345678 then 0x87654321 to this register to disable watchdog mode
+       register WatchdogDisable wo addr(base, 0x34) "Watchdog Disable Register" type(uint32);
+       
+       
+ };
\ No newline at end of file
diff --git a/devices/pl130_gic.dev b/devices/pl130_gic.dev
new file mode 100644 (file)
index 0000000..be85d11
--- /dev/null
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2012, ETH Zurich. All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+/*
+ * pl130_gic.dev
+ *
+ * DESCRIPTION: PrimeCell PL130 Generic Interrupt Controller
+ *
+ * This is derived from:
+ *
+ * PrimeCell Generic Interrupt Controller PL130
+ * (DDI0416B_gic_pl390_r0p0_trm.pdf)
+ *
+ */
+ device pl130_gic msbfirst ( addr dist_base, addr cpu_base ) "PrimeCell PL130 Generic Interrupt Controller" {
+       
+       //
+       // Distributor register map
+       //
+       
+       register ICDDCR addr(dist_base, 0x0) "Distributor Control Register" {
+               _                       31      rsvd;
+               enable          1       rw              "enable forwarding to CPU interface";
+       };
+       
+       register ICDICTR ro addr(dist_base, 0x4) "Interrupt Controller Type Register" {
+               _                       16      rsvd;
+               LSPI            5       ro              "maximum number of lockable SPIs";
+               TZ                      1       ro              "GIC implements Security Extensions";
+               _                       2       rsvd;
+               cpu_number      3       ro              "number of implemented CPU interfaces";
+               it_lines_num 5  ro              "maximum number (N) of interrupts supported 32(N+1)";
+       };
+       
+       register ICDIIDR ro addr(dist_base, 0x8) "Distributor Implementer Identification Register" {
+               product_id      8       ro              "Product identifier";
+               rev_num         12      ro              "Revision number";
+               implementer     12      ro              "JEP106 code of implementing company";
+       };
+       
+       register SGI_ICDISR addr(dist_base, 0x80) "SGI Interrupt Security Register" type(uint16);
+       register PPI_ICDISR addr(dist_base, 0x82) "PPI Interrupt Security Register" type(uint16);
+       regarray SPI_ICDISR addr(dist_base, 0x84) [31] "SPI Interrupt Security Registers" type(uint32);
+       
+       register SGI_ICDISER ro addr(dist_base, 0x100) "SGI Interrupt Set-Enable Register" type(uint16);
+       register PPI_ICDISER  addr(dist_base, 0x102) "PPI Interrupt Set-Enable Register" type(uint16);
+       regarray SPI_ICDISER addr(dist_base, 0x104) [31] "Interrupt Set-Enable Registers" type(uint32);
+       
+       register SGI_ICDICER ro addr(dist_base, 0x180) "SGI Interrupt Clear-Enable Register" type(uint16);
+       register PPI_ICDICER  addr(dist_base, 0x182) "PPI Interrupt Clear-Enable Register" type(uint16);
+       regarray SPI_ICDICER addr(dist_base, 0x184) [31] "Interrupt Clear-Enable Registers" type(uint32);
+       
+       register SGI_ICDISPR ro addr(dist_base, 0x200) "SGI Interrupt Set-Pending Register" type(uint16);
+       register PPI_ICDISPR  addr(dist_base, 0x202) "PPI Interrupt Set-Pending Register" type(uint16);
+       regarray SPI_ICDISPR addr(dist_base, 0x204) [31] "Interrupt Set-Pending Registers" type(uint32);
+       
+       register SGI_ICDICPR ro addr(dist_base, 0x280) "SGI Interrupt Clear-Pending Register" type(uint16);
+       register PPI_ICDICPR  addr(dist_base, 0x282) "PPI Interrupt Clear-Pending Register" type(uint16);
+       regarray SPI_ICDICPR addr(dist_base, 0x284) [31] "Interrupt Clear-Pending Registers" type(uint32);
+       
+       register SGI_ICDABR ro addr(dist_base, 0x300) "SGI Interrupt Active Bit Register" type(uint16);
+       register PPI_ICDABR ro addr(dist_base, 0x302) "PPI Interrupt Active Bit Register" type(uint16);
+       regarray SPI_ICDABR ro addr(dist_base, 0x304) [31] "Interrupt Active Bit Registers" type(uint32);
+       
+       regtype priority_reg "Interrupt priority register" {
+               prio_off3       8       rw      "Priority, byte offset 3";
+               prio_off2       8       rw      "Priority, byte offset 2";
+               prio_off1       8       rw      "Priority, byte offset 1";
+               prio_off0       8       rw      "Priority, byte offset 0";
+       };
+       
+       regarray SGI_ICDIPR addr(dist_base, 0x400) [4] "SGI Interrupt Priority Registers" type(priority_reg);
+       regarray PPI_ICDIPR addr(dist_base, 0x410) [4] "PPI Interrupt Priority Registers" type(priority_reg);
+       regarray SPI_ICDIPR addr(dist_base, 0x420) [246] "Interrupt Active Bit Registers" type(priority_reg);
+       
+       regtype cpu_targets_ro_reg "SGI/PPI CPU targets register" {
+               targets_off3    8       ro      "CPU targets, byte offset 3";
+               targets_off2    8       ro      "CPU targets, byte offset 2";
+               targets_off1    8       ro      "CPU targets, byte offset 1";
+               targets_off0    8       ro      "CPU targets, byte offset 0";
+       };
+       
+       regtype cpu_targets_reg "SPI CPU targets register" {
+               targets_off3    8       rw      "CPU targets, byte offset 3";
+               targets_off2    8       rw      "CPU targets, byte offset 2";
+               targets_off1    8       rw      "CPU targets, byte offset 1";
+               targets_off0    8       rw      "CPU targets, byte offset 0";
+       };
+       
+       regarray SGI_ICDIPTR ro addr(dist_base, 0x800) [4] "SGI Interrupt Processor Targets Registers" type(cpu_targets_ro_reg);
+       regarray PPI_ICDIPTR ro addr(dist_base, 0x810) [4] "PPI Interrupt Processor Targets Registers" type(cpu_targets_ro_reg);
+       regarray SPI_ICDIPTR addr(dist_base, 0x820) [246] "SPI Interrupt Processor Targets Registers" type(cpu_targets_reg);
+       
+       register SGI_ICDICR ro addr(dist_base, 0xC00) "SGI Interrupt Configuration Register" {
+               sgi15           2       ro      "Configuration SGI 15";
+               sgi14           2       ro      "Configuration SGI 14";
+               sgi13           2       ro      "Configuration SGI 13";
+               sgi12           2       ro      "Configuration SGI 12";
+               sgi11           2       ro      "Configuration SGI 11";
+               sgi10           2       ro      "Configuration SGI 10";
+               sgi9            2       ro      "Configuration SGI 9";
+               sgi8            2       ro      "Configuration SGI 8";
+               sgi7            2       ro      "Configuration SGI 7";
+               sgi6            2       ro      "Configuration SGI 6";
+               sgi5            2       ro      "Configuration SGI 5";
+               sgi4            2       ro      "Configuration SGI 4";
+               sgi3            2       ro      "Configuration SGI 3";
+               sgi2            2       ro      "Configuration SGI 2";
+               sgi1            2       ro      "Configuration SGI 1";
+               sgi0            2       ro      "Configuration SGI 0";
+       };
+       
+       register PPI_ICDICR ro addr(dist_base, 0xC04) "PPI Interrupt Configuration Register" {
+               ppi15           2       ro      "Configuration ppi 15";
+               ppi14           2       ro      "Configuration ppi 14";
+               ppi13           2       ro      "Configuration ppi 13";
+               ppi12           2       ro      "Configuration ppi 12";
+               ppi11           2       ro      "Configuration ppi 11";
+               ppi10           2       ro      "Configuration ppi 10";
+               ppi9            2       ro      "Configuration ppi 9";
+               ppi8            2       ro      "Configuration ppi 8";
+               ppi7            2       ro      "Configuration ppi 7";
+               ppi6            2       ro      "Configuration ppi 6";
+               ppi5            2       ro      "Configuration ppi 5";
+               ppi4            2       ro      "Configuration ppi 4";
+               ppi3            2       ro      "Configuration ppi 3";
+               ppi2            2       ro      "Configuration ppi 2";
+               ppi1            2       ro      "Configuration ppi 1";
+               ppi0            2       ro      "Configuration ppi 0";
+       };
+       
+       regtype spi_config_reg  "SPI Interrupt Configuration Register" {
+               spi15           2       rw      "Configuration SPI 15";
+               spi14           2       rw      "Configuration SPI 14";
+               spi13           2       rw      "Configuration SPI 13";
+               spi12           2       rw      "Configuration SPI 12";
+               spi11           2       rw      "Configuration SPI 11";
+               spi10           2       rw      "Configuration SPI 10";
+               spi9            2       rw      "Configuration SPI 9";
+               spi8            2       rw      "Configuration SPI 8";
+               spi7            2       rw      "Configuration SPI 7";
+               spi6            2       rw      "Configuration SPI 6";
+               spi5            2       rw      "Configuration SPI 5";
+               spi4            2       rw      "Configuration SPI 4";
+               spi3            2       rw      "Configuration SPI 3";
+               spi2            2       rw      "Configuration SPI 2";
+               spi1            2       rw      "Configuration SPI 1";
+               spi0            2       rw      "Configuration SPI 0";
+       };
+       
+       regarray SPI_ICDICR addr(dist_base, 0xc08) [62] "SPI Interrupt Configuration Registers" type(spi_config_reg);
+       
+       register PPI_STATUS ro addr(dist_base, 0xd00) "PPI Status Register" {
+               _                       16      rsvd;
+               ppi_status      16      ro              "Status of PPI0 - PPI15";
+       };
+       
+       regarray SPI_STATUS ro addr(dist_base, 0xd04) [30] "SPI Status Registers" type(uint32);
+       
+       register ICDSGIR wo addr(dist_base, 0xf00) "Sogtware Generated Interrupt Register" {
+               _                                       6       rsvd;
+               target_list_filter      2       wo              "Target List Filter";
+               cpu_target_list         8       wo              "CPU Target List";
+               SATT                            1       wo              "Secure Access Bit";
+               _                                       11      rsvd;
+               SGIINTID                        4       wo              "SGI Interrupt ID";
+       };
+       
+       register DIST_PERIPH_ID0 ro addr(dist_base, 0xfec) "Peripheral Identification Register 0" {
+               _                                       24      rsvd;
+               part_number_0           8       ro              "Part Number 0";
+       };
+       
+       register DIST_PERIPH_ID1 ro addr(dist_base, 0xfe8) "Peripheral Identification Register 1" {
+               _                                       24      rsvd;
+               jep106_id_3_0           4       ro              "JEP106 identity code [3:0]";
+               part_number_1           4       ro              "Part Number 1";
+       };
+       
+       register DIST_PERIPH_ID2 ro addr(dist_base, 0xfe4) "Peripheral Identification Register 2" {
+               _                                       24      rsvd;
+               architecure                     4       ro              "Architecture version of the GIC";
+               jedec_used                      1       ro              "is ID allocated by JEDEC";
+               jep106_id_6_4           3       ro              "JEP106 identity code [6:4]";
+       };
+       
+       register DIST_PERIPH_ID3 ro addr(dist_base, 0xfe0) "Peripheral Identification Register 3" {
+               _                                       24      rsvd;
+               rev_and                         4       ro              "Revision of AND Gates";
+               mod_number                      4       ro              "Modification Number";
+       };
+       
+       register DIST_PERIPH_ID4 ro addr(dist_base, 0xfdc) "Peripheral Identification Register 4" {
+               _                                       24      rsvd;
+               page_count                      4       ro              "# of 4KB blocks needed to access Registers";
+               jep106_c_code           4       ro              "JEP106 continuation code";
+       };
+       
+       register DIST_PERIPH_ID5 ro addr(dist_base, 0xfd8) "Peripheral Identification Register 5" {
+               _                                       24      rsvd;
+               ppi_number_0            4       ro              "LSBs of the # of PPIs the GIC provides";
+               sgi_number                      4       ro              "# of SGIs the GIC provides";
+       };
+       
+       register DIST_PERIPH_ID6 ro addr(dist_base, 0xfd4) "Peripheral Identification Register 6" {
+               _                                       24      rsvd;
+               spi_number_0            4       ro              "LSBs of the # of SPIs the GIC provides";
+               ppi_number_1            4       ro              "MSBs of the # of PPIs the GIC provides";
+       };
+       
+       register DIST_PERIPH_ID7 ro addr(dist_base, 0xfd0) "Peripheral Identification Register 7" {
+               _                                       24      rsvd;
+               tz                                      1       ro              "# of secure states";
+               priority                        3       ro              "# of priority levels the GIC provides";
+               spi_number_1            4       ro              "MSBs of the # of SPIs the GIC provides";
+       };
+       
+       register DIST_PERIPH_ID8 ro addr(dist_base, 0xfc0) "Peripheral Identification Register 8" {
+               _                                       24      rsvd;
+               identifier                      1       ro              "AMBA interface ID";
+               if_type                         2       ro              "AMBA protocoll";
+               cpu_if                          3       ro              "# of CPU interfaces";
+               fiq_legacy                      1       ro              "Legacy FIQ signals supported";
+               irq_legacy                      1       ro              "Legacy IRQ signals supported";
+       };
+       
+       register DIST_COMPONENT_ID0 ro addr(dist_base, 0xffc) "PrimeCell Identification Register 0" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       register DIST_COMPONENT_ID1 ro addr(dist_base, 0xff8) "PrimeCell Identification Register 1" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       register DIST_COMPONENT_ID2 ro addr(dist_base, 0xff4) "PrimeCell Identification Register 2" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       register DIST_COMPONENT_ID3 ro addr(dist_base, 0xff0) "PrimeCell Identification Register 3" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       
+       //
+       // CPU interface register map
+       //
+       
+       register ICCICR addr(cpu_base, 0x0) "CPU Interface Control Register" {
+               _                                       31      rsvd;
+               enable                          1       rw              "enable forwarding to connected processors";
+       };
+       
+       register ICCPMR addr(cpu_base, 0x4) "Interrupt Priority Mask Register" {
+               _                                       24      rsvd;
+               priority                        8       rw              "Priority mask level for CPU Interface";
+       };
+       
+       register ICCBPR addr(cpu_base, 0x8) "Binary Point Register" {
+               _                                       29      rsvd;
+               binary_point            3                       "Split Group- and subpriority";
+       };
+       
+       register ICCIAR ro addr(cpu_base, 0xc) "Interrupt Acknowledge Register" {
+               _                                       19      rsvd;
+               cpu_id                          3       ro              "Processor ID of interrupting processor";
+               ack_int_id                      10      ro              "Interrupt ID";
+       };
+       
+       register ICCEOIR wo addr(cpu_base, 0x10) "End of Interrupt Register" {
+               _                                       19      rsvd;
+               cpu_id                          3       wo              "Proc ID of corresponding ICCIAR access";
+               eoi_int_id                      10      wo              "ACKINTID of corresponding ICCIAR access";
+       };
+       
+       register ICCRPR ro addr(cpu_base, 0x14) "Running Priority Register" {
+               _                                       24      rsvd;
+               priority                        8       ro              "Highest priority active interrupt";
+       };
+       
+       register ICCHPIR ro addr(cpu_base, 0x18) "Highest Pending Interrupt Register" {
+               _                                       19      rsvd;
+               cpu_id                          3       ro              "Processor ID of interrupting processor";
+               pend_int_id                     10      ro              "Interrupt ID of highest priority pending interrupt";
+       };
+       
+       register ICCABPR addr(cpu_base, 0x1c) "Aliased Binary Point Register" {
+               _                                       29      rsvd;
+               binary_point            3                       "Split Group- and subpriority";
+       };
+       
+       register ICCIIDR ro addr(cpu_base, 0xfc) "CPU Interface Identification Register" {
+               product_id                      12      ro              "Product ID";
+               arch_version            4       ro              "Implemented GIC architecture version";
+               revision                        4       ro              "Revision number for the CPU Interface";
+               implementer                     12      ro              "JEP106 code of the implementer";
+       };
+       
+       /*
+       register CPU_PERIPH_ID0 ro addr(cpu_base, 0xfe8) "Peripheral Identification Register 0" {
+               _                                       24      rsvd;
+               part_number_0           8       ro              "Part Number 0";
+       };
+       
+       register CPU_PERIPH_ID1 ro addr(cpu_base, 0xfe8) "Peripheral Identification Register 1" {
+               _                                       24      rsvd;
+               jep106_id_3_0           4       ro              "JEP106 identity code [3:0]";
+               part_number_1           4       ro              "Part Number 1";
+       };
+       
+       register CPU_PERIPH_ID2 ro addr(cpu_base, 0xfe4) "Peripheral Identification Register 2" {
+               _                                       24      rsvd;
+               architecure                     4       ro              "Architecture version of the GIC";
+               jedec_used                      1       ro              "is ID allocated by JEDEC";
+               jep106_id_6_4           3       ro              "JEP106 identity code [6:4]";
+       };
+       
+       register CPU_PERIPH_ID3 ro addr(cpu_base, 0xfe0) "Peripheral Identification Register 3" {
+               _                                       24      rsvd;
+               rev_and                         4       ro              "Revision of AND Gates";
+               mod_number                      4       ro              "Modification Number";
+       };
+       
+       register CPU_PERIPH_ID4 ro addr(cpu_base, 0xfdc) "Peripheral Identification Register 4" {
+               _                                       24      rsvd;
+               page_count                      4       ro              "# of 4KB blocks needed to access Registers";
+               jep106_c_code           4       ro              "JEP106 continuation code";
+       };
+       
+       register CPU_PERIPH_ID5 ro addr(cpu_base, 0xfd8) "Peripheral Identification Register 5" {
+               _                                       24      rsvd;
+               ppi_number_0            4       ro              "LSBs of the # of PPIs the GIC provides";
+               sgi_number                      4       ro              "# of SGIs the GIC provides";
+       };
+       
+       register CPU_PERIPH_ID6 ro addr(cpu_base, 0xfd4) "Peripheral Identification Register 6" {
+               _                                       24      rsvd;
+               spi_number_0            4       ro              "LSBs of the # of SPIs the GIC provides";
+               ppi_number_1            4       ro              "MSBs of the # of PPIs the GIC provides";
+       };
+       
+       register CPU_PERIPH_ID7 ro addr(cpu_base, 0xfd0) "Peripheral Identification Register 7" {
+               _                                       24      rsvd;
+               tz                                      1       ro              "# of secure states";
+               priority                        3       ro              "# of priority levels the GIC provides";
+               spi_number_1            4       ro              "MSBs of the # of SPIs the GIC provides";
+       };
+       
+       register CPU_PERIPH_ID8 ro addr(cpu_base, 0xfc0) "Peripheral Identification Register 8" {
+               _                                       24      rsvd;
+               identifier                      1       ro              "AMBA interface ID";
+               if_type                         2       ro              "AMBA protocoll";
+               cpu_if                          3       ro              "# of CPU interfaces";
+               fiq_legacy                      1       ro              "Legacy FIQ signals supported";
+               irq_legacy                      1       ro              "Legacy IRQ signals supported";
+       };
+       
+       register CPU_COMPONENT_ID0 ro addr(cpu_base, 0xffc) "PrimeCell Identification Register 0" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       register CPU_COMPONENT_ID1 ro addr(cpu_base, 0xff8) "PrimeCell Identification Register 1" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       register CPU_COMPONENT_ID2 ro addr(cpu_base, 0xff4) "PrimeCell Identification Register 2" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       
+       register CPU_COMPONENT_ID3 ro addr(cpu_base, 0xff0) "PrimeCell Identification Register 3" {
+               _                                       24      rsvd;
+               component_id            8       ro;
+       };
+       */
+ };
\ No newline at end of file
diff --git a/devices/sp804_pit.dev b/devices/sp804_pit.dev
new file mode 100644 (file)
index 0000000..6938e8e
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012, ETH Zurich. All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+/*
+ * sp804_pit.dev
+ *
+ * DESCRIPTION: Dual-Timer Module SP804
+ *
+ * This is derived from:
+ *
+ * ARM Dual-Timer Module (SP804) Technical Reference Manual
+ * (DDI0271_sp804_timer_trm.pdf)
+ *
+ */
+device sp804_pit msbfirst ( addr base ) "Dual-Timer Module SP804" {
+       
+       constants prescale "Possible Prescale Values" {
+               prescale0       =       0b00    "0 stages of prescale, clock divided by 1";
+               prescale4       =       0b01    "4 stages of prescale, clock divided by 16";
+               prescale8       =       0b10    "8 stages of prescale, clock divided by 256";
+       };
+       
+       constants timer_size "Timer operation sizes" {
+               size_16bit      =       0b0             "16-bit counter";
+               size_32bit      =       0b1             "32-bit counter";
+       };
+       
+       constants timer_modes "Timer Running Mode" {
+           free   = 0b0 "Counts once and then wraps to 0xffff";
+           periodic = 0b1 "Reloads from load register at end of each count"; 
+       };
+       
+       
+       //
+       // timer 1
+       //
+       
+       register Timer1Load addr(base, 0x0) "Load Register" type(uint32);
+       
+       register Timer1Value ro addr(base, 0x4) "Current Value Register" type(uint32);
+       
+       register Timer1Control addr(base, 0x8) "Control Register" {
+               _                               24      rsvd;
+               timer_en                1       rw              "Enable Bit";
+               timer_mode              1       rw              "Mode Bit";
+               int_enable              1       rw              "Interrupt Enable Bit";
+               _                               1       rsvd;
+               timer_pre               2       rw              "Prescale Bits";
+               timer_size              1       rw              "Selects 16/32 bit mode";
+               one_shot                1       rw              "Selects one-shot or wrapping counter mode";    
+       };
+       
+       register Timer1IntClr wo addr(base, 0xc) "Interrupt Clear Register" type(uint32);
+       
+       register Timer1RIS ro addr(base, 0x10) "Raw Interrupt Status Register" {
+               _                               31      rsvd;
+               ri_status               1       ro              "Raw interrupt status from the counter";
+       };
+       
+       register Timer1MIS ro addr(base, 0x14) "Masked Interrupt Status Register" {
+               _                               31      rsvd;
+               mi_status               1       ro              "Masked interrupt status from the counter";
+       };
+       
+       register Timer1BGLoad addr(base, 0x18) "Background Load Register" type(uint32);
+       
+       //
+       // timer 2
+       //
+       
+       register Timer2Load addr(base, 0x20) "Load Register" type(uint32);
+       
+       register Timer2Value ro addr(base, 0x24) "Current Value Register" type(uint32);
+       
+       register Timer2Control addr(base, 0x28) "Control Register" {
+               _                               24      rsvd;
+               timer_en                1       rw              "Enable Bit";
+               timer_mode              1       rw              "Mode Bit";
+               int_enable              1       rw              "Interrupt Enable Bit";
+               _                               1       rsvd;
+               timer_pre               2       rw              "Prescale Bits";
+               timer_size              1       rw              "Selects 16/32 bit mode";
+               one_shot                1       rw              "Selects one-shot or wrapping counter mode";    
+       };
+       
+       register Timer2IntClr wo addr(base, 0x2c) "Interrupt Clear Register" type(uint32);
+       
+       register Timer2RIS ro addr(base, 0x30) "Raw Interrupt Status Register" {
+               _                               31      rsvd;
+               ri_status               1       ro              "Raw interrupt status from the counter";
+       };
+       
+       register Timer2MIS ro addr(base, 0x34) "Masked Interrupt Status Register" {
+               _                               31      rsvd;
+               mi_status               1       ro              "Masked interrupt status from the counter";
+       };
+       
+       register Timer2BGLoad addr(base, 0x38) "Background Load Register" type(uint32);
+ };
\ No newline at end of file
index 06a1240..d7b9145 100644 (file)
---------------------------------------------------------------------------
--- Copyright (c) 2007-2010, ETH Zurich.
--- All rights reserved.
---
--- This file is distributed under the terms in the attached LICENSE file.
--- If you do not find this file, copies can be found by writing to:
--- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
---
--- Architectural definitions for Barrelfish on ARMv5 ISA.
---
--- The build target is the integratorcp board on QEMU with the default
--- ARM926EJ-S cpu.
---
---------------------------------------------------------------------------
-
-module Gem5 where
-
-import HakeTypes
-import Path
-import qualified Config
-import qualified ArchDefaults
-
--------------------------------------------------------------------------
---
--- Architecture specific definitions for ARM
---
--------------------------------------------------------------------------
-
-arch = "gem5"
-archFamily = "arm"
-
-compiler = "arm-none-linux-gnueabi-gcc"
-objcopy  = "arm-none-linux-gnueabi-objcopy"
-objdump  = "arm-none-linux-gnueabi-objdump"
-ar       = "arm-none-linux-gnueabi-ar"
-ranlib   = "arm-none-linux-gnueabi-ranlib"
-cxxcompiler = "arm-none-linux-gnueabi-g++"
-
-ourCommonFlags = [ Str "-fno-unwind-tables",
-                   Str "-Wno-packed-bitfield-compat",
-                   Str "-mcpu=cortex-a9",
-                   Str "-mapcs",
-                   Str "-mabi=aapcs-linux",
-                   Str "-msingle-pic-base",
-                   Str "-mpic-register=r10",
-                   Str "-DPIC_REGISTER=R10",
-                   Str "-fpic",
-                   Str "-ffixed-r9",
-                   Str "-DTHREAD_REGISTER=R9",
-                   Str "-D__ARM_CORTEX__",
-                  Str "-Wno-unused-but-set-variable",
-                  Str "-Wno-format"
- ]
-
-cFlags = ArchDefaults.commonCFlags 
-         ++ ArchDefaults.commonFlags
-         ++ ourCommonFlags
-
-cxxFlags = ArchDefaults.commonCxxFlags
-           ++ ArchDefaults.commonFlags
-           ++ ourCommonFlags
-
-cDefines = ArchDefaults.cDefines options
-
-ourLdFlags = [ Str "-Wl,-section-start,.text=0x400000",
-               Str "-Wl,-section-start,.data=0x600000" ]
-
-ldFlags = ArchDefaults.ldFlags arch ++ ourLdFlags
-ldCxxFlags = ArchDefaults.ldCxxFlags arch ++ ourLdFlags
-
-stdLibs = ArchDefaults.stdLibs arch ++ [ Str "-lgcc" ]
-
-options = (ArchDefaults.options arch archFamily) { 
-            optFlags = cFlags,
-            optCxxFlags = cxxFlags,
-            optDefines = cDefines,
-            optDependencies = 
-                [ PreDep InstallTree arch "/include/errors/errno.h",
-                  PreDep InstallTree arch "/include/barrelfish_kpi/capbits.h",
-                  PreDep InstallTree arch "/include/asmoffsets.h", 
-                  PreDep InstallTree arch "/include/romfs_size.h" ],
-            optLdFlags = ldFlags,
-            optLdCxxFlags = ldCxxFlags,
-            optLibs = stdLibs,
-            optInterconnectDrivers = ["lmp"],
-            optFlounderBackends = ["lmp"]
-          }
-
---
--- Compilers
---
-cCompiler = ArchDefaults.cCompiler arch compiler
-cxxCompiler = ArchDefaults.cxxCompiler arch cxxcompiler
-makeDepend = ArchDefaults.makeDepend arch compiler
-makeCxxDepend  = ArchDefaults.makeCxxDepend arch cxxcompiler
-cToAssembler = ArchDefaults.cToAssembler arch compiler
-assembler = ArchDefaults.assembler arch compiler
-archive = ArchDefaults.archive arch
-linker = ArchDefaults.linker arch compiler
-cxxlinker = ArchDefaults.cxxlinker arch cxxcompiler
-
-
---
--- The kernel is "different"
---
-
-kernelCFlags = [ Str s | s <- [ "-fno-builtin",
-                                "-fno-unwind-tables",
-                                "-nostdinc",
-                                "-std=c99",
-                                "-mcpu=cortex-a9",
-                                "-mapcs",
-                                "-mabi=aapcs-linux",
-                                "-fPIE",
-                                "-U__linux__",
-                                "-Wall",
-                                "-Wshadow",
-                                "-Wstrict-prototypes",
-                                "-Wold-style-definition",
-                                "-Wmissing-prototypes",
-                                "-Wmissing-declarations",
-                                "-Wmissing-field-initializers",
-                                "-Wredundant-decls",
-                                "-Werror",
-                                "-imacros deputy/nodeputy.h",
-                                "-fpie",
-                                "-fno-stack-check",
-                                "-ffreestanding",
-                                "-fomit-frame-pointer",
-                                "-mno-long-calls",
-                                "-Wmissing-noreturn",
-                                "-mno-apcs-stack-check",
-                                "-mno-apcs-reentrant",
-                                "-msingle-pic-base",
-                                "-mpic-register=r10",
-                                "-DPIC_REGISTER=R10",
-                                "-ffixed-r9",
-                                "-DTHREAD_REGISTER=R9",
-                                "-D__ARM_CORTEX__",
-                               "-Wno-unused-but-set-variable",
-                               "-Wno-format" ]]
-
-kernelLdFlags = [ Str "-Wl,-N",
-                  NStr "-Wl,-Map,", Out arch "kernel.map",
-                  Str "-fno-builtin",
-                  Str "-nostdlib",
-                  Str "-Wl,--fatal-warnings"
-                ]
-
-
---
--- Link the kernel (CPU Driver)
---
-linkKernel :: Options -> [String] -> [String] -> String -> HRule
-linkKernel opts objs libs kbin =
-    let linkscript = "/kernel/linker.lds"
-        kbootable  = kbin ++ ".bin"
-    in
-        Rules [ Rule ([ Str compiler, Str Config.cOptFlags,
-                      NStr "-T", In BuildTree arch linkscript,
-                      Str "-o", Out arch kbin
-                    ]
-                    ++ (optLdFlags opts)
-                    ++
-                    [ In BuildTree arch o | o <- objs ]
-                    ++
-                    [ In BuildTree arch l | l <- libs ]
-                    ++
-                    [ Str "-lgcc" ]
-                   ),
-              -- Edit ELF header so qemu-system-arm will treat it as a Linux kernel
---              Rule [ In SrcTree "src" "/tools/arm-mkbootelf.sh",
---                     Str objdump, In BuildTree arch kbin, Out arch (kbootable)],
-              -- Generate kernel assembly dump
-              Rule [ Str (objdump ++ " -d -M reg-names-raw"),
-                    In BuildTree arch kbin, Str ">", Out arch (kbin ++ ".asm")],
-              Rule [ Str "cpp",
-                     NStr "-I", NoDep SrcTree "src" "/kernel/include/arch/gem5",
-                     Str "-D__ASSEMBLER__",
-                     Str "-P", In SrcTree "src" "/kernel/arch/gem5/linker.lds.in",
-                     Out arch linkscript
-                   ]
-            ]
+--------------------------------------------------------------------------\r
+-- Copyright (c) 2007-2010, ETH Zurich.\r
+-- All rights reserved.\r
+--\r
+-- This file is distributed under the terms in the attached LICENSE file.\r
+-- If you do not find this file, copies can be found by writing to:\r
+-- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.\r
+--\r
+-- Architectural definitions for Barrelfish on ARMv5 ISA.\r
+--\r
+-- The build target is the integratorcp board on QEMU with the default\r
+-- ARM926EJ-S cpu.\r
+--\r
+--------------------------------------------------------------------------\r
+\r
+module Gem5 where\r
+\r
+import HakeTypes\r
+import Path\r
+import qualified Config\r
+import qualified ArchDefaults\r
+\r
+-------------------------------------------------------------------------\r
+--\r
+-- Architecture specific definitions for ARM\r
+--\r
+-------------------------------------------------------------------------\r
+\r
+arch = "gem5"\r
+archFamily = "arm"\r
+\r
+compiler = "arm-none-linux-gnueabi-gcc"\r
+objcopy  = "arm-none-linux-gnueabi-objcopy"\r
+objdump  = "arm-none-linux-gnueabi-objdump"\r
+ar       = "arm-none-linux-gnueabi-ar"\r
+ranlib   = "arm-none-linux-gnueabi-ranlib"\r
+cxxcompiler = "arm-none-linux-gnueabi-g++"\r
+\r
+ourCommonFlags = [ Str "-fno-unwind-tables",\r
+                   Str "-Wno-packed-bitfield-compat",\r
+                   Str "-mcpu=cortex-a9",\r
+                   Str "-mapcs",\r
+                   Str "-mabi=aapcs-linux",\r
+                   Str "-msingle-pic-base",\r
+                   Str "-mpic-register=r10",\r
+                   Str "-DPIC_REGISTER=R10",\r
+                   Str "-fpic",\r
+                   Str "-ffixed-r9",\r
+                   Str "-DTHREAD_REGISTER=R9",\r
+                   Str "-D__ARM_CORTEX__",\r
+                  Str "-D__ARM_ARCH_7A__",\r
+                          Str "-D__GEM5__",\r
+                  Str "-Wno-unused-but-set-variable",\r
+                  Str "-Wno-format"\r
+ ]\r
+\r
+cFlags = ArchDefaults.commonCFlags \r
+         ++ ArchDefaults.commonFlags\r
+         ++ ourCommonFlags\r
+\r
+cxxFlags = ArchDefaults.commonCxxFlags\r
+           ++ ArchDefaults.commonFlags\r
+           ++ ourCommonFlags\r
+\r
+cDefines = ArchDefaults.cDefines options\r
+\r
+ourLdFlags = [ Str "-Wl,-section-start,.text=0x400000",\r
+               Str "-Wl,-section-start,.data=0x600000" ]\r
+\r
+ldFlags = ArchDefaults.ldFlags arch ++ ourLdFlags\r
+ldCxxFlags = ArchDefaults.ldCxxFlags arch ++ ourLdFlags\r
+\r
+stdLibs = ArchDefaults.stdLibs arch ++ [ Str "-lgcc" ]\r
+\r
+options = (ArchDefaults.options arch archFamily) { \r
+            optFlags = cFlags,\r
+            optCxxFlags = cxxFlags,\r
+            optDefines = cDefines,\r
+            optDependencies = \r
+                [ PreDep InstallTree arch "/include/errors/errno.h",\r
+                  PreDep InstallTree arch "/include/barrelfish_kpi/capbits.h",\r
+                  PreDep InstallTree arch "/include/asmoffsets.h", \r
+                  PreDep InstallTree arch "/include/romfs_size.h" ],\r
+            optLdFlags = ldFlags,\r
+            optLdCxxFlags = ldCxxFlags,\r
+            optLibs = stdLibs,\r
+            optInterconnectDrivers = ["lmp"],\r
+            optFlounderBackends = ["lmp"]\r
+          }\r
+\r
+--\r
+-- Compilers\r
+--\r
+cCompiler = ArchDefaults.cCompiler arch compiler\r
+cxxCompiler = ArchDefaults.cxxCompiler arch cxxcompiler\r
+makeDepend = ArchDefaults.makeDepend arch compiler\r
+makeCxxDepend  = ArchDefaults.makeCxxDepend arch cxxcompiler\r
+cToAssembler = ArchDefaults.cToAssembler arch compiler\r
+assembler = ArchDefaults.assembler arch compiler\r
+archive = ArchDefaults.archive arch\r
+linker = ArchDefaults.linker arch compiler\r
+cxxlinker = ArchDefaults.cxxlinker arch cxxcompiler\r
+\r
+\r
+--\r
+-- The kernel is "different"\r
+--\r
+\r
+kernelCFlags = [ Str s | s <- [ "-fno-builtin",\r
+                                "-fno-unwind-tables",\r
+                                "-nostdinc",\r
+                                "-std=c99",\r
+                                "-mcpu=cortex-a9",\r
+                                "-mapcs",\r
+                                "-mabi=aapcs-linux",\r
+                                "-fPIE",\r
+                                "-U__linux__",\r
+                                "-Wall",\r
+                                "-Wshadow",\r
+                                "-Wstrict-prototypes",\r
+                                "-Wold-style-definition",\r
+                                "-Wmissing-prototypes",\r
+                                "-Wmissing-declarations",\r
+                                "-Wmissing-field-initializers",\r
+                                "-Wredundant-decls",\r
+                                "-Werror",\r
+                                "-imacros deputy/nodeputy.h",\r
+                                "-fpie",\r
+                                "-fno-stack-check",\r
+                                "-ffreestanding",\r
+                                "-fomit-frame-pointer",\r
+                                "-mno-long-calls",\r
+                                "-Wmissing-noreturn",\r
+                                "-mno-apcs-stack-check",\r
+                                "-mno-apcs-reentrant",\r
+                                "-msingle-pic-base",\r
+                                "-mpic-register=r10",\r
+                                "-DPIC_REGISTER=R10",\r
+                                "-ffixed-r9",\r
+                                "-DTHREAD_REGISTER=R9",\r
+                                "-D__ARM_CORTEX__",\r
+                               "-D__ARM_ARCH_7A__",\r
+                               "-D__GEM5__",\r
+                               "-Wno-unused-but-set-variable",\r
+                               "-Wno-format" ]]\r
+\r
+kernelLdFlags = [ Str "-Wl,-N",\r
+                  NStr "-Wl,-Map,", Out arch "kernel.map",\r
+                  Str "-fno-builtin",\r
+                  Str "-nostdlib",\r
+                  Str "-Wl,--fatal-warnings"\r
+                ]\r
+\r
+\r
+--\r
+-- Link the kernel (CPU Driver)\r
+--\r
+linkKernel :: Options -> [String] -> [String] -> String -> HRule\r
+linkKernel opts objs libs kbin =\r
+    let linkscript = "/kernel/linker.lds"\r
+        kbootable  = kbin ++ ".bin"\r
+    in\r
+        Rules [ Rule ([ Str compiler, Str Config.cOptFlags,\r
+                      NStr "-T", In BuildTree arch linkscript,\r
+                      Str "-o", Out arch kbin\r
+                    ]\r
+                    ++ (optLdFlags opts)\r
+                    ++\r
+                    [ In BuildTree arch o | o <- objs ]\r
+                    ++\r
+                    [ In BuildTree arch l | l <- libs ]\r
+                    ++\r
+                    [ Str "-lgcc" ]\r
+                   ),\r
+              -- Edit ELF header so qemu-system-arm will treat it as a Linux kernel\r
+--              Rule [ In SrcTree "src" "/tools/arm-mkbootelf.sh",\r
+--                     Str objdump, In BuildTree arch kbin, Out arch (kbootable)],\r
+              -- Generate kernel assembly dump\r
+              Rule [ Str (objdump ++ " -d -M reg-names-raw"),\r
+                    In BuildTree arch kbin, Str ">", Out arch (kbin ++ ".asm")],\r
+              Rule [ Str "cpp",\r
+                     NStr "-I", NoDep SrcTree "src" "/kernel/include/arch/gem5",\r
+                     Str "-D__ASSEMBLER__",\r
+                     Str "-P", In SrcTree "src" "/kernel/arch/gem5/linker.lds.in",\r
+                     Out arch linkscript\r
+                   ]\r
+            ]\r
index e3e39fa..27eac1a 100644 (file)
@@ -124,10 +124,10 @@ in [
     
     -- gem5
    (let sfiles = [  ]
-        cfiles = [ "exn.c", "exec.c", "kludges.c", "kputchar.c", "misc.c", "phys_mmap.c", "startup_arch.c", "syscall.c" ]
+        cfiles = [ "exn.c", "exec.c", "kludges.c", "kputchar.c", "misc.c", "phys_mmap.c", "syscall.c" ]
         arch_sfiles = [ "boot.S", "exceptions.S" ]
-       arch_cfiles = ["init.c", "integrator.c", "paging.c", "pl011_uart.c" ]
-       mackerelFiles = [ "arm", "arm_icp_pit", "arm_icp_pic0", "pl011_uart" ]
+       arch_cfiles = ["init.c", "integrator.c", "paging.c", "pl011_uart.c", "startup_arch.c" ]
+       mackerelFiles = [ "arm", "arm_icp_pit", "pl011_uart", "pl130_gic", "sp804_pit", "cortex_a9_pit" ]
         libs = [ "elf", "cpio" ]
     in mkrules "gem5" cfiles sfiles mackerelFiles libs [] [] arch_cfiles arch_sfiles),
     
index b08c6d9..325d2c1 100644 (file)
@@ -114,9 +114,8 @@ void wait_for_interrupt(void)
 #elif defined(__ARM_ARCH_5TE__)
        // XXX: Need to change for Netronome?
         "mcr    p15, 0, r0, c7, c10, 4                  \n\t"
-#elif defined(__ARM_CORTEX__)
-       // TODO: Need to change for Netronome?
-        "mcr    p15, 0, r0, c7, c10, 4                  \n\t"
+#elif defined(__ARM_ARCH_7A__)
+        "wfi                  \n\t"
 #else
           // If no WFI functionality exists on system, just
           // spinning here is okay.
index de75ed9..b3db9a2 100644 (file)
@@ -183,8 +183,8 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc)
 
     uint32_t irq = pic_get_active_irq();
 
-    debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
-          dcb_current ? (dcb_current->disabled ? "disabled": "enabled") : "in kernel");
+   // debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
+   //       dcb_current ? (dcb_current->disabled ? "disabled": "enabled") : "in kernel");
 
     if (dcb_current != NULL) {
         dispatcher_handle_t handle = dcb_current->disp;
index d2c2d4c..73b6965 100644 (file)
@@ -47,6 +47,11 @@ irq_stack:
 irq_stack_top:
          .space 4, 0
 
+fiq_stack:
+        .space EXCEPTION_MODE_STACK_BYTES, 0
+fiq_stack_top:
+         .space 4, 0
+
 undef_stack:
         .space EXCEPTION_MODE_STACK_BYTES, 0
 undef_stack_top:
@@ -107,7 +112,7 @@ $exceptions_load_stacks:
         mov     r0, # ARM_MODE_SVC
         ldr     r1, = svc_stack_top
         bl      set_stack_for_mode
-$expections_install_handlers:
+$exceptions_install_handlers:
         mov     r0, # ARM_EVECTOR_PABT
         adr     r1, pabt_handler
         bl      exceptions_install_handler
@@ -117,15 +122,22 @@ $expections_install_handlers:
         mov     r0, # ARM_EVECTOR_IRQ
         adr     r1, irq_handler
         bl      exceptions_install_handler
+        mov     r0, # ARM_EVECTOR_FIQ
+        adr     r1, fiq_handler
+        bl      exceptions_install_handler
         mov     r0, # ARM_EVECTOR_UNDEF
         adr     r1, undef_handler
         bl      exceptions_install_handler
         mov     r0, # ARM_EVECTOR_SWI
-        adr     r1, swi_handler
+        ldr     r1, =swi_handler
         bl      exceptions_install_handler
 $exceptions_save_got:
         ldr     r0, = got_for_sys_mode
         str     PIC_REGISTER, [r0]
+//$exceptions_unmask_irq:
+//         mrs     r1, cpsr
+//        bic     r1, r1, #0x80
+//        msr     cpsr_c, r1
 $exceptions_init_done:
         ldmfd   sp!, {pc}
 
@@ -142,25 +154,6 @@ set_stack_for_mode:
         msr     cpsr_c, r3              // Switch back
         bx      lr
 
-        //
-        // void exceptions_install_handler(int vector_offset,
-        //                                 void (*handler)(void)
-        //
-/*
-exceptions_install_handler:
-        ldr     r2, = ETABLE_ADDR
-        add     r2, r2, r0
-        sub     r1, r1, r2
-        subs    r1, r1, #8
-        lsr     r1, r1, #2
-        ldr     r0, [r2]
-        mov     r3, #0xff000000
-        and     r0, r0, r3
-        bic     r1, r1, r3
-        orr     r0, r0, r1
-        str     r0, [r2]
-        bx      lr
-*/
                //
                //void exceptions_install_handler(int vector_offset, void (*handler)(void)
                //
@@ -183,7 +176,8 @@ exceptions_install_handler:
 null_handler:
         b       .
 
-        //
+        //#include <barrelfish_kpi/flags_arch.h> // ARM_MODE_MASK
+
         // Macro definition to get pointer to arch specific dispatcher
         //
         // Logical equivalent of C function with same name
@@ -262,11 +256,11 @@ null_handler:
 .endm
 
         //
-        // Macro to enter SYS mode with interrupts disabled.
+        // Macro to enter SVC mode with interrupts disabled.
         // Set up stack and GOT pointer.
         //
 .macro enter_sys scratch
-        mov \scratch, #(CPSR_IF_MASK | ARM_MODE_SYS)
+        mov \scratch, #(CPSR_IF_MASK | ARM_MODE_SVC)
         msr cpsr_c, \scratch
         init_sys_pic_register
         init_sys_stack
@@ -395,6 +389,33 @@ $irq_kernel:
         enter_sys       r3
         b       handle_irq                      // f(save_area)
 
+fiq_handler:
+        stmfd   sp!, {r0-r3}                    // Save for scratch use
+        sub     lr, lr, #4                      // lr = return address
+        mrs     r3, spsr                        // r0 = spsr until save_context
+        ands    r1, r3, #ARM_MODE_PRIV
+        bne     $irq_kernel
+$fiq_user:
+        get_dispatcher_shared_arm r2
+        mov     r1, lr
+        disp_is_disabled r2, r1, r0             // r0 = 1 if disabled, else 0
+        cmp     r0, #0
+        addeq   r0, r2, #OFFSETOF_DISP_ENABLED_AREA
+        addne   r0, r2, #OFFSETOF_DISP_DISABLED_AREA
+        save_context    r0, r3                  // r0 = save area
+        enter_sys       r3
+        mov     lr, #0
+        mov     r11, #0
+        b       handle_irq                      // f(save_area, fault_pc)
+$fiq_kernel:
+        // CPU was in System mode.
+        ldr     r0, =irq_save_area
+        save_context    r0, r3                  // r0 = saved context
+        enter_sys       r3
+        b       handle_irq                      // f(save_area)
+
+
+
         //
         // void swi_handler(void)
         //
index 147d608..509b17a 100644 (file)
 #include <arm_hal.h>
 #include <cpiobin.h>
 #include <getopt/getopt.h>
+#include <romfs_size.h>
 
 
+#define INITRD_BASE                    0x10000000
+#define GEM5_TOTAL_PHYSMEM     0x20000000
+
 //
 // ATAG boot header declarations
 //
@@ -69,7 +73,7 @@ struct atag_videotext {
 struct atag_ramdisk {
     uint32_t flags;             // Bit 0 = load, bit 1 = prompt
     uint32_t bytes;             // Decompressed size
-    uint32_t start;             // Starting block of RAM disk image
+    uint32_t start;                    // Starting block of RAM disk image
 };
 
 struct atag_initrd2 {
@@ -181,10 +185,17 @@ void arch_init(uint32_t     board_id,
 
     exceptions_init();
 
-    //lvaddr_t *foo = 0x0;
-    //elf_file = *foo;
+
 
     ae = atag_find(atag_base, ATAG_MEM);
+
+    //gem5 sets ATAG_MEM to only 512MB, but we are using actually 1024MB,
+    //where the upper 512MB are for the ramdisk
+
+#ifdef __GEM5__
+    ae->u.mem.bytes = GEM5_TOTAL_PHYSMEM;
+#endif
+
     paging_map_memory(0, ae->u.mem.start, ae->u.mem.bytes);
 
     ae = atag_find(atag_base, ATAG_CMDLINE);
@@ -201,43 +212,50 @@ void arch_init(uint32_t     board_id,
         serial_console_init(serial_console_port);
 
         // do not remove/change this printf: needed by regression harness
-        printf("Barrelfish CPU driver starting on ARMv5 Board id 0x%08"PRIx32"\n",
-               board_id);
-        printf("The address of paging_map_kernel_section is %p\n", 
-               paging_map_kernel_section);
+       // printf("Barrelfish CPU driver starting on ARMv5 Board id 0x%08"PRIx32"\n",
+     //          board_id);
+    //    printf("The address of paging_map_kernel_section is %p\n",
+     //          paging_map_kernel_section);
         errval = serial_debug_init(serial_debug_port);
         if (err_is_fail(errval))
         {
             printf("Failed to initialize debug port: %d", serial_debug_port);
         }
 
-        debug(SUBSYS_STARTUP, "alloc_top %08"PRIxLVADDR" %08"PRIxLVADDR"\n",
-               alloc_top, alloc_top - KERNEL_OFFSET);
+        //lvaddr_t *foo = 0x0;
+        //elf_file = *foo;
+
+       // debug(SUBSYS_STARTUP, "alloc_top %08"PRIxLVADDR" %08"PRIxLVADDR"\n",
+      //         alloc_top, alloc_top - KERNEL_OFFSET);
         //debug(SUBSYS_STARTUP, "elf_file %08"PRIxLVADDR"\n", elf_file);
 
         my_core_id = hal_get_cpu_id();
         
         pic_init();
-        pit_init(tick_hz);
+        pit_init(tick_hz, 0);
+        pit_init(tick_hz, 1);
         tsc_init();
 
+
+        //pit_start(0);
+        //while(1) {}
+
         ae = atag_find(atag_base, ATAG_MEM);
                 
         // Add unused physical memory to memory map
 
         phys_mmap_t phys_mmap;
 
-        // Kernel effectively consumes [0...alloc_top]
-        // Add region above alloc_top with care to skip exception vector
-        // page.
-        phys_mmap_add(&phys_mmap,
-                      alloc_top - KERNEL_OFFSET,
-                      ETABLE_ADDR - KERNEL_OFFSET);
+        // Kernel resides in the first 1MB, add everything above to phys_mmap
 
         phys_mmap_add(&phys_mmap,
-                      ETABLE_ADDR - KERNEL_OFFSET + BASE_PAGE_SIZE,
+                                 ARM_L1_SECTION_BYTES,
                       ae->u.mem.start + ae->u.mem.bytes);
 
+       // phys_mmap_add(&phys_mmap,
+       //               ETABLE_ADDR - KERNEL_OFFSET + BASE_PAGE_SIZE,
+       //               ae->u.mem.start + ae->u.mem.bytes);
+
         ae = atag_find(atag_base, ATAG_VIDEOLFB);
         if (NULL != ae)
         {
@@ -248,20 +266,19 @@ void arch_init(uint32_t     board_id,
             assert(!"Not supported");
         }
 
-        ae = atag_find(atag_base, ATAG_INITRD2);
-        if (NULL != ae)
-        {
-            phys_mmap_remove(&phys_mmap,
-                             ae->u.initrd2.start,
-                             ae->u.initrd2.start + ae->u.initrd2.bytes);
+        //ae = atag_find(atag_base, ATAG_INITRD2);
+
+        //Hardcoded because gem5 doesn't set ATAG_INITRD2
+        //Size of image is obtained by header file which is generated during compilation
+        phys_mmap_remove(&phys_mmap,
+                                        INITRD_BASE,
+                                        INITRD_BASE + romfs_cpio_archive_size);
+
+        arm_kernel_startup(&phys_mmap,
+                       INITRD_BASE,
+                       romfs_cpio_archive_size);
+
 
-            arm_kernel_startup(&phys_mmap,
-                               ae->u.initrd2.start,
-                               ae->u.initrd2.bytes);
-        }
-        else {
-            panic("initrd not found\n");
-        }
     }
     else {
         panic("Mis-matched board id: [current %"PRIu32", kernel %"PRIu32"]",
index 43898ff..a15ac95 100644 (file)
@@ -11,7 +11,9 @@
 #include <paging_kernel_arch.h>
 
 #include <dev/pl011_uart_dev.h>
-#include <dev/arm_icp_pic0_dev.h>
+#include <dev/pl130_gic_dev.h>
+#include <dev/sp804_pit_dev.h>
+#include <dev/cortex_a9_pit_dev.h>
 #include <dev/arm_icp_pit_dev.h>
 
 #include <pl011_uart.h>
@@ -20,7 +22,7 @@
 
 uint32_t hal_get_board_id(void)
 {
-    return 0x76D;
+    return 0x8e0;
 }
 
 uint8_t hal_get_cpu_id(void)
@@ -37,50 +39,234 @@ bool hal_cpu_is_bsp(void)
 // Interrupt controller
 //
 
-static arm_icp_pic0_source_un pic_primary_irqs;
-static arm_icp_pic0_t pic;
+#define PIC_BASE       0xE0200000
+#define DIST_OFFSET 0x1000
+#define CPU_OFFSET     0x100
+
+static pl130_gic_t pic;
+static pl130_gic_ICDICTR_t pic_config;
+
+static uint32_t it_num_lines;
+static uint8_t cpu_number;
+static uint8_t sec_extn_implemented;
 
 void pic_init(void)
 {
-    static const uintptr_t PIC_BASE = 0x14000000;
+       lvaddr_t pic_base = paging_map_device(PIC_BASE, 0x100000);
+       pl130_gic_initialize(&pic, (mackerel_addr_t)pic_base + DIST_OFFSET,
+                                               (mackerel_addr_t)pic_base + CPU_OFFSET);
+
+       //read GIC configuration
+       pic_config = pl130_gic_ICDICTR_rd(&pic);
+       it_num_lines = 32*(pl130_gic_ICDICTR_it_lines_num_extract(pic_config) + 1);
+       cpu_number = pl130_gic_ICDICTR_cpu_number_extract(pic_config);
+       sec_extn_implemented = pl130_gic_ICDICTR_TZ_extract(pic_config);
+
+       //pic_disable_all_irqs();
+
+       //config cpu interface (currently only one)
 
-    arm_icp_pic0_source_t sources = {
-        .SOFTINT  = 1, .UARTINT0  = 1, .UARTINT1  = 1, .KBDINT    = 1,
-        .MOUSEINT = 1, .TIMERINT0 = 1, .TIMERINT1 = 1, .TIMERINT2 = 1,
-        .RTCINT   = 1, .LM_LLINT0 = 1, .LM_LLINT1 = 1, .CLCDCINT  = 1,
-        .MMCIINT0 = 1, .MMCIINT1  = 1, .AACIINT   = 1, .CPPLDINT  = 1,
-        .ETH_INT  = 1, .TS_PENINT = 1
-    };
-    pic_primary_irqs.val = sources;
+       //set priority mask of cpu interface, currently set to lowest priority
+       //to accept all interrupts
+       pl130_gic_ICCPMR_wr(&pic, 0xff);
 
-    lvaddr_t pic_base = paging_map_device(PIC_BASE, 0x00100000);
-    arm_icp_pic0_initialize(&pic, (mackerel_addr_t)pic_base);
+       //set binary point to define split of group- and subpriority
+       //currently we allow for 8 subpriorities
+       pl130_gic_ICCBPR_wr(&pic, 0x2);
 
-    pic_disable_all_irqs();
+       //enable interrupt forwarding to processor
+       pl130_gic_ICCICR_wr(&pic, 0x1);
+
+
+       //enable interrupt forwarding from distributor to cpu interface
+       pl130_gic_ICDDCR_wr(&pic, 0x1);
 }
 
-void pic_set_irq_enabled(uint32_t irq, bool en)
+void pic_disable_all_irqs(void)
 {
-    uint32_t m = 1u << irq;
-    if (irq < 32 && (pic_primary_irqs.raw & m) == m) {
-        if (en) {
-            m |= arm_icp_pic0_PIC_IRQ_ENABLESET_rd_raw(&pic);
-            arm_icp_pic0_PIC_IRQ_ENABLESET_wr_raw(&pic, m);
-        }
-        else {
-            arm_icp_pic0_PIC_IRQ_ENABLECLR_wr_raw(&pic, m);
-        }
-    }
-    else {
-        panic("Unknown IRQ source %"PRIu32, irq);
-    }
+    //disable PPI interrupts
+       pl130_gic_PPI_ICDICER_wr(&pic, (uint16_t)0xffff);
+
+
+       //disable SPI interrupts
+       for(uint8_t i=0; i < it_num_lines; i++) {
+               pl130_gic_SPI_ICDICER_wr(&pic, i, (uint32_t)0xffffffff);
+       }
 }
 
-void pic_disable_all_irqs(void)
+
+void pic_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t prio,
+                                                 uint8_t edge_triggered, uint8_t one_to_n)
+{
+       // Set Interrupt Set-Enable Register
+       uint32_t ind = int_id / 32;
+       uint32_t bit_mask = (1U << (int_id % 32));
+       uint32_t regval;
+       if(int_id < 16)
+               return;
+       else if(int_id < 32)
+       {
+               regval = pl130_gic_PPI_ICDISER_rd(&pic);
+               regval |= bit_mask;
+               pl130_gic_PPI_ICDISER_wr(&pic, regval);
+       }
+       else if(int_id < it_num_lines)
+       {
+               regval = pl130_gic_SPI_ICDISER_rd(&pic, ind-1);
+               regval |= bit_mask;
+               pl130_gic_SPI_ICDISER_wr(&pic, ind-1, regval);
+       }
+       else
+               panic("Interrupt ID %"PRIu32" not supported", int_id);
+
+       //Set Interrupt Priority Register
+       ind = int_id/4;
+       if(int_id < 16)
+       {
+               switch(int_id % 4)
+               {
+               case 0:
+                       pl130_gic_SGI_ICDIPR_prio_off0_wrf(&pic, ind, prio);
+                       break;
+               case 1:
+                       pl130_gic_SGI_ICDIPR_prio_off1_wrf(&pic, ind, prio);
+                       break;
+               case 2:
+                       pl130_gic_SGI_ICDIPR_prio_off2_wrf(&pic, ind, prio);
+                       break;
+               case 3:
+                       pl130_gic_SGI_ICDIPR_prio_off3_wrf(&pic, ind, prio);
+                       break;
+               }
+       }
+       else if(int_id < 32)
+       {
+               switch(int_id % 4)
+               {
+               case 0:
+                       pl130_gic_PPI_ICDIPR_prio_off0_wrf(&pic, ind-4, prio);
+                       break;
+               case 1:
+                       pl130_gic_PPI_ICDIPR_prio_off1_wrf(&pic, ind-4, prio);
+                       break;
+               case 2:
+                       pl130_gic_PPI_ICDIPR_prio_off2_wrf(&pic, ind-4, prio);
+                       break;
+               case 3:
+                       pl130_gic_PPI_ICDIPR_prio_off3_wrf(&pic, ind-4, prio);
+                       break;
+               }
+       }
+       else
+       {
+               switch(int_id % 4)
+               {
+               case 0:
+                       pl130_gic_SPI_ICDIPR_prio_off0_wrf(&pic, ind-8, prio);
+                       break;
+               case 1:
+                       pl130_gic_SPI_ICDIPR_prio_off1_wrf(&pic, ind-8, prio);
+                       break;
+               case 2:
+                       pl130_gic_SPI_ICDIPR_prio_off2_wrf(&pic, ind-8, prio);
+                       break;
+               case 3:
+                       pl130_gic_SPI_ICDIPR_prio_off3_wrf(&pic, ind-8, prio);
+                       break;
+               }
+       }
+
+       // Set ICDIPTR Registers to cpu_targets
+       // only SPIs can be targeted manually
+       ind = int_id/4;
+       if(int_id >= 32)
+       {
+               switch(int_id % 4)
+               {
+                       case 0:
+                               pl130_gic_SPI_ICDIPTR_targets_off0_wrf(&pic, ind-8, cpu_targets);
+                               break;
+                       case 1:
+                               pl130_gic_SPI_ICDIPTR_targets_off1_wrf(&pic, ind-8, cpu_targets);
+                               break;
+                       case 2:
+                               pl130_gic_SPI_ICDIPTR_targets_off2_wrf(&pic, ind-8, cpu_targets);
+                               break;
+                       case 3:
+                               pl130_gic_SPI_ICDIPTR_targets_off3_wrf(&pic, ind-8, cpu_targets);
+                               break;
+               }
+       }
+
+
+
+       // Set Interrupt Configuration Register
+       if(int_id >= 32)
+       {
+               ind = int_id/16;
+               uint8_t val = (edge_triggered << 1) | one_to_n;
+               switch(int_id % 16)
+               {
+                       case 0:
+                               pl130_gic_SPI_ICDICR_spi0_wrf(&pic, ind-2, val);
+                               break;
+                       case 1:
+                               pl130_gic_SPI_ICDICR_spi1_wrf(&pic, ind-2, val);
+                               break;
+                       case 2:
+                               pl130_gic_SPI_ICDICR_spi2_wrf(&pic, ind-2, val);
+                               break;
+                       case 3:
+                               pl130_gic_SPI_ICDICR_spi3_wrf(&pic, ind-2, val);
+                               break;
+                       case 4:
+                               pl130_gic_SPI_ICDICR_spi4_wrf(&pic, ind-2, val);
+                               break;
+                       case 5:
+                               pl130_gic_SPI_ICDICR_spi5_wrf(&pic, ind-2, val);
+                               break;
+                       case 6:
+                               pl130_gic_SPI_ICDICR_spi6_wrf(&pic, ind-2, val);
+                               break;
+                       case 7:
+                               pl130_gic_SPI_ICDICR_spi7_wrf(&pic, ind-2, val);
+                               break;
+                       case 8:
+                               pl130_gic_SPI_ICDICR_spi8_wrf(&pic, ind-2, val);
+                               break;
+                       case 9:
+                               pl130_gic_SPI_ICDICR_spi9_wrf(&pic, ind-2, val);
+                               break;
+                       case 10:
+                               pl130_gic_SPI_ICDICR_spi10_wrf(&pic, ind-2, val);
+                               break;
+                       case 11:
+                               pl130_gic_SPI_ICDICR_spi11_wrf(&pic, ind-2, val);
+                               break;
+                       case 12:
+                               pl130_gic_SPI_ICDICR_spi12_wrf(&pic, ind-2, val);
+                               break;
+                       case 13:
+                               pl130_gic_SPI_ICDICR_spi13_wrf(&pic, ind-2, val);
+                               break;
+                       case 14:
+                               pl130_gic_SPI_ICDICR_spi14_wrf(&pic, ind-2, val);
+                               break;
+                       case 15:
+                               pl130_gic_SPI_ICDICR_spi15_wrf(&pic, ind-2, val);
+                               break;
+               }
+       }
+}
+
+uint32_t pic_get_active_irq(void)
 {
-    arm_icp_pic0_PIC_IRQ_ENABLECLR_wr_raw(&pic, pic_primary_irqs.raw);
+       uint32_t regval = pl130_gic_ICCIAR_rd(&pic);
+
+       return regval;
 }
 
+/*
 uint32_t pic_get_active_irq(void)
 {
     uint32_t status = arm_icp_pic0_PIC_IRQ_STATUS_rd_raw(&pic);
@@ -93,21 +279,29 @@ uint32_t pic_get_active_irq(void)
     }
     return ~0ul;
 }
+*/
 
 void pic_ack_irq(uint32_t irq)
 {
-    // From the ARM specs it looks as if just clearing the interrupt at the
-    // peripheral will clear the interrupt. No explicit EOI.
+    pl130_gic_ICCEOIR_rawwr(&pic, irq);
 }
 
 //
 // Kernel timer and tsc
 //
 
-static const uintptr_t PIT_BASE = 0x13000000;
-static const uint32_t  PIT_IRQ  = 6;
+#define PIT_BASE       0xE0000000
+#define PIT0_OFFSET    0x11000
+#define PIT_DIFF       0x1000
+
+#define PIT0_IRQ       36
+#define PIT1_IRQ       37
+
+#define PIT0_ID                0
+#define PIT1_ID                1
 
-static arm_icp_pit_t pit;
+static sp804_pit_t pit0;
+static sp804_pit_t pit1;
 
 static lvaddr_t pit_map_resources(void)
 {
@@ -118,84 +312,143 @@ static lvaddr_t pit_map_resources(void)
     return timer_base;
 }
 
-void pit_init(uint32_t tick_hz)
+void pit_init(uint32_t tick_hz, uint8_t pit_id)
 {
-    // PIT uses timer 1 (hardcoded to 1MHz)
-    arm_icp_pit_LOAD_t load = { .value = 1000000 / tick_hz };
-    arm_icp_pit_CONTROL_t control = {
-        .oneshot = 0, .timer32 = 1, .prescale = arm_icp_pit_none,
-        .int_enable = 0, .mode = arm_icp_pit_reload, .enable = 0
-    };
+    sp804_pit_t *pit;
+       if(pit_id == PIT0_ID)
+               pit = &pit0;
+       else if(pit_id == PIT1_ID)
+               pit = &pit1;
+       else
+               panic("Unsupported PIT ID: %"PRIu32, pit_id);
 
     lvaddr_t timer_base = pit_map_resources();
 
-    arm_icp_pit_initialize(&pit, (mackerel_addr_t)(timer_base + 0x100));
-    arm_icp_pit_LOAD_wr(&pit, load);
-    arm_icp_pit_CONTROL_wr(&pit, control);
+       sp804_pit_initialize(pit, (mackerel_addr_t)(timer_base + PIT0_OFFSET + pit_id*PIT_DIFF));
+
+       // PIT timer (hardcoded to 50MHz)
+    uint32_t load1 = 50000000 / tick_hz;
+    uint32_t load2 = 50000000 / tick_hz;
+
+    sp804_pit_Timer1Load_wr(pit, load1);
+    sp804_pit_Timer2Load_wr(pit, load2);
+
+    //configure timer 1
+    sp804_pit_Timer1Control_one_shot_wrf(pit, 0);
+    sp804_pit_Timer1Control_timer_size_wrf(pit, sp804_pit_size_32bit);
+    sp804_pit_Timer1Control_timer_pre_wrf(pit, sp804_pit_prescale0);
+    sp804_pit_Timer1Control_int_enable_wrf(pit, 0);
+    sp804_pit_Timer1Control_timer_mode_wrf(pit, sp804_pit_periodic);
+    sp804_pit_Timer1Control_timer_en_wrf(pit, 0);
+
+    //configure timer 2
+    sp804_pit_Timer2Control_one_shot_wrf(pit, 0);
+    sp804_pit_Timer2Control_timer_size_wrf(pit, sp804_pit_size_32bit);
+    sp804_pit_Timer2Control_timer_pre_wrf(pit, sp804_pit_prescale0);
+    sp804_pit_Timer2Control_int_enable_wrf(pit, 0);
+    sp804_pit_Timer2Control_timer_mode_wrf(pit, sp804_pit_periodic);
+    sp804_pit_Timer2Control_timer_en_wrf(pit, 0);
+
+    //enable PIT interrupt
+    uint32_t int_id = pit_id ? PIT1_IRQ : PIT0_IRQ;
+    pic_enable_interrupt(int_id, 0x1, 0xf, 0x1, 0);
 
-    pic_set_irq_enabled(PIT_IRQ, 1);
+    //pic_set_irq_enabled(PIT_IRQ, 1);
 }
 
-void pit_start(void)
+void pit_start(uint8_t pit_id)
 {
-    arm_icp_pit_CONTROL_t control = arm_icp_pit_CONTROL_rd(&pit);
-    control.int_enable = 1;
-    control.enable = 1;
-    arm_icp_pit_CONTROL_wr(&pit, control);
+        sp804_pit_t *pit;
+        if(pit_id == PIT0_ID)
+                pit = &pit0;
+        else if(pit_id == PIT1_ID)
+                pit = &pit1;
+        else
+                panic("Unsupported PIT ID: %"PRIu32, pit_id);
+
+
+       sp804_pit_Timer1Control_int_enable_wrf(pit, 1);
+       sp804_pit_Timer1Control_timer_en_wrf(pit, 1);
 }
 
 bool pit_handle_irq(uint32_t irq)
 {
-    if (PIT_IRQ == irq) {
-        arm_icp_pit_INTCLR_wr_raw(&pit, ~0ul);
+       if (PIT0_IRQ == irq)
+       {
+        sp804_pit_Timer1IntClr_wr(&pit0, ~0ul);
+        //TODO: change this in multicore implementation
+        pic_ack_irq(irq);
         return 1;
     }
+       else if(PIT1_IRQ == irq)
+       {
+               sp804_pit_Timer1IntClr_wr(&pit1, ~0ul);
+               //TODO: change this in multicore implementation
+               pic_ack_irq(irq);
+               return 1;
+       }
     else {
         return 0;
     }
 }
 
-void pit_mask_irq(bool masked)
+void pit_mask_irq(bool masked, uint8_t pit_id)
 {
-    arm_icp_pit_CONTROL_t control = arm_icp_pit_CONTROL_rd(&pit);
+        sp804_pit_t *pit;
+        if(pit_id == PIT0_ID)
+                pit = &pit0;
+        else if(pit_id == PIT1_ID)
+                pit = &pit1;
+        else
+                panic("Unsupported PIT ID: %"PRIu32, pit_id);
+
     if (masked) {
-        control.int_enable = 0;
+        sp804_pit_Timer1Control_int_enable_wrf(pit, 0);
     }
     else {
-        control.int_enable = 1;
+        sp804_pit_Timer1Control_int_enable_wrf(pit, 1);
     }
-    arm_icp_pit_CONTROL_wr(&pit, control);
 
     if (masked) {
         // Clear interrupt if pending.
-        pit_handle_irq(PIT_IRQ);
+        pit_handle_irq(pit_id ? PIT1_IRQ : PIT0_IRQ);
     }
 }
 
 //
-// TSC uses timer 0 (assuming 40MHz for QEMU)
+// TSC uses cpu private timer
 //
-static const uint32_t tsc_hz = 40000000;
-static arm_icp_pit_t tsc;
+
+#define TSC_BASE       0xE0200000
+#define TSC_OFFSET     0x600
+
+static cortex_a9_pit_t tsc;
+
+// clock rate hardcoded to 1GHz
+static uint32_t tsc_hz = 1000000000;
 
 void tsc_init(void)
 {
-    arm_icp_pit_LOAD_t load = { .value = ~0ul };
-    arm_icp_pit_CONTROL_t control = {
-        .oneshot = 0, .timer32 = 1, .prescale = arm_icp_pit_none,
-        .int_enable = 0, .mode = arm_icp_pit_reload, .enable = 1
-    };
-    pit_map_resources();
-
-    arm_icp_pit_initialize(&tsc, (mackerel_addr_t)pit_map_resources());
-    arm_icp_pit_LOAD_wr(&tsc, load);
-    arm_icp_pit_CONTROL_wr(&tsc, control);
+    lvaddr_t timer_base = paging_map_device(TSC_BASE, 0x100000);
+
+    cortex_a9_pit_initialize(&tsc, (mackerel_addr_t)timer_base+TSC_OFFSET);
+
+    // write load
+    uint32_t load = ~0ul;
+    cortex_a9_pit_TimerLoad_wr(&tsc, load);
+
+    //configure tsc
+    cortex_a9_pit_TimerControl_prescale_wrf(&tsc, 0);
+    cortex_a9_pit_TimerControl_int_enable_wrf(&tsc, 0);
+    cortex_a9_pit_TimerControl_auto_reload_wrf(&tsc, 1);
+    cortex_a9_pit_TimerControl_timer_enable_wrf(&tsc, 1);
+
 }
 
 uint32_t tsc_read(void)
 {
     // Timers count down so invert it.
-    return ~arm_icp_pit_CURRENT_rd_raw(&tsc);
+    return ~cortex_a9_pit_TimerCounter_rd(&tsc);
 }
 
 uint32_t tsc_get_hz(void)
@@ -210,7 +463,7 @@ uint32_t tsc_get_hz(void)
 #define CONSOLE_PORT 0
 #define DEBUG_PORT   1
 
-#define UART0_VBASE                            0x10009000
+#define UART0_VBASE                            0xE0009000
 #define UART0_SECTION_OFFSET   0x9000
 #define UART_DEVICE_BYTES              0x4c
 #define UART_MAPPING_DIFF              0x1000
@@ -224,7 +477,7 @@ static errval_t serial_init(uint8_t index, uint8_t port_no)
 
         //TODO: only map page and not section
         lvaddr_t base = paging_map_device(UART0_VBASE + port_no * UART_MAPPING_DIFF,
-                                          UART_DEVICE_BYTES); //probably 0x4c is enough
+                                          UART_DEVICE_BYTES);
         pl011_uart_init(&ports[index], base + UART0_SECTION_OFFSET + port_no*UART_MAPPING_DIFF);
         return SYS_ERR_OK;
     }
index 33b98ac..6f62710 100644 (file)
@@ -129,7 +129,7 @@ STATIC_ASSERT_SIZEOF(union l2_entry, 4);
 
 #define BYTES_PER_SECTION       0x100000
 #define BYTES_PER_PAGE          0x1000
-//#define BYTES_PER_SMALL_PAGE    0x400
+#define BYTES_PER_SMALL_PAGE    0x400
 
 // ------------------------------------------------------------------------
 // Utility declarations
@@ -272,7 +272,7 @@ void paging_map_user_pages_l1(lvaddr_t table_base, lvaddr_t va, lpaddr_t pa)
 {
     assert(aligned(table_base, ARM_L1_ALIGN));
     assert(aligned(va, BYTES_PER_SECTION));
-    assert(aligned(pa, BYTES_PER_PAGE));
+    assert(aligned(pa, BYTES_PER_SMALL_PAGE));
 
     union l1_entry e;
 
@@ -304,14 +304,14 @@ void paging_set_l2_entry(uintptr_t* l2e, lpaddr_t addr, uintptr_t flags)
 void paging_context_switch(lpaddr_t ttbr)
 {
     assert(ttbr < MEMORY_OFFSET);
-    assert((ttbr & 0x3fff) == 0);
+    //assert((ttbr & 0x3fff) == 0);
 
     lpaddr_t old_ttbr = cp15_read_ttbr();
     if (ttbr != old_ttbr)
     {
         cp15_write_ttbr(ttbr);
         cp15_invalidate_tlb();
-        cp15_invalidate_i_and_d_caches();
+        //cp15_invalidate_i_and_d_caches();
     }
 }
 
diff --git a/kernel/arch/gem5/startup_arch.c b/kernel/arch/gem5/startup_arch.c
new file mode 100644 (file)
index 0000000..c2dd6fe
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2009, 2010 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <kernel.h>
+#include <dispatch.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <barrelfish_kpi/init.h>
+#include <barrelfish_kpi/syscalls.h>
+#include <elf/elf.h>
+
+#include <arm_hal.h>
+#include <paging_kernel_arch.h>
+#include <exceptions.h>
+#include <cp15.h>
+#include <cpiobin.h>
+#include <init.h>
+#include <phys_mmap.h>
+#include <barrelfish_kpi/paging_arm_v5.h>
+#include <startup.h>
+
+//#include <romfs_size.h>
+
+#define CNODE(cte)              (cte)->cap.u.cnode.cnode
+#define UNUSED(x)               (x) = (x)
+
+#define STARTUP_PROGRESS()      debug(SUBSYS_STARTUP, "%s:%d\n",          \
+                                      __FUNCTION__, __LINE__);
+
+#define BSP_INIT_MODULE_NAME    "gem5/sbin/init"
+
+#define INIT_L1_BYTES           (ARM_L1_MAX_ENTRIES * ARM_L1_BYTES_PER_ENTRY)
+
+#define INIT_L2_PAGES           ((INIT_SPACE_LIMIT - INIT_VBASE) / BASE_PAGE_SIZE)
+#define INIT_L2_BYTES           INIT_L2_PAGES * ARM_L2_BYTES_PER_ENTRY
+
+#define INIT_BOOTINFO_VBASE     INIT_VBASE
+#define INIT_ARGS_VBASE         (INIT_BOOTINFO_VBASE + BOOTINFO_SIZE)
+#define INIT_DISPATCHER_VBASE   (INIT_ARGS_VBASE + ARGS_SIZE)
+
+#define INIT_PERM_RO            (ARM_L2_SMALL_CACHEABLE  | \
+                                 ARM_L2_SMALL_BUFFERABLE | \
+                                 ARM_L2_SMALL_USR_RO)
+
+#define INIT_PERM_RW            (ARM_L2_SMALL_CACHEABLE  | \
+                                 ARM_L2_SMALL_BUFFERABLE | \
+                                 ARM_L2_SMALL_USR_RW)
+
+static phys_mmap_t* g_phys_mmap;        // Physical memory map
+static uintptr_t* init_l1;              // L1 page table for init
+static uintptr_t* init_l2;              // L2 page tables for init
+
+static struct spawn_state spawn_state;
+
+static inline uintptr_t round_up(uintptr_t value, size_t unit)
+{
+    assert(0 == (unit & (unit - 1)));
+    size_t m = unit - 1;
+    return (value + m) & ~m;
+}
+
+static inline uintptr_t round_down(uintptr_t value, size_t unit)
+{
+    assert(0 == (unit & (unit - 1)));
+    size_t m = unit - 1;
+    return value & ~m;
+}
+
+static lpaddr_t alloc_phys_aligned(size_t bytes, size_t align)
+{
+    bytes = round_up(bytes, align);
+    lpaddr_t a = phys_mmap_alloc(g_phys_mmap, bytes, align);
+    assert(0 == (a & (align - 1)));
+    return a;
+}
+
+static lpaddr_t alloc_phys(size_t bytes)
+{
+    return alloc_phys_aligned(bytes, BASE_PAGE_SIZE);
+}
+
+static lvaddr_t alloc_mem_aligned(size_t bytes, size_t align)
+{
+    return local_phys_to_mem(alloc_phys_aligned(bytes, align));
+}
+
+static lvaddr_t alloc_mem(size_t bytes)
+{
+    return local_phys_to_mem(alloc_phys_aligned(bytes, BASE_PAGE_SIZE));
+}
+
+/**
+ * Map frames into init process address space. Init has a contiguous set of
+ * l2 entries so this is straightforward.
+ *
+ * @param l2_table      pointer to init's L2 table.
+ * @param l2_base       virtual address represented by first L2 table entry
+ * @param va_base       virtual address to map.
+ * @param pa_base       physical address to associate with virtual address.
+ * @param bytes        number of bytes to map.
+ * @param l2_flags      ARM L2 small page flags for mapped pages.
+ */
+static void
+spawn_init_map(uintptr_t* l2_table,
+               lvaddr_t   l2_base,
+               lvaddr_t   va_base,
+               lpaddr_t   pa_base,
+               size_t     bytes,
+               uintptr_t  l2_flags)
+{
+    assert(va_base >= l2_base);
+    assert(0 == (va_base & (BASE_PAGE_SIZE - 1)));
+    assert(0 == (pa_base & (BASE_PAGE_SIZE - 1)));
+    assert(0 == (bytes & (BASE_PAGE_SIZE - 1)));
+
+    int bi = (va_base - l2_base) / BASE_PAGE_SIZE;
+    int li = bi + bytes / BASE_PAGE_SIZE;
+
+    while (bi < li)
+    {
+        paging_set_l2_entry(&l2_table[bi], pa_base, l2_flags);
+        pa_base += BASE_PAGE_SIZE;
+        bi++;
+    }
+}
+
+static uint32_t elf_to_l2_flags(uint32_t eflags)
+{
+    switch (eflags & (PF_W|PF_R))
+    {
+      case PF_W|PF_R:
+        return (ARM_L2_SMALL_USR_RW |
+                ARM_L2_SMALL_CACHEABLE |
+                ARM_L2_SMALL_BUFFERABLE);
+      case PF_R:
+        return (ARM_L2_SMALL_USR_RO |
+                ARM_L2_SMALL_CACHEABLE |
+                ARM_L2_SMALL_BUFFERABLE);
+      default:
+        panic("Unknown ELF flags combination.");
+    }
+}
+
+struct startup_l2_info
+{
+    uintptr_t* l2_table;
+    lvaddr_t   l2_base;
+};
+
+static errval_t
+startup_alloc_init(
+    void*      state,
+    genvaddr_t gvbase,
+    size_t     bytes,
+    uint32_t   flags,
+    void**     ret
+    )
+{
+    const struct startup_l2_info* s2i = (const struct startup_l2_info*)state;
+
+    lvaddr_t sv = round_down((lvaddr_t)gvbase, BASE_PAGE_SIZE);
+    size_t   off = (lvaddr_t)gvbase - sv;
+    lvaddr_t lv = round_up((lvaddr_t)gvbase + bytes, BASE_PAGE_SIZE);
+    lpaddr_t pa;
+
+    STARTUP_PROGRESS();
+    if (lv > sv && ((pa = alloc_phys(lv - sv)) != 0))
+    {
+        spawn_init_map(s2i->l2_table, s2i->l2_base, sv,
+                       pa, lv - sv, elf_to_l2_flags(flags));
+        *ret = (void*)(local_phys_to_mem(pa) + off);
+    }
+    else
+    {
+        *ret = 0;
+    }
+    return SYS_ERR_OK;
+}
+
+static void
+load_init_image(
+    struct startup_l2_info* l2i,
+    const uint8_t*          initrd_base,
+    size_t                  initrd_bytes,
+    genvaddr_t*             init_ep,
+    genvaddr_t*             got_base
+    )
+{
+    const uint8_t* elf_base;
+    size_t elf_bytes;
+    int found;
+
+    STARTUP_PROGRESS();
+    *init_ep = *got_base = 0;
+
+    found = cpio_get_file_by_name(initrd_base,
+                                  initrd_bytes,
+                                  BSP_INIT_MODULE_NAME,
+                                  &elf_base, &elf_bytes);
+    if (!found)
+    {
+        panic("Failed to find " BSP_INIT_MODULE_NAME "\n");
+    }
+
+    debug(SUBSYS_STARTUP, "load_init_image %p %08x\n", initrd_base, initrd_bytes);
+
+    errval_t err = elf_load(EM_ARM, startup_alloc_init, l2i,
+                            (lvaddr_t)elf_base, elf_bytes, init_ep);
+    if (err_is_fail(err))
+    {
+        panic("ELF load of " BSP_INIT_MODULE_NAME " failed!\n");
+    }
+
+    // TODO: Fix application linkage so that it's non-PIC.
+    struct Elf32_Shdr* got_shdr =
+        elf32_find_section_header_name((lvaddr_t)elf_base, elf_bytes, ".got");
+    if (got_shdr)
+    {
+        *got_base = got_shdr->sh_addr;
+    }
+}
+
+static void
+create_modules_from_initrd(struct bootinfo* bi,
+                           const uint8_t*   initrd_base,
+                           size_t           initrd_bytes)
+{
+    errval_t err;
+    lvaddr_t mmstrings_base = 0;
+    lvaddr_t mmstrings      = 0;
+
+    // CPIO archive is crafted such that first file is
+    // command-line strings for "modules" - ie menu.lst. The
+    // subsequent file follow in the order they appear in
+    // menu.lst.arm.
+    const uint8_t* data;
+    size_t bytes;
+
+    if (cpio_get_file_by_name(initrd_base, initrd_bytes,
+                              "gem5/menu.lst.modules",
+                              &data, &bytes))
+    {
+        assert(bytes < BASE_PAGE_SIZE);
+
+        mmstrings_base = alloc_mem(BASE_PAGE_SIZE);
+        mmstrings      = mmstrings_base;
+
+        STARTUP_PROGRESS();
+
+        // Create cap for strings area in first slot of modulecn
+        err = caps_create_new(
+                  ObjType_Frame,
+                  mem_to_local_phys(mmstrings_base),
+                  BASE_PAGE_BITS, BASE_PAGE_BITS,
+                  caps_locate_slot(
+                      CNODE(spawn_state.modulecn),
+                      spawn_state.modulecn_slot++)
+                  );
+        assert(err_is_ok(err));
+
+        STARTUP_PROGRESS();
+
+        // Copy strings from file into allocated page
+        memcpy((void*)mmstrings_base, data, bytes);
+        ((char*)mmstrings_base)[bytes] = '\0';
+
+        STARTUP_PROGRESS();
+
+        // Skip first line (corresponds to bootscript in archive)
+        strtok((char*)mmstrings_base, "\r\n");
+
+        STARTUP_PROGRESS();
+
+        assert(bi->regions_length == 0);
+        int ord = 1;
+        const char* name;
+        while ((mmstrings = (lvaddr_t)strtok(NULL, "\r\n")) != 0)
+        {
+            if (!cpio_get_file_by_ordinal(initrd_base, initrd_bytes, ord,
+                                          &name, &data, &bytes))
+            {
+                panic("Failed to find file\n");
+            }
+            ord++;
+
+            debug(SUBSYS_STARTUP,
+                  "Creating caps for \"%s\" (Command-line \"%s\")\n",
+                   name, (char*)mmstrings);
+
+            // Copy file from archive into RAM.
+            // TODO: Give up archive space.
+            size_t   pa_bytes = round_up(bytes, BASE_PAGE_SIZE);
+            lpaddr_t pa       = alloc_phys(pa_bytes);
+            memcpy((void*)local_phys_to_mem(pa), data, bytes);
+
+            struct mem_region* region = &bi->regions[bi->regions_length++];
+            region->mr_type    = RegionType_Module;
+            region->mrmod_slot = spawn_state.modulecn_slot;
+            region->mrmod_size = pa_bytes;
+            region->mrmod_data = mmstrings - mmstrings_base;
+
+            assert((pa & BASE_PAGE_MASK) == 0);
+            assert((pa_bytes & BASE_PAGE_MASK) == 0);
+
+            while (pa_bytes != 0)
+            {
+                assert(spawn_state.modulecn_slot
+                       < (1UL << spawn_state.modulecn->cap.u.cnode.bits));
+                // create as DevFrame cap to avoid zeroing memory contents
+                err = caps_create_new(
+                          ObjType_DevFrame, pa, BASE_PAGE_BITS,
+                          BASE_PAGE_BITS,
+                          caps_locate_slot(
+                              CNODE(spawn_state.modulecn),
+                              spawn_state.modulecn_slot++)
+                          );
+                assert(err_is_ok(err));
+                pa       += BASE_PAGE_SIZE;
+                pa_bytes -= BASE_PAGE_SIZE;
+            }
+        }
+    }
+    else
+    {
+        panic("No command-line file.\n");
+    }
+}
+
+/// Create physical address range or RAM caps to unused physical memory
+static void
+create_phys_caps(struct capability *physaddrcn_cap, struct bootinfo* bi)
+{
+    STARTUP_PROGRESS();
+    int i;
+    for (i = 0; i < g_phys_mmap->region_count; i++)
+    {
+        // TODO: Add RegionType_PhyAddr entries for memory mapped I/O
+        // regions.
+        const phys_region_t* r = &g_phys_mmap->regions[i];
+        if (r->limit - r->start >= BASE_PAGE_SIZE) {
+            create_caps_to_cnode(r->start, r->limit - r->start,
+                                 RegionType_Empty, &spawn_state, bi);
+        }
+    }
+    g_phys_mmap->region_count = 0;
+    STARTUP_PROGRESS();
+}
+
+static void __attribute__ ((noreturn))
+spawn_init(const char*      name,
+           int32_t          kernel_id,
+           const uint8_t*   initrd_base,
+           size_t           initrd_bytes)
+{
+    assert(0 == kernel_id);
+
+    // Create page table for init
+
+    init_l1 =  (uintptr_t*)alloc_mem_aligned(INIT_L1_BYTES, ARM_L1_ALIGN);
+    memset(init_l1, 0, INIT_L1_BYTES);
+
+    init_l2 = (uintptr_t*)alloc_mem_aligned(INIT_L2_BYTES, ARM_L2_ALIGN);
+    memset(init_l2, 0, INIT_L2_BYTES);
+
+    STARTUP_PROGRESS();
+
+    /* Allocate bootinfo */
+    lpaddr_t bootinfo_phys = alloc_phys(BOOTINFO_SIZE);
+    memset((void *)local_phys_to_mem(bootinfo_phys), 0, BOOTINFO_SIZE);
+
+    STARTUP_PROGRESS();
+
+    /* Construct cmdline args */
+    char bootinfochar[16];
+    snprintf(bootinfochar, sizeof(bootinfochar), "%u", INIT_BOOTINFO_VBASE);
+    const char *argv[] = { "init", bootinfochar };
+
+    lvaddr_t paramaddr;
+    struct dcb *init_dcb = spawn_module(&spawn_state, name,
+                                        ARRAY_LENGTH(argv), argv,
+                                        bootinfo_phys, INIT_ARGS_VBASE,
+                                        alloc_phys, &paramaddr);
+
+    STARTUP_PROGRESS();
+
+    struct dispatcher_shared_generic *disp
+        = get_dispatcher_shared_generic(init_dcb->disp);
+    struct dispatcher_shared_arm *disp_arm
+        = get_dispatcher_shared_arm(init_dcb->disp);
+    assert(NULL != disp);
+
+    STARTUP_PROGRESS();
+
+    /* Initialize dispatcher */
+    disp->udisp = INIT_DISPATCHER_VBASE;
+
+    STARTUP_PROGRESS();
+    init_dcb->vspace = mem_to_local_phys((lvaddr_t)init_l1);
+
+    STARTUP_PROGRESS();
+
+    /* Page table setup */
+
+    /* Map pagetables into page CN */
+    int pagecn_pagemap = 0;
+
+    /*
+     * ARM has:
+     *
+     * L1 has 4096 entries (16KB).
+     * L2 Coarse has 256 entries (256 * 4B = 1KB).
+     *
+     * CPU driver currently fakes having 1024 entries in L1 and
+     * L2 with 1024 entries by treating a page as 4 consecutive
+     * L2 tables and mapping this as a unit in L1.
+     */
+    caps_create_new(
+        ObjType_VNode_ARM_l1,
+        mem_to_local_phys((lvaddr_t)init_l1),
+            vnode_objbits(ObjType_VNode_ARM_l1), 0,
+            caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++)
+        );
+
+    STARTUP_PROGRESS();
+
+    // Map L2 into successive slots in pagecn
+    size_t i;
+    for (i = 0; i < INIT_L2_BYTES / BASE_PAGE_SIZE; i++) {
+        size_t objbits_vnode = vnode_objbits(ObjType_VNode_ARM_l2);
+        assert(objbits_vnode == BASE_PAGE_BITS);
+        caps_create_new(
+            ObjType_VNode_ARM_l2,
+            mem_to_local_phys((lvaddr_t)init_l2) + (i << objbits_vnode),
+            objbits_vnode, 0,
+            caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++)
+            );
+    }
+
+    /*
+     * Initialize init page tables - this just wires the L1
+     * entries through to the corresponding L2 entries.
+     */
+    STATIC_ASSERT(0 == (INIT_VBASE % ARM_L1_SECTION_BYTES), "");
+    for (lvaddr_t vaddr = INIT_VBASE; vaddr < INIT_SPACE_LIMIT; vaddr += ARM_L1_SECTION_BYTES)
+    {
+        uintptr_t section = (vaddr - INIT_VBASE) / ARM_L1_SECTION_BYTES;
+        uintptr_t l2_off = section * ARM_L2_TABLE_BYTES;
+        lpaddr_t paddr = mem_to_local_phys((lvaddr_t)init_l2) + l2_off;
+        paging_map_user_pages_l1((lvaddr_t)init_l1, vaddr, paddr);
+    }
+
+    paging_make_good((lvaddr_t)init_l1, INIT_L1_BYTES);
+
+    STARTUP_PROGRESS();
+
+    printf("XXX: Debug print to make Bram's code work\n");
+
+    paging_context_switch(mem_to_local_phys((lvaddr_t)init_l1));
+
+    STARTUP_PROGRESS();
+
+    // Map cmdline arguments in VSpace at ARGS_BASE
+    STATIC_ASSERT(0 == (ARGS_SIZE % BASE_PAGE_SIZE), "");
+
+    STARTUP_PROGRESS();
+
+    spawn_init_map(init_l2, INIT_VBASE, INIT_ARGS_VBASE,
+                   spawn_state.args_page, ARGS_SIZE, INIT_PERM_RW);
+
+    STARTUP_PROGRESS();
+
+    // Map bootinfo
+    spawn_init_map(init_l2, INIT_VBASE, INIT_BOOTINFO_VBASE,
+                   bootinfo_phys, BOOTINFO_SIZE  , INIT_PERM_RW);
+
+    struct startup_l2_info l2_info = { init_l2, INIT_VBASE };
+
+    genvaddr_t init_ep, got_base;
+    load_init_image(&l2_info, initrd_base, initrd_bytes, &init_ep, &got_base);
+
+    // Set startup arguments (argc, argv)
+    disp_arm->enabled_save_area.named.r0   = paramaddr;
+    disp_arm->enabled_save_area.named.cpsr = ARM_MODE_USR | CPSR_F_MASK;
+    disp_arm->enabled_save_area.named.rtls = INIT_DISPATCHER_VBASE;
+    disp_arm->enabled_save_area.named.r10  = got_base;
+
+    disp_arm->got_base = got_base;
+
+    struct bootinfo* bootinfo = (struct bootinfo*)INIT_BOOTINFO_VBASE;
+    bootinfo->regions_length = 0;
+
+    STARTUP_PROGRESS();
+
+    create_modules_from_initrd(bootinfo, initrd_base, initrd_bytes);
+
+    STARTUP_PROGRESS();
+    create_phys_caps(&spawn_state.physaddrcn->cap, bootinfo);
+
+    STARTUP_PROGRESS();
+
+    bootinfo->mem_spawn_core  = ~0;     // Size of kernel if bringing up others
+
+    // Map dispatcher
+    spawn_init_map(init_l2, INIT_VBASE, INIT_DISPATCHER_VBASE,
+                   mem_to_local_phys(init_dcb->disp), DISPATCHER_SIZE,
+                   INIT_PERM_RW);
+
+    STARTUP_PROGRESS();
+
+    // NB libbarrelfish initialization sets up the stack.
+    disp_arm->disabled_save_area.named.pc   = init_ep;
+    disp_arm->disabled_save_area.named.cpsr = ARM_MODE_USR | CPSR_F_MASK;
+    disp_arm->disabled_save_area.named.rtls = INIT_DISPATCHER_VBASE;
+    disp_arm->disabled_save_area.named.r10  = got_base;
+
+#ifdef __XSCALE__
+    cp15_disable_cache();
+#endif
+
+    printf("Kernel ready.\n");
+
+    pit_start(0);
+
+    // On to userland...
+    STARTUP_PROGRESS();
+    dispatch(init_dcb);
+    
+    panic("Not reached.");
+}
+
+void arm_kernel_startup(phys_mmap_t* mmap,
+                        lpaddr_t     initrd_base,
+                        size_t       initrd_bytes)
+{
+    g_phys_mmap = mmap;
+
+    STARTUP_PROGRESS();
+
+
+    const uint8_t* initrd_cpio_base = (uint8_t*)local_phys_to_mem(initrd_base);
+
+   // if (!cpio_archive_valid(initrd_cpio_base, initrd_bytes))
+   // {
+   //             panic("Invalid initrd filesystem\n");
+   // }
+
+    spawn_init(BSP_INIT_MODULE_NAME, 0, initrd_cpio_base, initrd_bytes);
+}
index eb52a2a..2a6a545 100644 (file)
@@ -37,15 +37,18 @@ uint8_t  hal_get_cpu_id(void);
 bool     hal_cpu_is_bsp(void);
 
 void     pic_init(void);
-void     pic_set_irq_enabled(uint32_t irq, bool en);
+//void     pic_set_irq_enabled(uint32_t irq, bool en);
+void    pic_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t prio,
+                                                         uint8_t edge_triggered, uint8_t one_to_n);
 void     pic_disable_all_irqs(void);
 uint32_t pic_get_active_irq(void);
 void     pic_ack_irq(uint32_t irq);
 
-void     pit_init(uint32_t tick_hz);
-void     pit_start(void);
+//void     pit_init(uint32_t tick_hz);
+void    pit_init(uint32_t tick_hz, uint8_t pit_id);
+void     pit_start(uint8_t pit_id);
 bool     pit_handle_irq(uint32_t irq);
-void     pit_mask_irq(bool masked);
+void     pit_mask_irq(bool masked, uint8_t pit_id);
 
 void     tsc_init(void);
 uint32_t tsc_read(void);
index 588205d..1d44978 100644 (file)
@@ -19,8 +19,9 @@
 #define ARM_EVECTOR_FIQ   0x1c
 
 #define CACHE_LINE_BYTES 32
-#define ETABLE_ADDR      0xffff0000
-#define JUMP_TABLE_OFFSET      0x100
+#define ETABLE_ADDR                    0xffff0000
+#define ETABLE_SECTION_OFFSET  0xf000
+#define JUMP_TABLE_OFFSET              0x100
 
 #if !defined(__ASSEMBLER__)
 
index 5273777..c776fd5 100644 (file)
@@ -78,7 +78,7 @@ void paging_map_memory(uintptr_t ttbase, lpaddr_t paddr, size_t bytes);
 
 #define ARM_L2_SMALL_CACHEABLE          0x008
 #define ARM_L2_SMALL_BUFFERABLE         0x004
-#define ARM_L2_SMALL_USR_RO             0xaa0
-#define ARM_L2_SMALL_USR_RW             0xff0
+#define ARM_L2_SMALL_USR_RO             0x20
+#define ARM_L2_SMALL_USR_RW             0x30
 
 #endif // KERNEL_ARCH_ARM_PAGING_H
index 07c87ac..db49c00 100644 (file)
@@ -22,6 +22,7 @@
 #include <if/monitor_blocking_rpcclient_defs.h>
 #include <barrelfish/monitor_client.h>
 #include <trace/trace.h>
+#include <stdio.h>
 
 /// Root CNode
 struct cnoderef cnode_root = {
@@ -285,6 +286,8 @@ errval_t cap_delete(struct capref cap)
     if (err == SYS_ERR_RETRY_THROUGH_MONITOR) {
         return cap_delete_remote(caddr, vbits);
     } else {
+       if(err)
+               printf("invoke_cnode_delete in capabilities.c failed\n");
         return err;
     }
 }
@@ -323,6 +326,7 @@ errval_t cap_destroy(struct capref cap)
     errval_t err;
     err = cap_delete(cap);
     if (err_is_fail(err)) {
+       printf("cap_delete in capabilities.c failed!\n");
         return err;
     }
 
@@ -575,6 +579,7 @@ errval_t frame_create(struct capref dest, size_t bytes, size_t *retbytes)
 
     err = cap_destroy(ram);
     if (err_is_fail(err)) {
+       printf("cap_destroy in capabilities.c failed!\n");
         return err;
     }
 
index abfa3b0..6d959f1 100644 (file)
@@ -976,6 +976,8 @@ static bool init_domain_global; // XXX
 
 /// Thread created on static stack in new domain that runs init code
 static int bootstrap_thread(struct spawn_domain_params *params)
+//int bootstrap_thread(struct spawn_domain_params *params);
+//int bootstrap_thread(struct spawn_domain_params *params)
 {
     errval_t err;
 
index 7ee53e0..5e6921b 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <barrelfish/barrelfish.h>
 #include "vspace_internal.h"
+#include <stdio.h>
 
 /**
  * \brief Map the memory object into a region
@@ -41,12 +42,14 @@ static errval_t map_region(struct memobj *memobj, struct vregion *vregion)
         void *buf;
         err = vspace_pinned_alloc(&buf, VREGION_LIST);
         if (err_is_fail(err)) {
+               printf("vspace pinned alloc fail!\n");
             return err_push(err, LIB_ERR_VSPACE_PINNED_ALLOC);
         }
         slab_grow(&anon->vregion_slab, buf,
                   VSPACE_PINNED_UNIT * sizeof(struct vregion_list));
         data = slab_alloc(&anon->vregion_slab);
         if (!data) {
+               printf("slab alloc fail!\n");
             return LIB_ERR_SLAB_ALLOC_FAIL;
         }
     }
index ccdb7a8..e06d07a 100644 (file)
@@ -29,6 +29,8 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/core_state_arch.h>
 #include "vspace_internal.h"
+#include <stdio.h>
+
 
 /**
  * \brief Initialize the pinned region
@@ -102,6 +104,7 @@ errval_t vspace_pinned_alloc(void **retbuf, enum slab_type slab_type)
         err = frame_alloc(&frame, BASE_PAGE_SIZE, NULL);
         if (err_is_fail(err)) {
             thread_mutex_unlock(&state->mutex);
+               printf("frame alloc fail!\n");
             return err_push(err, LIB_ERR_FRAME_ALLOC);
         }
         err = state->memobj.m.f.fill((struct memobj*)&state->memobj,
@@ -109,6 +112,7 @@ errval_t vspace_pinned_alloc(void **retbuf, enum slab_type slab_type)
                                      BASE_PAGE_SIZE);
         if (err_is_fail(err)) {
             thread_mutex_unlock(&state->mutex);
+               printf("memobj fill fail!\n");
             return err_push(err, LIB_ERR_MEMOBJ_FILL);
         }
 
@@ -125,6 +129,7 @@ errval_t vspace_pinned_alloc(void **retbuf, enum slab_type slab_type)
     thread_mutex_unlock(&state->mutex);
 
     if (buf == NULL) {
+       printf("slab alloc fail!\n");
         return LIB_ERR_SLAB_ALLOC_FAIL;
     } else {
         *retbuf = buf;
index 5634ba5..8b2af59 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <barrelfish/barrelfish.h>
 #include "vspace_internal.h"
+#include <stdio.h>
 
 /**
  * \brief Setup a new vregion with alignment constraints in an address space
@@ -40,6 +41,7 @@ errval_t vregion_map_aligned(struct vregion *vregion, struct vspace* vspace,
     genvaddr_t address;
     err = pmap->f.determine_addr(pmap, memobj, alignment, &address);
     if (err_is_fail(err)) {
+       printf("pmap fail!\n");
         return err_push(err, LIB_ERR_PMAP_DETERMINE_ADDR);
     }
 
@@ -54,12 +56,14 @@ errval_t vregion_map_aligned(struct vregion *vregion, struct vspace* vspace,
     // Add to the vspace
     err = vspace_add_vregion(vspace, vregion);
     if (err_is_fail(err)) {
+       printf("vspace add vregion fail!\n");
         return err_push(err, LIB_ERR_VSPACE_ADD_REGION);
     }
 
     // Add to memobj
     err = memobj->f.map_region(memobj, vregion);
     if (err_is_fail(err)) {
+       printf("map region fail!\n");
         return err_push(err, LIB_ERR_MEMOBJ_MAP_REGION);
     }
 
index 968c15f..d11465e 100644 (file)
@@ -23,6 +23,7 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/core_state.h>
 #include "vspace_internal.h"
+#include <stdio.h>
 
 /**
  * \brief Initialize the current vspace structure