diff --git a/include/minix/board.h b/include/minix/board.h index 143859e1e..d3e43ef66 100644 --- a/include/minix/board.h +++ b/include/minix/board.h @@ -176,6 +176,19 @@ get_board_id_by_short_name(const char *name) return 0; } +/* returns 0 if no board was found that match that id */ +static int +get_board_id_by_name(const char *name) +{ + int x; + for (x = 0; x < sizeof(board_id2name) / sizeof(board_id2name[0]); x++) { + if (strncmp(name, board_id2name[x].name, 40) == 0) { + return board_id2name[x].id; + } + } + return 0; +} + /* convert a board id to a board name to use later returns NULL if no board was found that match that id */ static const char * diff --git a/include/minix/padconf.h b/include/minix/padconf.h index ba09a1c99..ee5d51995 100644 --- a/include/minix/padconf.h +++ b/include/minix/padconf.h @@ -5,15 +5,15 @@ * The base must be page aligned, so we round down and the kernel adds the * offset. The size must be a multiple of ARM_PAGE_SIZE, so we round up to 4KB. */ -#ifdef AM335X -#define PADCONF_REGISTERS_BASE 0x44E10000 -#define PADCONF_REGISTERS_OFFSET 0x0000 -#define PADCONF_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */ -#elif DM37XX -#define PADCONF_REGISTERS_BASE 0x48002000 -#define PADCONF_REGISTERS_OFFSET 0x0030 -#define PADCONF_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */ -#endif +//#ifdef AM335X +#define PADCONF_AM335X_REGISTERS_BASE 0x44E10000 +#define PADCONF_AM335X_REGISTERS_OFFSET 0x0000 +#define PADCONF_AM335X_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */ +//#elif DM37XX +#define PADCONF_DM37XX_REGISTERS_BASE 0x48002000 +#define PADCONF_DM37XX_REGISTERS_OFFSET 0x0030 +#define PADCONF_DM37XX_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */ +//#endif #define PADCONF_MUXMODE(X) (X & 0x7) /* mode 1 til 7 [2:0] */ #define PADCONF_PULL_MODE(X) ((X & 0x3) << 3) /* 2 bits[4:3] */ diff --git a/kernel/arch/earm/arch_clock.c b/kernel/arch/earm/arch_clock.c index 754c6ccde..b045ca75c 100644 --- a/kernel/arch/earm/arch_clock.c +++ b/kernel/arch/earm/arch_clock.c @@ -7,6 +7,7 @@ #include "kernel/proc.h" #include "kernel/interrupt.h" #include +#include #include "kernel/glo.h" #include "kernel/profile.h" @@ -28,12 +29,14 @@ int init_local_timer(unsigned freq) { omap3_timer_init(freq); omap3_frclock_init(); -#ifdef DM37XX - tsc_per_ms[0] = 16250; -#endif -#ifdef AM335X - tsc_per_ms[0] = 15000; -#endif + + if (BOARD_IS_BBXM(machine.board_id)){ + tsc_per_ms[0] = 16250; + } else if (BOARD_IS_BB(machine.board_id)){ + tsc_per_ms[0] = 15000; + } else { + panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine.board_id); + }; return 0; } diff --git a/kernel/arch/earm/do_padconf.c b/kernel/arch/earm/do_padconf.c index 544fa49bd..e1087ec5f 100644 --- a/kernel/arch/earm/do_padconf.c +++ b/kernel/arch/earm/do_padconf.c @@ -4,9 +4,9 @@ #if USE_PADCONF /* get arch specific arch_padconf_set() */ -#if defined(AM335X) || defined(DM37XX) +//#if defined(AM335X) || defined(DM37XX) #include "omap_padconf.h" -#endif +//#endif /*===========================================================================* * do_padconf * diff --git a/kernel/arch/earm/include/cpufunc.h b/kernel/arch/earm/include/cpufunc.h index c5606dbe4..318c992c5 100644 --- a/kernel/arch/earm/include/cpufunc.h +++ b/kernel/arch/earm/include/cpufunc.h @@ -410,6 +410,17 @@ static inline void write_vbar(u32_t vbar) isb(); } +#define MIDR_IMPLEMENTER_SHIFT (24) +#define MIDR_IMPLEMENTER_MASK (0xFF << MIDR_IMPLEMENTER_SHIFT) +#define MIDR_MAJOR_REV_SHIFT (20) +#define MIDR_MAJOR_REV_MASK (0xF << MIDR_MAJOR_REV_SHIFT) +#define MIDR_ARCH_CODE_SHIFT (16) +#define MIDR_ARCH_CODE_MASK (0xF << MIDR_ARCH_CODE_SHIFT) +#define MIDR_PART_NUMBER_SHIFT (4) +#define MIDR_PART_NUMBER_MASK (0xFFF << MIDR_PART_NUMBER_SHIFT) +#define MIDR_MINOR_REV_SHIFT (0) +#define MIDR_MINOR_REV_MASK (0xF << MIDR_MINOR_REV_SHIFT) + /* Read the Main ID Register */ static inline u32_t read_midr() { diff --git a/kernel/arch/earm/memory.c b/kernel/arch/earm/memory.c index 4da9f118b..faa48ce51 100644 --- a/kernel/arch/earm/memory.c +++ b/kernel/arch/earm/memory.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -737,12 +738,13 @@ int arch_phys_map(const int index, } else if (index == frclock_index) { -#ifdef DM37XX - *addr = OMAP3_GPTIMER10_BASE; -#endif -#ifdef AM335X - *addr = AM335X_DMTIMER7_BASE; -#endif + if (BOARD_IS_BBXM(machine.board_id)){ + *addr = OMAP3_GPTIMER10_BASE; + } else if (BOARD_IS_BB(machine.board_id)){ + *addr = AM335X_DMTIMER7_BASE; + } else { + panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine.board_id); + }; *len = ARM_PAGE_SIZE; *flags = VMMF_UNCACHED | VMMF_USER; return OK; @@ -792,15 +794,15 @@ int arch_phys_map_reply(const int index, const vir_bytes addr) return OK; } else if (index == frclock_index) { -#if defined(DM37XX) - minix_kerninfo.minix_frclock_tcrr = addr + OMAP3_TIMER_TCRR; - minix_kerninfo.minix_arm_frclock_hz = 1625000; -#elif defined(AM335X) - minix_kerninfo.minix_frclock_tcrr = addr + AM335X_TIMER_TCRR; - minix_kerninfo.minix_arm_frclock_hz = 1500000; -#else -#error ARM: plese define either AM335X or DM37XX. -#endif + if (BOARD_IS_BBXM(machine.board_id)){ + minix_kerninfo.minix_frclock_tcrr = addr + OMAP3_TIMER_TCRR; + minix_kerninfo.minix_arm_frclock_hz = 1625000; + } else if (BOARD_IS_BB(machine.board_id)){ + minix_kerninfo.minix_frclock_tcrr = addr + AM335X_TIMER_TCRR; + minix_kerninfo.minix_arm_frclock_hz = 1500000; + } else { + panic("memory setup errot machine (0x%08x) is unhandled\n",machine.board_id); + }; return OK; } diff --git a/kernel/arch/earm/omap_intr.c b/kernel/arch/earm/omap_intr.c index a99b8c6a1..7dac821a6 100644 --- a/kernel/arch/earm/omap_intr.c +++ b/kernel/arch/earm/omap_intr.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "kernel/kernel.h" @@ -21,12 +22,13 @@ static kern_phys_map intr_phys_map; int intr_init(const int auto_eoi) { -#ifdef DM37XX - omap_intr.base = OMAP3_DM37XX_INTR_BASE; -#endif -#ifdef AM335X - omap_intr.base = OMAP3_AM335X_INTR_BASE; -#endif + if (BOARD_IS_BBXM(machine.board_id)){ + omap_intr.base = OMAP3_DM37XX_INTR_BASE; + } else if (BOARD_IS_BB(machine.board_id)){ + omap_intr.base = OMAP3_AM335X_INTR_BASE; + } else { + panic("Can not do the interrupt setup. machine (0x%08x) is unknown\n",machine.board_id); + }; omap_intr.size = 0x1000 ; /* 4K */ kern_phys_map_ptr(omap_intr.base,omap_intr.size, diff --git a/kernel/arch/earm/omap_intr.h b/kernel/arch/earm/omap_intr.h index 32e7eaca7..60c53aefb 100644 --- a/kernel/arch/earm/omap_intr.h +++ b/kernel/arch/earm/omap_intr.h @@ -1,16 +1,16 @@ #ifndef _OMAP_INTR_H #define _OMAP_INTR_H -#ifdef DM37XX +//#ifdef DM37XX /* Interrupt controller memory map */ #define OMAP3_DM37XX_INTR_BASE 0x48200000 /* INTCPS physical address */ -#endif /* DM37XX */ +//#endif /* DM37XX */ -#ifdef AM335X +//#ifdef AM335X /* Interrupt controller memory map */ #define OMAP3_AM335X_INTR_BASE 0x48200000 /* INTCPS physical address */ -#endif /* AM335X */ +//#endif /* AM335X */ /* Interrupt controller registers */ #define OMAP3_INTCPS_REVISION 0x000 /* IP revision code */ @@ -59,7 +59,7 @@ -#ifdef DM37XX +//#ifdef DM37XX #define OMAP3_DM337X_NR_IRQ_VECTORS 96 @@ -135,9 +135,9 @@ #define OMAP3_HSUSB_DMA_IRQ 93 /* High-speed USB OTG DMA */ #define OMAP3_MMC3_IRQ 94 /* MMC/SD module 3 */ -#endif +//#endif -#ifdef AM335X +//#ifdef AM335X #define AM335X_INT_EMUINT 0 /* Emulation interrupt (EMUICINTR) */ #define AM335X_INT_COMMTX 1 /* CortexA8 COMMTX */ #define AM335X_INT_COMMRX 2 /* CortexA8 COMMRX */ @@ -239,7 +239,7 @@ #define AM335X_INT_SPI1INT 125 /* McSPI1 SINTERRUPTN */ #define OMAP3_AM335X_NR_IRQ_VECTORS 125 -#endif +//#endif #ifndef __ASSEMBLY__ diff --git a/kernel/arch/earm/omap_padconf.c b/kernel/arch/earm/omap_padconf.c index 3b6638a8b..2c8f52246 100644 --- a/kernel/arch/earm/omap_padconf.c +++ b/kernel/arch/earm/omap_padconf.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -18,25 +19,43 @@ struct omap_padconf vir_bytes base; vir_bytes offset; vir_bytes size; + unsigned int board_filter_value; + unsigned int board_filter_mask; }; -static struct omap_padconf omap_padconf = { - .base = PADCONF_REGISTERS_BASE, - .offset = PADCONF_REGISTERS_OFFSET, - .size = PADCONF_REGISTERS_SIZE + +struct omap_padconf omap_padconfs[] = { + { + .base = PADCONF_DM37XX_REGISTERS_BASE, + .offset = PADCONF_DM37XX_REGISTERS_OFFSET, + .size = PADCONF_DM37XX_REGISTERS_SIZE, + .board_filter_value = BOARD_FILTER_BBXM_VALUE, + .board_filter_mask = BOARD_FILTER_BBXM_MASK, + }, + { + .base = PADCONF_AM335X_REGISTERS_BASE, + .offset = PADCONF_AM335X_REGISTERS_OFFSET, + .size = PADCONF_AM335X_REGISTERS_SIZE, + .board_filter_value = BOARD_FILTER_BB_VALUE, + .board_filter_mask = BOARD_FILTER_BB_MASK, + }, }; +/* initialized in init */ +static struct omap_padconf *omap_padconf; + + static kern_phys_map padconf_phys_map; int arch_padconf_set(u32_t padconf, u32_t mask, u32_t value) { /* check that the value will be inside the padconf memory range */ - if (padconf >= (PADCONF_REGISTERS_SIZE - PADCONF_REGISTERS_OFFSET)) { + if (padconf >= (omap_padconf->size - omap_padconf->offset)) { return EINVAL; /* outside of valid range */ } - set32(padconf + omap_padconf.base + omap_padconf.offset, mask, value); + set32(padconf + omap_padconf->base + omap_padconf->offset, mask, value); return OK; } @@ -44,8 +63,19 @@ arch_padconf_set(u32_t padconf, u32_t mask, u32_t value) void arch_padconf_init(void) { - kern_phys_map_ptr(omap_padconf.base, omap_padconf.size, - &padconf_phys_map, (vir_bytes) &omap_padconf.base); + int x; + omap_padconf = NULL; + /* find the correct padconf */ + for (x =0 ; x < sizeof(omap_padconfs)/sizeof(omap_padconfs[0]) ; x++){ + if ( (omap_padconfs[x].board_filter_mask & machine.board_id) == omap_padconfs[x].board_filter_value){ + omap_padconf = &omap_padconfs[x]; + break; + } + } + assert(omap_padconf); + + kern_phys_map_ptr(omap_padconf->base, omap_padconf->size, + &padconf_phys_map, (vir_bytes) &omap_padconf->base); return; } diff --git a/kernel/arch/earm/omap_reset.c b/kernel/arch/earm/omap_reset.c index 29b059c97..5715679a8 100644 --- a/kernel/arch/earm/omap_reset.c +++ b/kernel/arch/earm/omap_reset.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "kernel/kernel.h" @@ -11,21 +12,17 @@ #include "arch_proto.h" #include "omap_reset.h" -#ifdef AM335X -#define CM_BASE 0x44E00000 -#define CM_SIZE 0x1000 -#define PRM_DEVICE_OFFSET 0xf00 -#define PRM_RSTCTRL_REG 0x00 -#define RST_GLOBAL_WARM_SW_BIT 0 -#elif DM37XX -#define CM_BASE 0x48307000 -#define CM_SIZE 0x1000 -#define PRM_RSTCTRL_REG 0x250 -#define RST_DPLL3_BIT 2 -#else -#define CM_BASE 0x00000000 -#define CM_SIZE 0x1000 -#endif +#define AM335X_CM_BASE 0x44E00000 +#define AM335X_CM_SIZE 0x1000 + +#define AM335X_PRM_DEVICE_OFFSET 0xf00 +#define AM335X_PRM_RSTCTRL_REG 0x00 +#define AM335X_RST_GLOBAL_WARM_SW_BIT 0 + +#define DM37XX_CM_BASE 0x48307000 +#define DM37XX_CM_SIZE 0x1000 +#define DM37XX_PRM_RSTCTRL_REG 0x250 +#define DM37XX_RST_DPLL3_BIT 2 struct omap_reset { @@ -33,28 +30,32 @@ struct omap_reset vir_bytes size; }; -static struct omap_reset omap_reset = { - .base = CM_BASE, - .size = CM_SIZE -}; +static struct omap_reset omap_reset; static kern_phys_map reset_phys_map; void omap3_reset_init(void) { -#if defined(AM335X) || defined(DM37XX) + + if(BOARD_IS_BBXM(machine.board_id)){ + omap_reset.base = DM37XX_CM_BASE; + omap_reset.size = DM37XX_CM_SIZE; + } else if(BOARD_IS_BB(machine.board_id)){ + omap_reset.base = AM335X_CM_BASE; + omap_reset.size = AM335X_CM_SIZE; + } + kern_phys_map_ptr(omap_reset.base, omap_reset.size, &reset_phys_map, (vir_bytes) &omap_reset.base); -#endif /* AM335X || DM37XX */ } void omap3_reset(void) { -#ifdef AM335X - mmio_set((omap_reset.base + PRM_DEVICE_OFFSET + PRM_RSTCTRL_REG), (1 << RST_GLOBAL_WARM_SW_BIT)); -#elif DM37XX - mmio_set((omap_reset.base + PRM_RSTCTRL_REG), (1 << RST_DPLL3_BIT)); -#endif + if(BOARD_IS_BBXM(machine.board_id)){ + mmio_set((omap_reset.base + DM37XX_PRM_RSTCTRL_REG), (1 << DM37XX_RST_DPLL3_BIT)); + } else if(BOARD_IS_BB(machine.board_id)){ + mmio_set((omap_reset.base + AM335X_PRM_DEVICE_OFFSET + AM335X_PRM_RSTCTRL_REG), (1 << AM335X_RST_GLOBAL_WARM_SW_BIT)); + } } diff --git a/kernel/arch/earm/omap_serial.c b/kernel/arch/earm/omap_serial.c index 3d182ef71..69235f3b4 100644 --- a/kernel/arch/earm/omap_serial.c +++ b/kernel/arch/earm/omap_serial.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "kernel/kernel.h" @@ -41,13 +42,13 @@ static kern_phys_map serial_phys_map; * The serial driver also gets used in the "pre_init" stage before the kernel is loaded * in high memory so keep in mind there are two copies of this code in the kernel. */ -void omap3_ser_init(){ -#ifdef DM37XX +void omap3_ser_init() +{ + if(BOARD_IS_BBXM(machine.board_id)){ omap_serial.base = OMAP3_DM37XX_DEBUG_UART_BASE; -#endif -#ifdef AM335X + } else if (BOARD_IS_BB(machine.board_id)){ omap_serial.base = OMAP3_AM335X_DEBUG_UART_BASE; -#endif + } omap_serial.size = 0x1000 ; /* 4k */ diff --git a/kernel/arch/earm/omap_timer.c b/kernel/arch/earm/omap_timer.c index cb2c2a1ec..ec3e42a28 100644 --- a/kernel/arch/earm/omap_timer.c +++ b/kernel/arch/earm/omap_timer.c @@ -2,6 +2,7 @@ #include "kernel/clock.h" #include #include +#include #include #include #include @@ -157,37 +158,37 @@ void omap3_frclock_init(void) &fr_timer_phys_map, (vir_bytes) &fr_timer.base); /* enable the clock */ -#ifdef AM335X - /* Disable the module and wait for the module to be disabled */ - set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED); - while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE); + if(BOARD_IS_BBXM(machine.board_id)){ + /* Stop timer */ + mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); - set32(CLKSEL_TIMER7_CLK,CLKSEL_TIMER7_CLK_SEL_MASK, CLKSEL_TIMER7_CLK_SEL_SEL2); - while( (read32(CLKSEL_TIMER7_CLK) & CLKSEL_TIMER7_CLK_SEL_MASK) != CLKSEL_TIMER7_CLK_SEL_SEL2); + /* Use functional clock source for GPTIMER10 */ + mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10); - /* enable the module and wait for the module to be ready */ - set32(CM_PER_TIMER7_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE); - while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC); -#endif + /* Scale timer down to 13/8 = 1.625 Mhz to roughly get microsecond ticks */ + /* The scale is computed as 2^(PTV+1). So if PTV == 2, we get 2^3 = 8. + */ + mmio_set(fr_timer.base + fr_timer.regs->TCLR, (2 << OMAP3_TCLR_PTV)); + } else if(BOARD_IS_BB(machine.board_id)){ + /* Disable the module and wait for the module to be disabled */ + set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED); + while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE); - /* Stop timer */ - mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); + set32(CLKSEL_TIMER7_CLK,CLKSEL_TIMER7_CLK_SEL_MASK, CLKSEL_TIMER7_CLK_SEL_SEL2); + while( (read32(CLKSEL_TIMER7_CLK) & CLKSEL_TIMER7_CLK_SEL_MASK) != CLKSEL_TIMER7_CLK_SEL_SEL2); + + /* enable the module and wait for the module to be ready */ + set32(CM_PER_TIMER7_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE); + while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC); + + /* Stop timer */ + mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); + + /* 24Mhz / 16 = 1.5 Mhz */ + mmio_set(fr_timer.base + fr_timer.regs->TCLR, (3 << OMAP3_TCLR_PTV)); + } -#ifdef DM37XX - /* Use functional clock source for GPTIMER10 */ - mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10); -#endif -#ifdef DM37XX - /* Scale timer down to 13/8 = 1.625 Mhz to roughly get microsecond ticks */ - /* The scale is computed as 2^(PTV+1). So if PTV == 2, we get 2^3 = 8. - */ - mmio_set(fr_timer.base + fr_timer.regs->TCLR, (2 << OMAP3_TCLR_PTV)); -#endif -#ifdef AM335X - /* 24Mhz / 16 = 1.5 Mhz */ - mmio_set(fr_timer.base + fr_timer.regs->TCLR, (3 << OMAP3_TCLR_PTV)); -#endif /* Start and auto-reload at 0 */ mmio_write(fr_timer.base + fr_timer.regs->TLDR, 0x0); @@ -230,11 +231,15 @@ void omap3_timer_init(unsigned freq) /* enable the module and wait for the module to be ready */ set32(CM_WKUP_TIMER1_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE); while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC); + + /* Stop timer */ + mmio_clear(timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); #endif + +#ifdef DM37XX /* Stop timer */ mmio_clear(timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); -#ifdef DM37XX /* Use 32 KHz clock source for GPTIMER1 */ mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1); #endif diff --git a/kernel/arch/earm/omap_timer_registers.h b/kernel/arch/earm/omap_timer_registers.h index 42e55b190..014ad6ef6 100644 --- a/kernel/arch/earm/omap_timer_registers.h +++ b/kernel/arch/earm/omap_timer_registers.h @@ -1,7 +1,7 @@ #ifndef _OMAP_TIMER_REGISTERS_H #define _OMAP_TIMER_REGISTERS_H -#ifdef DM37XX +//#ifdef DM37XX /* General-purpose timer register map */ #define OMAP3_GPTIMER1_BASE 0x48318000 /* GPTIMER1 physical address */ @@ -16,7 +16,7 @@ #define OMAP3_GPTIMER10_BASE 0x48086000 /* GPTIMER10 physical address */ #define OMAP3_GPTIMER11_BASE 0x48088000 /* GPTIMER11 physical address */ -#endif /* DM37XX */ +//#endif /* DM37XX */ /* General-purpose timer registers */ #define OMAP3_TIMER_TIDR 0x000 /* IP revision code */ @@ -40,7 +40,7 @@ #define OMAP3_TIMER_TOCR 0x054 /* Masks tick interrupt */ #define OMAP3_TIMER_TOWR 0x058 /* Number of masked overflow interrupts */ -#ifdef AM335X +//#ifdef AM335X #define AM335X_DMTIMER0_BASE 0x44E05000 /* DMTimer0 Registers */ #define AM335X_DMTIMER1_1MS_BASE 0x44E31000 /* DMTimer1 1ms Registers (Accurate 1ms timer) */ #define AM335X_DMTIMER2_BASE 0x48040000 /* DMTimer2 Registers */ @@ -68,7 +68,7 @@ #define AM335X_TIMER_TSICR 0x054 /* Control posted mode and functional SW reset */ #define AM335X_TIMER_TCAR2 0x058 /* Second captured value of counter register */ -#endif +//#endif /* Interrupt status register fields */ @@ -88,7 +88,7 @@ #define OMAP3_TCLR_PTV 2 #define OMAP3_TCLR_OVF_TRG (1 << 10) /* Overflow trigger */ -#ifdef DM37XX +//#ifdef DM37XX #define OMAP3_CM_CLKSEL_GFX 0x48004b40 #define OMAP3_CM_CLKEN_PLL 0x48004d00 @@ -98,9 +98,9 @@ #define OMAP3_CM_CLKSEL_PER 0x48005040 #define OMAP3_CM_CLKSEL_WKUP 0x48004c40 /* GPT1 source clock selection */ -#endif /* DM37XX */ +//#endif /* DM37XX */ -#ifdef AM335X +//#ifdef AM335X #define CM_MODULEMODE_MASK (0x3 << 0) #define CM_MODULEMODE_ENABLE (0x2 << 0) @@ -146,7 +146,7 @@ -#endif /* AM335X */ +//#endif /* AM335X */ #define OMAP3_CLKSEL_GPT1 (1 << 0) /* Selects GPTIMER 1 source * clock: diff --git a/kernel/arch/earm/pre_init.c b/kernel/arch/earm/pre_init.c index 7360bd661..cdf15b775 100644 --- a/kernel/arch/earm/pre_init.c +++ b/kernel/arch/earm/pre_init.c @@ -30,7 +30,7 @@ struct kmessages kmessages; /* pg_utils.c uses this; in this phase, there is a 1:1 mapping. */ phys_bytes vir2phys(void *addr) { return (phys_bytes) addr; } -static void setup_mbi(multiboot_info_t *mbi); +static void setup_mbi(multiboot_info_t *mbi,char *cmdline); /* String length used for mb_itoa */ #define ITOA_BUFFER_SIZE 20 @@ -41,8 +41,73 @@ int kernel_may_alloc = 1; extern u32_t _edata; extern u32_t _end; -static int mb_set_param(char *bigbuf, char *name, char *value, kinfo_t *cbi) +/** + * + * The following function combines a few things together + * that can well be done using standard libc like strlen/strstr + * and such but these are not available in pre_init stage. + * + * The function expects content to be in the form of space separated + * key value pairs. + * param content the contents to search in + * param key the key to find (this *should* include the key/value delimiter) + * param value a pointer to an initialized char * of at least value_max_len length + * param value_max_len the maximum length of the value to store in value including + * the end char + * +**/ +int find_value(char * content,char * key,char *value,int value_max_len){ + + char *iter,*keyp; + int key_len,content_len,match_len,value_len; + + /* return if the input is invalid */ + if (key == NULL || content == NULL || value == NULL){ + return 1; + } + + /* find the key and content length */ + key_len = content_len =0; + for(iter = key ; *iter != '\0'; iter++, key_len++); + for(iter = content ; *iter != '\0'; iter++, content_len++); + + /* return if key or content length invalid */ + if (key_len == 0 || content_len == 0) { + return 1; + } + + /* now find the key in the contents */ + match_len =0; + for (iter = content ,keyp=key; match_len < key_len && *iter != '\0' ; iter++){ + if (*iter == *keyp){ + match_len++; + keyp++; + continue; + } + /* The current key does not match the value , reset */ + match_len =0; + keyp=key; + } + + if (match_len == key_len){ + printf("key found at %d %s\n", match_len, &content[match_len]); + value_len = 0; + /* copy the content to the value char iter already points to the first + char value */ + while(*iter != '\0' && *iter != ' ' && value_len + 1< value_max_len){ + *value++ = *iter++; + value_len++; + } + *value='\0'; + return 0; + } + return 1; /* not found */ +} + +static int mb_set_param(char *bigbuf,char *name,char *value, kinfo_t *cbi) { + /* bigbuf contains a list of key=value pairs separated by \0 char. + * The list itself is ended by a second \0 terminator*/ char *p = bigbuf; char *bufend = bigbuf + MULTIBOOT_PARAM_BUF_SIZE; char *q; @@ -57,18 +122,24 @@ static int mb_set_param(char *bigbuf, char *name, char *value, kinfo_t *cbi) while (*p) { if (strncmp(p, name, namelen) == 0 && p[namelen] == '=') { q = p; - while (*q) q++; - for (q++; q < bufend; q++, p++) + /* let q point to the end of the entry */ + while (*q) q++; + /* now copy the remained of the buffer */ + for (q++; q < bufend; q++, p++) *p = *q; break; } - while (*p++) - ; + + /* find the end of the buffer */ + while (*p++); p++; } - for (p = bigbuf; p < bufend && (*p || *(p + 1)); p++) - ; + + /* find the first empty spot */ + for (p = bigbuf; p < bufend && (*p || *(p + 1)); p++); + + /* unless we are the first entry step over the delimiter */ if (p > bigbuf) p++; /* Make sure there's enough space for the new parameter */ @@ -79,7 +150,7 @@ static int mb_set_param(char *bigbuf, char *name, char *value, kinfo_t *cbi) p[namelen] = '='; strcpy(p + namelen + 1, value); p[namelen + valuelen + 1] = 0; - p[namelen + valuelen + 2] = 0; + p[namelen + valuelen + 2] = 0; /* end with a second delimiter */ return 0; } @@ -103,7 +174,6 @@ int overlaps(multiboot_module_t *mod, int n, int cmp_mod) /* XXX: hard-coded stuff for modules */ #define MB_MODS_NR 12 #define MB_MODS_BASE 0x82000000 -#define MB_PARAM_MOD 0x88000000 #define MB_MODS_ALIGN 0x00800000 /* 8 MB */ #define MB_MMAP_START 0x80000000 #define MB_MMAP_SIZE 0x10000000 /* 256 MB */ @@ -111,7 +181,7 @@ int overlaps(multiboot_module_t *mod, int n, int cmp_mod) multiboot_module_t mb_modlist[MB_MODS_NR]; multiboot_memory_map_t mb_memmap; -void setup_mbi(multiboot_info_t *mbi) +void setup_mbi(multiboot_info_t *mbi, char *cmdline) { memset(mbi, 0, sizeof(*mbi)); mbi->flags = MULTIBOOT_INFO_MODS | MULTIBOOT_INFO_MEM_MAP | @@ -127,8 +197,7 @@ void setup_mbi(multiboot_info_t *mbi) mb_modlist[i].cmdline = 0; } - /* Final 'module' is actually a string holding the boot cmdline */ - mbi->cmdline = MB_PARAM_MOD; + mbi->cmdline = (u32_t)cmdline; mbi->mmap_addr =(u32_t)&mb_memmap; mbi->mmap_length = sizeof(mb_memmap); @@ -139,7 +208,7 @@ void setup_mbi(multiboot_info_t *mbi) mb_memmap.type = MULTIBOOT_MEMORY_AVAILABLE; } -void get_parameters(u32_t ebx, kinfo_t *cbi) +void get_parameters(u32_t ebx, kinfo_t *cbi,char *cmdline) { multiboot_memory_map_t *mmap; multiboot_info_t *mbi = &cbi->mbi; @@ -150,11 +219,11 @@ void get_parameters(u32_t ebx, kinfo_t *cbi) phys_bytes kernbase = (phys_bytes) &_kern_phys_base, kernsize = (phys_bytes) &_kern_size; #define BUF 1024 - static char cmdline[BUF]; + static char module_cmdline[BUF]; /* get our own copy of the multiboot info struct and module list */ //memcpy((void *) mbi, (void *) ebx, sizeof(*mbi)); - setup_mbi(mbi); + setup_mbi(mbi,cmdline); /* Set various bits of info for the higher-level kernel. */ cbi->mem_high_phys = 0; @@ -175,13 +244,13 @@ void get_parameters(u32_t ebx, kinfo_t *cbi) static char value[BUF]; /* Override values with cmdline argument */ - memcpy(cmdline, (void *) mbi->cmdline, BUF); - p = cmdline; + memcpy(module_cmdline, (void *) mbi->cmdline, BUF); + p = module_cmdline; while (*p) { var_i = 0; value_i = 0; - while (*p == ' ') p++; - if (!*p) break; + while (*p == ' ') p++; /* skip spaces */ + if (!*p) break; /* is this the end? */ while (*p && *p != '=' && *p != ' ' && var_i < BUF - 1) var[var_i++] = *p++ ; var[var_i] = 0; @@ -196,21 +265,8 @@ void get_parameters(u32_t ebx, kinfo_t *cbi) /* let higher levels know what we are booting on */ mb_set_param(cbi->param_buf, ARCHVARNAME, "earm", cbi); -#ifdef AM335X - int id = get_board_id_by_short_name("A335BONE"); - printf("BOARD ID=0x%08x\n",id); - const char * boardname = get_board_name(id); - printf("BOARD NAME=%s\n",boardname); - mb_set_param(cbi->param_buf, BOARDVARNAME,(char *) boardname, cbi); -#endif -#ifdef DM337x - int id = get_board_id_by_short_name("BBXM"); - printf("BOARD ID=0x%08x\n",id); - const char * boardname = get_board_name(id); - printf("BOARD NAME=%s\n",boardname); - mb_set_param(cbi->param_buf, BOARDVARNAME,(char *) boardname, cbi); -#endif - + mb_set_param(cbi->param_buf, BOARDVARNAME,(char *)get_board_name(machine.board_id) , cbi); + /* round user stack down to leave a gap to catch kernel * stack overflow; and to distinguish kernel and user addresses @@ -277,18 +333,44 @@ void get_parameters(u32_t ebx, kinfo_t *cbi) } } -kinfo_t *pre_init(u32_t magic, u32_t ebx) +/* use the passed cmdline argument to determine the machine id */ +void set_machine_id(char *cmdline) { + + char boardname[20]; + memset(boardname,'\0',20); + if (find_value(cmdline,"board_name=",boardname,20)){ + /* we expect the bootloader to pass a board_name as argument + * this however did not happen and given we still are in early + * boot we can't use the serial. We therefore generate an interrupt + * and hope the bootloader will do something nice with it */ + asm volatile("svc #00\n"); + } + machine.board_id = get_board_id_by_short_name(boardname); + + if (machine.board_id ==0){ + /* same thing as above there is no safe escape */ + asm volatile("svc #00\n"); + } +} + +kinfo_t *pre_init(u32_t brd_info, u32_t img_addr ,char *cons_dev, char *cmdline) +{ + /* This is the main "c" entry point into the kernel. It gets called + from head.S */ + /* Clear BSS */ memset(&_edata, 0, (u32_t)&_end - (u32_t)&_edata); + set_machine_id(cmdline); omap3_ser_init(); + /* Get our own copy boot params pointed to by ebx. * Here we find out whether we should do serial output. */ - get_parameters(ebx, &kinfo); + get_parameters(brd_info, &kinfo,cmdline); - /* Make and load a pagetable that will map the kernel + /* Make and load a page table that will map the kernel * to where it should be; but first a 1:1 mapping so * this code stays where it should be. */ @@ -314,3 +396,4 @@ void busy_delay_ms(int x) { } int raise(int n) { panic("raise(%d)\n", n); } int kern_phys_map_ptr( phys_bytes base_address, vir_bytes io_size, struct kern_phys_map * priv, vir_bytes ptr) {}; +struct machine machine; /* pre init stage machine */ diff --git a/kernel/arch/i386/pre_init.c b/kernel/arch/i386/pre_init.c index d6ad07f97..3db5569cc 100644 --- a/kernel/arch/i386/pre_init.c +++ b/kernel/arch/i386/pre_init.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -154,7 +155,7 @@ void get_parameters(u32_t ebx, kinfo_t *cbi) /* let higher levels know what we are booting on */ mb_set_param(cbi->param_buf, ARCHVARNAME, "i386", cbi); - mb_set_param(cbi->param_buf, BOARDVARNAME, "i586", cbi); + mb_set_param(cbi->param_buf, BOARDVARNAME,(char *)get_board_name(BOARD_ID_INTEL) , cbi); /* round user stack down to leave a gap to catch kernel * stack overflow; and to distinguish kernel and user addresses diff --git a/kernel/main.c b/kernel/main.c index 9978b5b51..66ab7a0cd 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -131,14 +131,9 @@ void kmain(kinfo_t *local_cbi) memcpy(&kinfo, local_cbi, sizeof(kinfo)); memcpy(&kmess, kinfo.kmess, sizeof(kmess)); -/* The following will be replaced with code getting this information from the - bootloader */ -#ifdef DM37XX - machine.board_id = BOARD_ID_BBXM; -#endif -#ifdef AM335X - machine.board_id = BOARD_ID_BBW; -#endif + /* We have done this exercise in pre_init so we expect this code + to simply work! */ + machine.board_id = get_board_id_by_name(env_get(BOARDVARNAME)); #ifdef __arm__ /* We want to initialize serial before we do any output */ omap3_ser_init(); diff --git a/releasetools/arm_sdimage.sh b/releasetools/arm_sdimage.sh index f51da89bb..6f79f7d16 100755 --- a/releasetools/arm_sdimage.sh +++ b/releasetools/arm_sdimage.sh @@ -51,7 +51,7 @@ fi export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH -for needed in mcopy dd wget mkfs.vfat +for needed in mcopy dd wget mkfs.vfat mkimage do if ! which $needed 2>&1 > /dev/null then @@ -147,35 +147,30 @@ mkfs.vfat ${IMG_DIR}/fat.img # Create a uEnv.txt file # -n default to network boot # -p add a prefix to the network booted files (e.g. xm/" -./releasetools/gen_uEnv.txt.sh > ${IMG_DIR}/uEnv.txt - -# -# Generate the MINIX command line -# -# options: # -c set console e.g. tty02 or tty00 # -v set verbosity e.g. 0 to 3 -./releasetools/gen_cmdline.txt.sh -c ${CONSOLE} > ${IMG_DIR}/cmdline.txt +#./releasetools/gen_uEnv.txt.sh -c ${CONSOLE} -n -p bb/ > ${IMG_DIR}/uEnv.txt +./releasetools/gen_uEnv.txt.sh -c ${CONSOLE} > ${IMG_DIR}/uEnv.txt echo "Copying configuration kernel and boot modules" mcopy -bsp -i ${IMG_DIR}/fat.img ${IMG_DIR}/$MLO ::MLO mcopy -bsp -i ${IMG_DIR}/fat.img ${IMG_DIR}/$UBOOT ::u-boot.img mcopy -bsp -i ${IMG_DIR}/fat.img ${IMG_DIR}/uEnv.txt ::uEnv.txt -mcopy -bsp -i ${IMG_DIR}/fat.img ${IMG_DIR}/cmdline.txt ::cmdline.txt # # For tftp booting # cp ${IMG_DIR}/uEnv.txt ${OBJ}/ -cp ${IMG_DIR}/cmdline.txt ${OBJ}/ # # Do some last processing of the kernel and servers before also putting # them on the FAT # ${CROSS_PREFIX}objcopy ${OBJ}/kernel/kernel -O binary ${OBJ}/kernel.bin +mkimage -A arm -O netbsd -T kernel -C none -e 0x80200000 -a 0x80200000 -d ${OBJ}/kernel.bin ${OBJ}/uImage mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/kernel.bin ::kernel.bin +mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/uImage ::uImage for f in vm rs pm sched vfs ds mfs pfs init do diff --git a/releasetools/gen_cmdline.txt.sh b/releasetools/gen_cmdline.txt.sh deleted file mode 100755 index ff8d87ee9..000000000 --- a/releasetools/gen_cmdline.txt.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -#default for the beagleboard-xM -CONSOLE=tty02 -#verbosity -VERBOSE=3 -HZ=1000 -while getopts "c:v:?" c -do - case "$c" in - \?) - echo "Usage: $0 [-c consoletty] [-v level]" >&2 - exit 1 - ;; - c) - # genrate netbooting uEnv.txt - CONSOLE=$OPTARG - ;; - v) - # genrate netbooting uEnv.txt - VERBOSE=$OPTARG - ;; - h) - # system hz - HZ=$OPTARG - ;; - esac -done - - -echo console=$CONSOLE rootdevname=c0d0p1 verbose=$VERBOSE hz=$HZ diff --git a/releasetools/gen_uEnv.txt.sh b/releasetools/gen_uEnv.txt.sh index 6cd7552dc..48e627b8e 100755 --- a/releasetools/gen_uEnv.txt.sh +++ b/releasetools/gen_uEnv.txt.sh @@ -1,7 +1,12 @@ #!/bin/sh #generate a u-boot u-env. -list="0x80200000 kernel.bin +#The kernel is configured to start and run at 0x80200000 +#but we use the u-boot uImage format to allow to use the +#bootm command. To ensure we can still boot "in place" +#we load the kernel 0x40 bellow 0x80200000. This allows +#us to "eXecute in place" XIP. +list="0x801fffc0 uImage 0x82000000 ds.elf 0x82800000 rs.elf 0x83000000 pm.elf @@ -13,8 +18,7 @@ list="0x80200000 kernel.bin 0x86000000 mfs.elf 0x86800000 vm.elf 0x87000000 pfs.elf -0x87800000 init.elf -0x88000000 cmdline.txt" +0x87800000 init.elf" # # PREFIX for loading file over tftp to allow hosting multiple @@ -23,11 +27,17 @@ NETBOOT_PREFIX="" NETBOOT="no" BOOT="mmcbootcmd" -while getopts "p:n?" c +#default for the beagleboard-xM +CONSOLE=tty02 +#verbosity +VERBOSE=3 +HZ=1000 + +while getopts "c:v:h:p:n?" c do case "$c" in \?) - echo "Usage: $0 [-p netboot_prefix] -n" >&2 + echo "Usage: $0 [-p netboot_prefix] -n [-c consoletty] [-v level] " >&2 exit 1 ;; n) @@ -38,6 +48,16 @@ do p) NETBOOT_PREFIX=$OPTARG ;; + c) + CONSOLE=$OPTARG + ;; + v) + VERBOSE=$OPTARG + ;; + h) + # system hz + HZ=$OPTARG + ;; esac done @@ -61,14 +81,39 @@ fill_cmd() { echo "# Set the command to be executed" echo "uenvcmd=run $BOOT" +echo "bootargs=console=$CONSOLE rootdevname=c0d0p1 verbose=$VERBOSE hz=$HZ" +echo +echo "bootminix=setenv bootargs \$bootargs board_name=\$board_name ; echo \$bootargs ; bootm 0x801fffc0" echo -echo "# With cmdline/bootargs in cmdline.txt" -echo "mmcbootcmd=echo starting from MMC ; mmc part 0; mw.b 0x88000000 0 16384 $(fill_cmd "fatload mmc 0:1" "") ; dcache off ; icache off ; go 0x80200000" +echo "mmcbootcmd=echo starting from MMC ; mmc part 0; $(fill_cmd "fatload mmc 0:1" "") ; dcache off ; icache off ; run bootminix" echo echo "# Netbooting." echo "serverip=192.168.12.10" echo "ipaddr=192.168.12.62" echo "usbnet_devaddr=e8:03:9a:24:f9:10" echo "usbethaddr=e8:03:9a:24:f9:11" -echo "netbootcmd=echo starting from TFTP; mw.b 0x88000000 0 16384 $(fill_cmd "tftp" "$NETBOOT_PREFIX") ; dcache off ; icache off ; go 0x80200000" +echo "netbootcmd=echo starting from TFTP; $(fill_cmd "tftp" "$NETBOOT_PREFIX") ; dcache off ; icache off ; run bootminix" exit 0 + +while getopts "c:v:?" c +do + case "$c" in + \?) + exit 1 + ;; + c) + # genrate netbooting uEnv.txt + CONSOLE=$OPTARG + ;; + v) + # genrate netbooting uEnv.txt + VERBOSE=$OPTARG + ;; + h) + # system hz + HZ=$OPTARG + ;; + esac +done + +