Commit a042ac8439a5d3795af525ab3de9e6db96d72aa1

Authored by wdenk
1 parent a46d821fc8

Initial revision

Showing 2 changed files with 430 additions and 0 deletions Side-by-side Diff

cpu/mpc8xx/commproc.c
  1 +/*
  2 + * (C) Copyright 2000-2002
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +#include <common.h>
  25 +#include <commproc.h>
  26 +
  27 +#ifdef CFG_ALLOC_DPRAM
  28 +
  29 +int dpram_init (void)
  30 +{
  31 + DECLARE_GLOBAL_DATA_PTR;
  32 +
  33 + /* Reclaim the DP memory for our use. */
  34 + gd->dp_alloc_base = CPM_DATAONLY_BASE;
  35 + gd->dp_alloc_top = CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE;
  36 +
  37 + return (0);
  38 +}
  39 +
  40 +/* Allocate some memory from the dual ported ram. We may want to
  41 + * enforce alignment restrictions, but right now everyone is a good
  42 + * citizen.
  43 + */
  44 +uint dpram_alloc (uint size)
  45 +{
  46 + DECLARE_GLOBAL_DATA_PTR;
  47 + uint addr = gd->dp_alloc_base;
  48 +
  49 + if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top)
  50 + return (CPM_DP_NOSPACE);
  51 +
  52 + gd->dp_alloc_base += size;
  53 +
  54 + return addr;
  55 +}
  56 +
  57 +uint dpram_base (void)
  58 +{
  59 + DECLARE_GLOBAL_DATA_PTR;
  60 +
  61 + return gd->dp_alloc_base;
  62 +}
  63 +
  64 +/* Allocate some memory from the dual ported ram. We may want to
  65 + * enforce alignment restrictions, but right now everyone is a good
  66 + * citizen.
  67 + */
  68 +uint dpram_alloc_align (uint size, uint align)
  69 +{
  70 + DECLARE_GLOBAL_DATA_PTR;
  71 +
  72 + uint addr, mask = align - 1;
  73 +
  74 + addr = (gd->dp_alloc_base + mask) & ~mask;
  75 +
  76 + if ((addr + size) >= gd->dp_alloc_top)
  77 + return (CPM_DP_NOSPACE);
  78 +
  79 + gd->dp_alloc_base = addr + size;
  80 +
  81 + return addr;
  82 +}
  83 +
  84 +uint dpram_base_align (uint align)
  85 +{
  86 + DECLARE_GLOBAL_DATA_PTR;
  87 +
  88 + uint mask = align - 1;
  89 +
  90 + return (gd->dp_alloc_base + mask) & ~mask;
  91 +}
  92 +#endif /* CFG_ALLOC_DPRAM */
  93 +
  94 +#ifdef CONFIG_POST
  95 +
  96 +void post_word_store (ulong a)
  97 +{
  98 + volatile void *save_addr =
  99 + ((immap_t *) CFG_IMMR)->im_cpm.cp_dpmem + CPM_POST_WORD_ADDR;
  100 +
  101 + *(volatile ulong *) save_addr = a;
  102 +}
  103 +
  104 +ulong post_word_load (void)
  105 +{
  106 + volatile void *save_addr =
  107 + ((immap_t *) CFG_IMMR)->im_cpm.cp_dpmem + CPM_POST_WORD_ADDR;
  108 +
  109 + return *(volatile ulong *) save_addr;
  110 +}
  111 +
  112 +#endif /* CONFIG_POST */
  1 +/*
  2 + * (C) Copyright 2002
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +#include <common.h>
  25 +#include <console.h>
  26 +#include <watchdog.h>
  27 +#include <post.h>
  28 +
  29 +#ifdef CONFIG_POST
  30 +
  31 +#define POST_MAX_NUMBER 32
  32 +
  33 +#define BOOTMODE_MAGIC 0xDEAD0000
  34 +
  35 +void post_bootmode_init (void)
  36 +{
  37 + int bootmode = post_bootmode_get (0);
  38 +
  39 + if (bootmode == 0) {
  40 + bootmode = POST_POWERON;
  41 + } else if (bootmode == POST_POWERON) {
  42 + bootmode = POST_POWERNORMAL;
  43 + } else {
  44 + return;
  45 + }
  46 +
  47 + post_word_store (BOOTMODE_MAGIC | bootmode);
  48 +}
  49 +
  50 +int post_bootmode_get (unsigned int *last_test)
  51 +{
  52 + unsigned long word = post_word_load ();
  53 + int bootmode;
  54 +
  55 + if ((word & 0xFFFF0000) != BOOTMODE_MAGIC) {
  56 + return 0;
  57 + }
  58 +
  59 + bootmode = word & 0xFF;
  60 +
  61 + if (last_test && (bootmode & POST_POWERTEST)) {
  62 + *last_test = (word >> 8) & 0xFF;
  63 + }
  64 +
  65 + return bootmode;
  66 +}
  67 +
  68 +void post_bootmode_clear (void)
  69 +{
  70 + post_word_store (0);
  71 +}
  72 +
  73 +static void post_bootmode_test_on (unsigned int last_test)
  74 +{
  75 + unsigned long word = post_word_load ();
  76 +
  77 + word |= POST_POWERTEST;
  78 +
  79 + word |= (last_test & 0xFF) << 8;
  80 +
  81 + post_word_store (word);
  82 +}
  83 +
  84 +static void post_bootmode_test_off (void)
  85 +{
  86 + unsigned long word = post_word_load ();
  87 +
  88 + word &= ~POST_POWERTEST;
  89 +
  90 + post_word_store (word);
  91 +}
  92 +
  93 +static void post_get_flags (int *test_flags)
  94 +{
  95 + int flag[] = { POST_POWERON, POST_POWERNORMAL, POST_POWERFAIL };
  96 + char *var[] = { "post_poweron", "post_normal", "post_shutdown" };
  97 + int varnum = sizeof (var) / sizeof (var[0]);
  98 + char list[128]; /* long enough for POST list */
  99 + char *name;
  100 + char *s;
  101 + int last;
  102 + int i, j;
  103 +
  104 + for (j = 0; j < post_list_size; j++) {
  105 + test_flags[j] = post_list[j].flags;
  106 + }
  107 +
  108 + for (i = 0; i < varnum; i++) {
  109 + if (getenv_r (var[i], list, sizeof (list)) <= 0)
  110 + continue;
  111 +
  112 + for (j = 0; j < post_list_size; j++) {
  113 + test_flags[j] &= ~flag[i];
  114 + }
  115 +
  116 + last = 0;
  117 + name = list;
  118 + while (!last) {
  119 + while (*name && *name == ' ')
  120 + name++;
  121 + if (*name == 0)
  122 + break;
  123 + s = name + 1;
  124 + while (*s && *s != ' ')
  125 + s++;
  126 + if (*s == 0)
  127 + last = 1;
  128 + else
  129 + *s = 0;
  130 +
  131 + for (j = 0; j < post_list_size; j++) {
  132 + if (strcmp (post_list[j].cmd, name) == 0) {
  133 + test_flags[j] |= flag[i];
  134 + break;
  135 + }
  136 + }
  137 +
  138 + if (j == post_list_size) {
  139 + printf ("No such test: %s\n", name);
  140 + }
  141 +
  142 + name = s + 1;
  143 + }
  144 + }
  145 +}
  146 +
  147 +static int post_run_single (struct post_test *test,
  148 + int test_flags, int flags, unsigned int i)
  149 +{
  150 + if ((flags & test_flags & POST_ALWAYS) &&
  151 + (flags & test_flags & POST_MEM)) {
  152 + WATCHDOG_RESET ();
  153 +
  154 + if (!(flags & POST_REBOOT)) {
  155 + if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL)) {
  156 + post_bootmode_test_on (i);
  157 + }
  158 +
  159 + post_log ("START %s\n", test->cmd);
  160 + }
  161 +
  162 + if ((*test->test) (flags) != 0)
  163 + post_log ("FAILED\n");
  164 + else
  165 + post_log ("PASSED\n");
  166 +
  167 + if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL)) {
  168 + post_bootmode_test_off ();
  169 + }
  170 +
  171 + return 0;
  172 + } else {
  173 + return -1;
  174 + }
  175 +}
  176 +
  177 +int post_run (char *name, int flags)
  178 +{
  179 + unsigned int i;
  180 + int test_flags[POST_MAX_NUMBER];
  181 +
  182 + post_get_flags (test_flags);
  183 +
  184 + if (name == NULL) {
  185 + unsigned int last;
  186 +
  187 + if (post_bootmode_get (&last) & POST_POWERTEST) {
  188 + if (last < post_list_size &&
  189 + (flags & test_flags[last] & POST_ALWAYS) &&
  190 + (flags & test_flags[last] & POST_MEM)) {
  191 +
  192 + post_run_single (post_list + last, test_flags[last],
  193 + flags | POST_REBOOT, last);
  194 +
  195 + for (i = last + 1; i < post_list_size; i++) {
  196 + post_run_single (post_list + i, test_flags[i],
  197 + flags, i);
  198 + }
  199 + }
  200 + } else {
  201 + for (i = 0; i < post_list_size; i++) {
  202 + post_run_single (post_list + i, test_flags[i], flags,
  203 + i);
  204 + }
  205 + }
  206 +
  207 + return 0;
  208 + } else {
  209 + for (i = 0; i < post_list_size; i++) {
  210 + if (strcmp (post_list[i].cmd, name) == 0)
  211 + break;
  212 + }
  213 +
  214 + if (i < post_list_size) {
  215 + return post_run_single (post_list + i,
  216 + test_flags[i],
  217 + flags, i);
  218 + } else {
  219 + return -1;
  220 + }
  221 + }
  222 +}
  223 +
  224 +static int post_info_single (struct post_test *test, int full)
  225 +{
  226 + if (test->flags & POST_MANUAL) {
  227 + if (full)
  228 + printf ("%s - %s\n"
  229 + " %s\n", test->cmd, test->name, test->desc);
  230 + else
  231 + printf (" %-15s - %s\n", test->cmd, test->name);
  232 +
  233 + return 0;
  234 + } else {
  235 + return -1;
  236 + }
  237 +}
  238 +
  239 +int post_info (char *name)
  240 +{
  241 + unsigned int i;
  242 +
  243 + if (name == NULL) {
  244 + for (i = 0; i < post_list_size; i++) {
  245 + post_info_single (post_list + i, 0);
  246 + }
  247 +
  248 + return 0;
  249 + } else {
  250 + for (i = 0; i < post_list_size; i++) {
  251 + if (strcmp (post_list[i].cmd, name) == 0)
  252 + break;
  253 + }
  254 +
  255 + if (i < post_list_size) {
  256 + return post_info_single (post_list + i, 1);
  257 + } else {
  258 + return -1;
  259 + }
  260 + }
  261 +}
  262 +
  263 +int post_log (char *format, ...)
  264 +{
  265 + va_list args;
  266 + uint i;
  267 + char printbuffer[CFG_PBSIZE];
  268 +
  269 + va_start (args, format);
  270 +
  271 + /* For this to work, printbuffer must be larger than
  272 + * anything we ever want to print.
  273 + */
  274 + i = vsprintf (printbuffer, format, args);
  275 + va_end (args);
  276 +
  277 + /* Send to the stdout file */
  278 + puts (printbuffer);
  279 +
  280 + return 0;
  281 +}
  282 +
  283 +void post_reloc (void)
  284 +{
  285 + DECLARE_GLOBAL_DATA_PTR;
  286 +
  287 + unsigned int i;
  288 +
  289 + /*
  290 + * We have to relocate the test table manually
  291 + */
  292 + for (i = 0; i < post_list_size; i++) {
  293 + ulong addr;
  294 + struct post_test *test = post_list + i;
  295 +
  296 + if (test->name) {
  297 + addr = (ulong) (test->name) + gd->reloc_off;
  298 + test->name = (char *) addr;
  299 + }
  300 +
  301 + if (test->cmd) {
  302 + addr = (ulong) (test->cmd) + gd->reloc_off;
  303 + test->cmd = (char *) addr;
  304 + }
  305 +
  306 + if (test->desc) {
  307 + addr = (ulong) (test->desc) + gd->reloc_off;
  308 + test->desc = (char *) addr;
  309 + }
  310 +
  311 + if (test->test) {
  312 + addr = (ulong) (test->test) + gd->reloc_off;
  313 + test->test = (int (*)(int flags)) addr;
  314 + }
  315 + }
  316 +}
  317 +
  318 +#endif /* CONFIG_POST */