diff options
author | imp <imp@FreeBSD.org> | 2012-07-11 20:17:14 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2012-07-11 20:17:14 +0000 |
commit | 515d0c1d290c1ac2fb1aa99e74ef4175c158a007 (patch) | |
tree | cdb15b34649d1c3b0b980724718c54d34344146f /sys/arm/at91/at91_machdep.c | |
parent | 003ccf85faf91187b67eb412e643bb75b87ae2a6 (diff) | |
download | FreeBSD-src-515d0c1d290c1ac2fb1aa99e74ef4175c158a007.zip FreeBSD-src-515d0c1d290c1ac2fb1aa99e74ef4175c158a007.tar.gz |
Make the SoC stuff a little more modular, and start to move away from
having the CPU device that's a child of atmelarm that does stuff.
o Create a linker_set for the support fucntions for the SoCs.
o Rename soc_data to soc_info.
o Move the delay and reset function pointers to new soc_data struct
o Create elements for all known SoCs
o Add lookup of the SoC we found, and print a warning if it isn't one
we know about.
Diffstat (limited to 'sys/arm/at91/at91_machdep.c')
-rw-r--r-- | sys/arm/at91/at91_machdep.c | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c index 15e404f..0bb79bd 100644 --- a/sys/arm/at91/at91_machdep.c +++ b/sys/arm/at91/at91_machdep.c @@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$"); #include <arm/at91/at91board.h> #include <arm/at91/at91var.h> +#include <arm/at91/at91soc.h> #include <arm/at91/at91_usartreg.h> #include <arm/at91/at91rm92reg.h> #include <arm/at91/at91sam9g20reg.h> @@ -278,7 +279,7 @@ static const char *soc_subtype_name[] = { [AT91_ST_SAM9X35] = "at91sam9x35", }; -struct at91_soc_info soc_data; +struct at91_soc_info soc_info; /* * Read the SoC ID from the CIDR register and try to match it against the @@ -291,92 +292,92 @@ at91_try_id(uint32_t dbgu_base) { uint32_t socid; - soc_data.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base + + soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base + DBGU_C1R); - socid = soc_data.cidr & ~AT91_CPU_VERSION_MASK; + socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK; - soc_data.type = AT91_T_NONE; - soc_data.subtype = AT91_ST_NONE; - soc_data.family = (soc_data.cidr & AT91_CPU_FAMILY_MASK) >> 20; - soc_data.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base + + soc_info.type = AT91_T_NONE; + soc_info.subtype = AT91_ST_NONE; + soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20; + soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base + DBGU_C2R); switch (socid) { case AT91_CPU_CAP9: - soc_data.type = AT91_T_CAP9; + soc_info.type = AT91_T_CAP9; break; case AT91_CPU_RM9200: - soc_data.type = AT91_T_RM9200; + soc_info.type = AT91_T_RM9200; break; case AT91_CPU_SAM9XE128: case AT91_CPU_SAM9XE256: case AT91_CPU_SAM9XE512: case AT91_CPU_SAM9260: - soc_data.type = AT91_T_SAM9260; - if (soc_data.family == AT91_FAMILY_SAM9XE) - soc_data.subtype = AT91_ST_SAM9XE; + soc_info.type = AT91_T_SAM9260; + if (soc_info.family == AT91_FAMILY_SAM9XE) + soc_info.subtype = AT91_ST_SAM9XE; break; case AT91_CPU_SAM9261: - soc_data.type = AT91_T_SAM9261; + soc_info.type = AT91_T_SAM9261; break; case AT91_CPU_SAM9263: - soc_data.type = AT91_T_SAM9263; + soc_info.type = AT91_T_SAM9263; break; case AT91_CPU_SAM9G10: - soc_data.type = AT91_T_SAM9G10; + soc_info.type = AT91_T_SAM9G10; break; case AT91_CPU_SAM9G20: - soc_data.type = AT91_T_SAM9G20; + soc_info.type = AT91_T_SAM9G20; break; case AT91_CPU_SAM9G45: - soc_data.type = AT91_T_SAM9G45; + soc_info.type = AT91_T_SAM9G45; break; case AT91_CPU_SAM9N12: - soc_data.type = AT91_T_SAM9N12; + soc_info.type = AT91_T_SAM9N12; break; case AT91_CPU_SAM9RL64: - soc_data.type = AT91_T_SAM9RL; + soc_info.type = AT91_T_SAM9RL; break; case AT91_CPU_SAM9X5: - soc_data.type = AT91_T_SAM9X5; + soc_info.type = AT91_T_SAM9X5; break; default: return (0); } - switch (soc_data.type) { + switch (soc_info.type) { case AT91_T_SAM9G45: - switch (soc_data.exid) { + switch (soc_info.exid) { case AT91_EXID_SAM9G45: - soc_data.subtype = AT91_ST_SAM9G45; + soc_info.subtype = AT91_ST_SAM9G45; break; case AT91_EXID_SAM9G46: - soc_data.subtype = AT91_ST_SAM9G46; + soc_info.subtype = AT91_ST_SAM9G46; break; case AT91_EXID_SAM9M10: - soc_data.subtype = AT91_ST_SAM9M10; + soc_info.subtype = AT91_ST_SAM9M10; break; case AT91_EXID_SAM9M11: - soc_data.subtype = AT91_ST_SAM9M11; + soc_info.subtype = AT91_ST_SAM9M11; break; } break; case AT91_T_SAM9X5: - switch (soc_data.exid) { + switch (soc_info.exid) { case AT91_EXID_SAM9G15: - soc_data.subtype = AT91_ST_SAM9G15; + soc_info.subtype = AT91_ST_SAM9G15; break; case AT91_EXID_SAM9G25: - soc_data.subtype = AT91_ST_SAM9G25; + soc_info.subtype = AT91_ST_SAM9G25; break; case AT91_EXID_SAM9G35: - soc_data.subtype = AT91_ST_SAM9G35; + soc_info.subtype = AT91_ST_SAM9G35; break; case AT91_EXID_SAM9X25: - soc_data.subtype = AT91_ST_SAM9X25; + soc_info.subtype = AT91_ST_SAM9X25; break; case AT91_EXID_SAM9X35: - soc_data.subtype = AT91_ST_SAM9X35; + soc_info.subtype = AT91_ST_SAM9X35; break; } break; @@ -384,18 +385,24 @@ at91_try_id(uint32_t dbgu_base) break; } /* - * Disable interrupts + * Disable interrupts in the DBGU unit... */ *(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff; /* * Save the name for later... */ - snprintf(soc_data.name, sizeof(soc_data.name), "%s%s%s", - soc_type_name[soc_data.type], - soc_data.subtype == AT91_ST_NONE ? "" : " subtype ", - soc_data.subtype == AT91_ST_NONE ? "" : - soc_subtype_name[soc_data.subtype]); + snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s", + soc_type_name[soc_info.type], + soc_info.subtype == AT91_ST_NONE ? "" : " subtype ", + soc_info.subtype == AT91_ST_NONE ? "" : + soc_subtype_name[soc_info.subtype]); + + /* + * try to get the matching CPU support. + */ + soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype); + return (1); } @@ -548,6 +555,9 @@ initarm(struct arm_boot_params *abp) cninit(); + if (soc_info.soc_data == NULL) + printf("Warning: No soc support for %s found.\n", soc_info.name); + memsize = board_init(); physmem = memsize / PAGE_SIZE; @@ -637,16 +647,16 @@ void DELAY(int n) { - if (soc_data.delay) - soc_data.delay(n); + if (soc_info.soc_data) + soc_info.soc_data->soc_delay(n); } void cpu_reset(void) { - if (soc_data.reset) - soc_data.reset(); + if (soc_info.soc_data) + soc_info.soc_data->soc_reset(); while (1) continue; } |